お金をかけずにサーバーの勉強をしよう

NextCloud ちょっと本気環境 4

2023年4月26日

メニューへ戻る

NextCloud ちょっと本気環境 1」で環境設計をし、
NextCloud ちょっと本気環境 2」で MySQLサーバーを作り、
NextCloud ちょっと本気環境 3」で NextCloudアプリケーションサーバーを作りました。

ここでは NextCloudサーバーの前段に置くロードバランサー(リバースプロキシ)として NGINXサーバーを作ります。

構成図ではここです。
構成図

それではスタートです。


1.OSインストール

VMware Workstation PlayerのゲストOSとして、Ubuntu Server 22.04.2 を1つ作ります。

インストールについては、以下に書いている通りに作りました。
Ubuntu Linux Serverをインストール
Ubuntu Serverの初期設定

私の家のLANに作りますので IPアドレスは以下にし、他のネットワーク設定は上のページに書いてあるものに準じています。

マシン名: nginx
IP: 192.168.1.108


2.IPv6無効化

IPv4での運用にしたいと思います。
Ubuntu 22.04の IPv6無効化」に書いておりますので、それに従ってやっておきました。


3.マシン名解決

我が家には家庭内LAN用の DNSがありませんので、[/etc/hosts]ファイルでマシン名解決(マシン名からIPアドレスに変換)をしています。

[nextcloud]サーバーは、[nginx]サーバー・[mysql]サーバーと通信しますので、IPv4の記載部分を以下のように変更しています。

[/etc/hosts]

127.0.0.1 localhost
192.168.1.108 nginx ← IPアドレス変更
192.168.1.109 nextcloud ← この行を追加


4.make-sslパッケージインストール

NGINXで httpsを扱わせるに、[nginx]サーバーの秘密鍵ファイルを読ませる必要があります。
OSに[ssl-cert]グループがあると都合が良いので、make-sslパッケージを導入します。

subro@nginx:~$ sudo apt install -y ssl-cert
〜〜〜 省略 〜〜〜

インストール後には、[ssl-cert]グループができるのと、[/etc/ssl/private]ディレクトリのグループとパーミッションが変更され、[ssl-cert]グループに所属しているユーザーが秘密鍵にアクセスできるようになります。

subro@nginx:~$ ls -l /etc/ssl
合計 32
drwxr-xr-x 2 root root     12288  4月 26 10:34 certs
-rw-r--r-- 1 root root     12419  2月  7 02:57 openssl.cnf
drwx--x--- 2 root ssl-cert  4096  4月 26 10:34 private

[www-data]ユーザーを [ssl-cert]グループに追加しておきます。

subro@nginx:~$ sudo usermod -aG ssl-cert www-data

subro@nginx:/etc/ssl$ grep ssl-cert /etc/group
ssl-cert:x:119:www-data

できました。


5.NGINXインストール

NGINXのインストールについては「NGiNXサーバーを作る」に書いておりますので、それを参考に勧めます。

NGINXをインストールします。

subro@nginx:~$ sudo apt install -y nginx
〜〜〜 省略 〜〜〜

インストールできました。


6.プライベート認証局にサーバー証明書に署名してもらう

NGINXまでの通信は httpsで行いたく、サーバー証明書が必要になります。
この環境はインターネットに晒していないので、家庭内LAN様に作ったプライベート認証局でサーバー証明書に署名してもらいます。

プライベート認証局については「プライベート認証局」に書いておりますので、その環境で署名つきサーバー証明書を作ります。

[nginx]サーバーでサーバー証明書への署名依頼(CSR)ファイルを作ります。
[Common Name]が大事で、NextCloudにアクセスする時のサーバー名に合わせなければなりません。
この環境では[subronextcloud]としました。
(カレントディレクトリは [/etc/ssl]にしています)

subro@nginx:/etc/ssl$ sudo /usr/lib/ssl/misc/CA.pl -newreq
Use of uninitialized value $1 in concatenation (.) or string at /usr/lib/ssl/misc/CA.pl line 145.
====
openssl req  -new  -keyout newkey.pem -out newreq.pem -days 365
Ignoring -days without -x509; not generating a certificate
....+..........+..+.........+......+....+...+......++++++++++ 〜〜〜 以降長いので省略 〜〜〜
Enter PEM pass phrase:[nginx]サーバーの秘密鍵パスワードを入れる
Verifying - Enter PEM pass phrase:パスワードをもう一回
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:JP
State or Province Name (full name) [Some-State]:Tokyo
Locality Name (eg, city) []:Minato-ku
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Subro NextCloud Company
Organizational Unit Name (eg, section) []:Director
Common Name (e.g. server FQDN or YOUR name) []:subronextcloud ← 重要
Email Address []:空にしました

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:空にしました
An optional company name []:空にしました
==> 0
====
Request is in newreq.pem, private key is in newkey.pem

subro@nginx:/etc/ssl$ ls -l
合計 40
drwxr-xr-x 2 root root     12288  4月 26 10:34 certs
-rw------- 1 root root      1854  4月 26 11:03 newkey.pem ← 秘密鍵
-rw-r--r-- 1 root root      1001  4月 26 11:03 newreq.pem ← サーバー証明要求(CSR)
-rw-r--r-- 1 root root     12419  2月  7 02:57 openssl.cnf
drwx--x--- 2 root ssl-cert  4096  4月 26 10:34 private

秘密鍵は大事なので、パーミッションが厳しい [private]ディレクトリ下に名前をかえつつ移し、[ssl-cert]グループに変更し、[ssl-cert]グループのユーザーは読めるようパーミッションを設定します。

subro@nginx:/etc/ssl$ sudo mv newkey.pem ./private/private-key.pem

subro@nginx:/etc/ssl$ sudo chgrp ssl-cert ./private/private-key.pem

subro@nginx:/etc/ssl$ sudo chmod 640 ./private/private-key.pem

subro@nginx:/etc/ssl$ sudo ls -l ./private
合計 8
-rw-r----- 1 root ssl-cert 1854  4月 26 11:03 private-key.pem
-rw-r----- 1 root ssl-cert 1704  4月 26 10:34 ssl-cert-snakeoil.key

移りました。

CSRのファイル [newreq.pem]を、私の家のプライベート認証局になっている Lubuntu 22.04のクライアントPCに持ってきました。

subro@Lubuntu2204:~/work/ssl$ ls -l
total 12
drwxrwxr-x 6 subro subro 4096  4月 17 23:02 demoCA
-rw-r--r-- 1 subro subro 1037  4月 26 11:08 newreq.pem
-rw-rw-r-- 1 subro subro   34  4月 26 11:09 sans.ext

SANs(Subject Alternative Names)設定用のファイル[sans.ext]の内容はこうなっています。

subjectAltName=DNS:subronextcloud ← サーバー証明依頼(CSR)を出した時の[Common Name]と同じにしないとならない

CA.plに open-sslにこのファイルを読ませるオプションを渡すため、[OPENSSL_CONFIG]環境変数を設定します。

subro@Lubuntu2204:~/work/ssl$ export OPENSSL_CONFIG="-extfile sans.ext"

署名します。

subro@Lubuntu2204:~/work/ssl$ /usr/lib/ssl/misc/CA.pl -sign
====
openssl ca -extfile sans.ext -policy policy_anything -out newcert.pem -infiles newreq.pem
Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:プライベート認証局(Lubuntu 22.04)のサーバー秘密鍵のパスワードを入れる
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number:
            72:0d:75:0a:2c:57:95:46:91:ff:37:e6:67:6e:56:a0:31:05:18:67
        Validity
            Not Before: Apr 26 02:12:47 2023 GMT
            Not After : Apr 25 02:12:47 2024 GMT
        Subject:
            countryName               = JP
            stateOrProvinceName       = Tokyo
            localityName              = Minato-ku
            organizationName          = Subro NextCloud Company
            organizationalUnitName    = Director
            commonName                = subronextcloud
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:subronextcloud ← 重要
Certificate is to be certified until Apr 25 02:12:47 2024 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
==> 0
====
Signed certificate is in newcert.pem

subro@Lubuntu2204:~/work/ssl$ ls -l
total 20
drwxrwxr-x 6 subro subro 4096  4月 26 11:12 demoCA
-rw-rw-r-- 1 subro subro 4519  4月 26 11:12 newcert.pem ← できあがった[nginx]サーバーの署名つき証明書
-rw-r--r-- 1 subro subro 1037  4月 26 11:08 newreq.pem
-rw-rw-r-- 1 subro subro   34  4月 26 11:09 sans.ext

この[newcert.pem]ファイルを [nginx]サーバーに持ってきました。

subro@nginx:/etc/ssl$ ls -l
合計 44
drwxr-xr-x 2 root root 12288  2月 18 02:25 certs
-rw-r--r-- 1 root root  4519  4月 26 11:16 newcert.pem
-rw-r--r-- 1 root root  1037  4月 26 11:08 newreq.pem
-rw-r--r-- 1 root root 12419  2月  7 02:57 openssl.cnf
drwx------ 2 root root  4096  4月 26 10:34 private

このサーバー証明書用のディレクトリを作って、ファイル名も変えて置いておきます。

subro@nginx:/etc/ssl$ sudo mkdir subronextcloud

subro@nginx:/etc/ssl$ sudo mv newcert.pem ./subronextcloud/subronextcloud_servercert.pem

subro@nginx:/etc/ssl$ ls -l
合計 40
drwxr-xr-x 2 root root     12288  4月 26 10:34 certs
-rw-r--r-- 1 root root      1037  4月 26 11:04 newreq.pem
-rw-r--r-- 1 root root     12419  2月  7 02:57 openssl.cnf
drwx--x--- 2 root ssl-cert  4096  4月 26 11:04 private
drwxr-xr-x 2 root root      4096  4月 26 11:19 subronextcloud

subro@nginx:/etc/ssl$ ls -l subronextcloud
合計 8
-rw-r--r-- 1 root root 4519  4月 26 11:16 subronextcloud_servercert.pem

サーバー証明要求(CSR)のファイルは消しておきます。

subro@nginx:/etc/ssl$ sudo rm newreq.pem


7.NGINXの設定

NGINXで、ロードバランサー(アプリケーションサーバーが一台しかないので実質はリバースプロキシ設定の意味しかありません)と SSL(https利用)の設定をします。

これも「プライベート認証局」でやったのを参考にしています。

[nginx]サーバーの秘密鍵ファイル[/etc/ssl/private/private-key.pem]ファイルを NGINX起動時に読めるよう、パスワード記述ファイル[/etc/nginx/ssl/password.txt]を作ります。
このファイルの中には秘密鍵ファイルのパスワードだけ書いておきます。

subro@nginx:~$ mkdir /etc/nginx/ssl

subro@nginx:~$ sudo chmod 700 /etc/nginx/ssl ← 重要ファイルを格納するディレクトリなのでパーミッションを厳しくしています

この段階で [root]ユーザーで password.txt を作ります

subro@nginx:~$ sudo chmod 600 /etc/nginx/ssl/password.txt ← 重要ファイルなのでパーミッションを厳しくしています

subro@nginx:~$ ls -l
合計 4
-rw------- 1 root root 10  4月 26 11:37 password.txt

NGINXの設定をします。
NextCloud以外の用途がないので、設定ファイルは [/etc/nginx/sites-available/default]をイジってしまいます。

[/etc/nginx/sites-available/default]

# httpでアクセスされちゃった時にhttpsの方にリダイレクトする設定
server {
        listen       80;
        server_name  subronextcloud;
        return       301 https://$host$request_uri;
}

# 本体設定
server {
        listen 443 ssl default_server;

        root /var/www/html;

        index index.html index.htm index.php;

        # バーチャルホスト名
        server_name subronextcloud;

        # https用設定
        ssl on;
        ssl_certificate     /etc/ssl/subronextcloud/subronextcloud_servercert.pem;
        ssl_certificate_key /etc/ssl/private/private-key.pem;
        ssl_password_file   /etc/nginx/ssl/password.txt;

        # リバースプロキシ用設定
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-Host   $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;

        # マシン名だけでアクセスされた時は /nextcloud 付きにリライト
        location / {
                rewrite ^/ https://subronextcloud/nextcloud/ redirect;
        }

        # [nextcloud]サーバーの NextCloudeへ
        location /nextcloud {
                proxy_pass http://nextcloud:60004/nextcloud/;
        }
}


NGINXを再起動します。

subro@nginx:~$ sudo systemctl restart nginx

これで [nginx]サーバーが NGINXをリバースプロキシとし、かつ httpsでのアクセスを実現するサーバーとなりました。


8.NextCloudの Trusted Domain設定

このまま WEBブラウザで [nginx]サーバーにアクセスすると、NextCloudから「信頼できないドメインからのアクセス」アクセスであると怒られます。
構成図

以下のマニュアルに従って、[nextcloud]サーバーで設定をします。
Trusted Domains

PHPの設定ファイルに、[subronextcloud]という NGINXのバーチャルサーバー名を信頼できるドメインとさせます。 [/var/www/nextcloud/config/config.php]ファイルを以下のように書き換えます。

[/var/www/nextcloud/config/config.php]

  'trusted_domains' =>
  array (
    0 => 'nextcloud:60004',
  ),
  ↓
  'trusted_domains' =>
  array (
    0 => 'nextcloud:60004',
    1 => 'subronextcloud', ← 追加
  ),

Apache2を再起動します。

subro@nextcloud:~$ sudo service apache2 restart


9.動作確認準備

私の Lubuntu 22.04のクライアントの Firefoxからアクセスすることにします。
これにあたり、プライベート認証局のサーバー証明書を Firefoxに仕込んでおく必要があります。

プライベート認証局」で書いている通り、プライベート認証局はたった今 Firefoxを動かそうとしている Lubuntu 22.04クライアントですので、認証局のサーバー証明書がローカルにあります。

これを取り込みます。

Firefoxの[設定]メニューから[プライバシーとセキュリティ]を選ぶと[証明書]って段落があります。
そこの証明書を表示…を押します。
Firefoxに認証局の証明書を取り込み 1

[認証局証明書]タブを開きインポートを押します。
Firefoxに認証局の証明書を取り込み 2
ファイラーが出てくるので、[/home/subro/work/ssl/demoCA/cacert.pem]ファイルを指定しました。

[この認証局によるウェブサイトの識別を信頼する]にチェックし、OKを押します。
Firefoxに認証局の証明書を取り込み 3

しますと証明書一覧に「Subro. Inc.」が現れました。ハハッ ワロス
Firefoxに認証局の証明書を取り込み 4


それから Lubunu 22.04クライアントは、NGINXのバーチャルホスト [subronextcloud]の IPを知りませんので、[/etc/hosts]ファイルの [niginx]サーバーの行に追加しておきました。

192.168.1.108 nginx subronextcloud


10.動作確認

準備ができましたので、わざと [http://subronextcloud]でアクセスしてみます。

ログイン画面が出ました!\(^o^)/
NextCloud ログイン

ログインするとダッシュボードになります。
NextCloud ログインダッシュボード

ログアウトは右上のアイコン(Sになってるのは[subro]ユーザーだから)をクリックして出てくるメニューから[ログアウト]を選ぶとログアウトします。
NextCloud ログインログアウト


11.sshd ポート変更

[nginx]サーバーに戻って参りました。

[22/tcp]から変えてしまいます。
[/etc/ssh/sshd_config]ファイルを以下の通り変更します。

[/etc/ssh/sshd_config]

#Port 22
  ↓
Port 60003 ← コメントアウト(#)を消して番号を変更します 60003は適当です

設定の反映を確認するため再起動しました。

subro@nginx:~$ sudo reboot

なお、ポート番号を変更された sshサーバーには [-p]オプションを使ってログインします。

subro@Lubuntu2204:~$ ssh subro@nginx -p 60003

リブート後の待受ポート状態です。

subro@nginx:~$ ss -antl
State                  Recv-Q                 Send-Q                                 Local Address:Port                                   Peer Address:Port                 Process
LISTEN                 0                      511                                          0.0.0.0:443                                         0.0.0.0:*
LISTEN                 0                      128                                          0.0.0.0:60003                                       0.0.0.0:*
LISTEN                 0                      511                                          0.0.0.0:80                                          0.0.0.0:*
LISTEN                 0                      4096                                   127.0.0.53%lo:53                                          0.0.0.0:*

良さげです。


12.ファイアウォール有効化

ufw(program for managing a netfilter firewall)で、NGINXへのアクセスと sshだけが可能になるよう締め付けます。

この手順は一部「Ubuntuでもファイアウォール」に書いていますので、良かったら見てやって下さい。

現在の状態を確認します。

subro@nginx:~$ sudo ufw status
状態: 非アクティブ


ファイアウォールのロギングを有効にします。

subro@nginx:~$ sudo ufw logging on
ログ取得を有効にしました


入ってくる方は全閉じの設定です。
デフォルトではこうなっているので、やらなくても良いです。

subro@nginx:~$ sudo ufw default deny
デフォルトの incoming ポリシーは 'deny' に変更しました
(適用したい内容に基づいて必ずルールを更新してください)


先に sshdの [60003/tcp] を作業用の PCがあるネットワークにだけ許可しておきます。

※これはネットワークセグメントに対して許可する参考です。
この実験環境で [192.168.1.0/24]に許可してしまうと、他のサーバーからでも sshでアクセスできてしまいます。
自分の環境に適宜置き換えて下さい。

subro@nginx:~$ sudo ufw allow from 192.168.1.0/24 to any port 60003 proto tcp
ルールをアップデートしました


NGINXへの[80/tcp][443/tcp]を許可します。

subro@nginx:~$ sudo ufw allow 80/tcp
ルールをアップデートしました

subro@nginx:~$ sudo ufw allow 443/tcp
ルールをアップデートしました

セッティングが済みましたので、ファイアウォールを有効化します。

subro@nginx:~$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
ファイアウォールはアクティブかつシステムの起動時に有効化されます。

リブート後も有効になっているか確認するため、一旦リブートします。

subro@nginx:~$ sudo reboot

リブート後に改めてログインしました。
sshコマンドの [-p 60003]オプションを忘れずに。

状態確認です。

subro@nginx:~$ sudo ufw status numbered
状態: アクティブ

     To                         Action      From
     --                         ------      ----
[ 1] 60003/tcp                  ALLOW IN    192.168.1.0/24
[ 2] 80/tcp                     ALLOW IN    Anywhere
[ 3] 443/tcp                    ALLOW IN    Anywhere

良さげです。


改めてログインしてみましたが、問題なくログインできました。


こうしてシリーズの4にて、やっとこ NextCloudを動かすことができました。
感無量です。

ただ、セキュリティに関してはまだまだヌルくて、NGINXなり Apache2なりでもっと詰められるんでしょう、というのが心残りです。

NextCloud ちょっと本気環境 5」では NextCloudの簡単な使用感をレポートしています。