nginxの導入、リバースプロキシ設定、複数のGrowiを稼動させる、SSL証明書の発行などの手順について

前回の手順ではhttp://wiki.imo-tikuwa.com:3000/にアクセスすることでGrowiが使えるようになりました。
今回はNode.jsへのリクエストを直前にnginxで受け取りGrowiにポート番号を含まないhttp://wiki.imo-tikuwa.com/でアクセスできるようにリバースプロキシの設定を行います。また、ConoHaの同サーバー内にもう一つGrowiを導入し、http://wiki2.imo-tikuwa.com/というドメイン名で別のGrowiにアクセスできるように設定を行います。
最後にCertbot(旧Let’s Encrypt)を導入して2つのWikiに対してのSSL対応を行います。


まずCentOS7.4にnginxをインストールします。リポジトリの設定なんかは行わずに普通にインストールできました。

# yum install nginx


まずはnginxをデフォルトの状態で起動します。ブラウザでhttp://wiki.imo-tikuwa.com/にアクセスすると以下のようなnginxのテストページが表示されます。

# systemctl start nginx
# systemctl enable nginx


wiki.imo-tikuwa.com用の設定ファイルを新規作成しバーチャルホストとリバースプロキシの設定を行います。ちなみに前回導入したGrowiは3000番ポートで動かしています。

# vi /etc/nginx/conf.d/wiki.imo-tikuwa.com.conf
+server {
+    server_name wiki.imo-tikuwa.com;
+    access_log  /var/log/nginx/wiki.imo-tikuwa.com.access_log;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Host $http_host;
+    location / {
+        proxy_pass http://localhost:3000;
+    }
+}

nginxを再起動し、先ほどと同じようにブラウザでhttp://wiki.imo-tikuwa.com/にアクセスします。nginxのリバースプロキシによりwiki.imo-tikuwa.comドメインによる80番ポートへのリクエストが3000番ポートで稼働中のGrowiに転送されたことが確認できます。

# systemctl restart nginx


nginxの設定はひとまず完了したためもう一つのGrowiを導入します。新しいGrowiは3001番ポートで稼動させます。Node.js、npm等の設定は前回の手順で完了しているため、Growiのgitリポジトリの辺りからの設定となります。やっていることは前回の記事とほとんど同じですがgrowiという名前のディレクトリ、サービスなどは既に使われているのでgrowi2としています。

# cd /usr/local/site 
# git clone https://github.com/weseek/growi.git growi2
# cd growi2
# yarn
# yarn add growi-plugin-lsx

新しいGrowi用の設定ファイルを作成します。

# vi /etc/systemd/system/growi2.service
[Unit]
Description=Growi2
After=network.target mongod.service

[Service]
WorkingDirectory=/usr/local/site/growi2
EnvironmentFile=/etc/sysconfig/growi2
ExecStart=/usr/bin/npm start

[Install]
WantedBy=multi-user.target

新しいGrowi用の環境変数ファイルを作成します。

# vi /etc/sysconfig/growi2
PORT=3001
NODE_ENV=production
PASSWORD_SEED="`openssl rand -base64 128 | head -1`"
MONGO_URI="mongodb://localhost/growi2"
FILE_UPLOAD=local

growi2を起動します。

# systemctl daemon-reload
# systemctl start growi2
# systemctl enable growi2

growi2を起動した後ブラウザでhttp://wiki2.imo-tikuwa.com:3001/にアクセスしたところうまく表示できませんでした。Growiが起動していなかったか、wiki2のDNSレコード設定が反映されていなかったか、もしかしたらサブドメインを間違えていたかもしれません。しばらく調べているうちにhttp://[ConoHaのVPSのグローバルIP]:3001/にアクセスしたところ、前回同様管理者情報を登録する初回セットアップ画面が表示されました。


以下はセットアップを終えたgrowi2になります。わかりやすいようテーマを別のものにしてみました。
http://wiki2.imo-tikuwa.com:3001/
BASIC認証あり:growi2 / growi2


growi2に関してもnginxによるリバースプロキシの設定を行います。

# vi /etc/nginx/conf.d/wiki2.imo-tikuwa.com.conf
+server {
+    server_name wiki2.imo-tikuwa.com;
+    access_log  /var/log/nginx/wiki2.imo-tikuwa.com.access_log;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    proxy_set_header Host $http_host;
+    location / {
+        proxy_pass http://localhost:3001;
+    }
+}

nginxを再起動しhttp://wiki2.imo-tikuwa.com/でアクセスできることを確認します。

# systemctl restart nginx


ここまでの設定でConoHaのVPSサーバーにそれぞれが独立した2つのGrowiを導入することができました。最後にCertbot(旧Let’s Encrypt)を導入してSSLに対応させます。

# yum install certbot python2-certbot-nginx


certbotコマンドによる証明書の発行を行います。certbotが証明書発行の際に80番ポートを使用するため直前でnginxを停止し、証明書の発行が終わったら起動しなおします。今回は2つのサブドメインで使用できるドメインを発行します。ちなみに私は以下の画像の通りnginxを停止するのを忘れた状態で証明書の発行を行ったことにより注意されてしまいました。2つ目の画像のようにCongratulations!っていう表記が出て/etc/letsencrypt配下に証明書ファイルが生成されていれば正常に証明書の発行が行えています。

# systemctl stop nginx
# certbot certonly --standalone -d wiki.imo-tikuwa.com -d wiki2.imo-tikuwa.com
# systemctl start nginx

初回起動、nginxの停止するの忘れたときの結果


nginxを停止して再挑戦したときの結果


証明書の有効期限は3ヶ月なので自動で更新するスクリプトを作成します。

# cd /root
# mkdir sh && cd $_
# vi letsencrypt_renew.sh
# chmod +x /root/sh/letsencrypt_renew.sh
#!/bin/sh

systemctl stop nginx
certbot renew --force-renew
systemctl start nginx

作成したスクリプトをcronで2ヶ月毎の1日の午前4時に実行するよう設定します。

# crontab -e
0 4 1 1-12/2 * /root/sh/letsencrypt_renew.sh

先ほど手動で発行したSSL証明書をnginxで読み込むよう設定します。また、これまでのhttpへのリクエストは全てhttpsへ301リダイレクトする設定も行います。

# vi /etc/nginx/conf.d/wiki.imo-tikuwa.com.conf
-server {
-    server_name wiki.imo-tikuwa.com;
-    access_log  /var/log/nginx/wiki.imo-tikuwa.com.access_log;
-    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-    proxy_set_header Host $http_host;
-    location / {
-        proxy_pass http://localhost:3000;
-    }
-}
+server {
+    listen 80;
+    server_name wiki.imo-tikuwa.com;
+    return 301 https://$host$request_uri;
+}
+server {
+    listen 443;
+    server_name wiki.imo-tikuwa.com;
+    ssl on;
+    ssl_certificate         /etc/letsencrypt/live/wiki.imo-tikuwa.com/fullchain.pem;
+    ssl_certificate_key     /etc/letsencrypt/live/wiki.imo-tikuwa.com/privkey.pem;
+    access_log  /var/log/nginx/wiki.imo-tikuwa.com.access_log;
+    proxy_set_header Host $http_host;
+    proxy_set_header X-Real-IP $remote_addr;
+    proxy_set_header X-Forwarded-Proto $scheme;
+    proxy_set_header X-Forwarded-Host $http_host;
+    proxy_set_header X-Forwarded-Server $host;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    location / {
+        proxy_pass http://localhost:3000;
+    }
+}
# vi /etc/nginx/conf.d/wiki2.imo-tikuwa.com.conf
-server {
-    server_name wiki2.imo-tikuwa.com;
-    access_log  /var/log/nginx/wiki2.imo-tikuwa.com.access_log;
-    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-    proxy_set_header Host $http_host;
-    location / {
-        proxy_pass http://localhost:3001;
-    }
-}
+server {
+    listen 80;
+    server_name wiki2.imo-tikuwa.com;
+    return 301 https://$host$request_uri;
+}
+server {
+    listen 443;
+    server_name wiki2.imo-tikuwa.com;
+    ssl on;
+    ssl_certificate /etc/letsencrypt/live/wiki.imo-tikuwa.com/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/wiki.imo-tikuwa.com/privkey.pem;
+    access_log /var/log/nginx/wiki2.imo-tikuwa.com.access_log;
+    proxy_set_header Host $http_host;
+    proxy_set_header X-Real-IP $remote_addr;
+    proxy_set_header X-Forwarded-Proto $scheme;
+    proxy_set_header X-Forwarded-Host $http_host;
+    proxy_set_header X-Forwarded-Server $host;
+    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+    location / {
+        proxy_pass http://localhost:3001;
+    }
+}

最後にnginxを再起動します。ブラウザであえてhttp://wiki.imo-tikuwa.com/にアクセスしhttpsに301リダイレクトされることを確認します。

# systemctl restart nginx


証明書が正しく読み込まれていることを確認します。

ちょっと長くなりましたが今回の内容は以上となります。nginxは仕事で導入されてるサーバーを見ることはあっても自分で導入したことはなかったので設定について以下のサイトで勉強しました。
nginx で SSL リバースプロキシを構築 – WebOS Goodies
nginx で http でのアクセスを https にリダイレクト – Qiita
Apacheに比べて設定が散らばりにくい印象が良いと思いました。


※追記
Certbotで証明書を発行する件についてですが、nginxオプションを有効にすることでnginxの停止は不要であることがわかりました。前々からなんとなく目にはしてたけど実際に動作含めて確認できました。発行済みのSSL証明書を一旦無効化したあとで以下のコマンドで再発行しました。ちなみにnginxはあらかじめ80番ポートの他に443番ポートでlistenしている設定がないと443番ポートの応答がないというエラーが発生してしまうようです。

# certbot --nginx certonly -d wiki.imo-tikuwa.com -d wiki2.imo-tikuwa.com

証明書を更新するスクリプトについても以下のように修正しました。

# vi /root/sh/letsencrypt_renew.sh
#!/bin/sh

-systemctl stop nginx
certbot renew --force-renew
-systemctl start nginx