自室のサーバに専用redmineを運用するようになって半年ほど。一つの課題が浮かび上がりました。
課題
現状、
- redmine
- フォトアルバム
- growi
を自宅サーバ群で運用中。Webサービスが増えるたびに「証明書更新をサーバ毎に行うのが面倒」です。ワイルドカード証明書を用いて、シンボリックリンクの張り替えで済むようにしてもなお各サーバに同じ設定を行うのは手間がかかる上にミスが生じる温床となります。
施策
そこで、既にgrowiサーバで運用しているnginxのリバースプロキシーをredmineにも拡張するようにしました。
やりたいことは以下です。(IPアドレスとドメインは便宜上です)
sequenceDiagram
participant クライアント
participant nginx as nginxサーバ<br> 192.168.1.30<br>abc .local
participant redmine as redmine<br> 192.168.1.99<br>xyz.local
クライアント->> nginx: abc.localにhttpアクセス
par クライアント~nginxはhttps通信
note over nginx: httpsにリライト
nginx -->> クライアント: httpsでの接続要求
and nginx~redmineはhttp通信
クライアント ->> nginx: redmineにhttpsアクセス
note over nginx: SSLデコード
nginx -->>+ redmine: クライアントからの要求を<br>redmine(xyz.local)に送信
redmine -->>- nginx: redmineのデータを送信
end
nginx ->> クライアント:redmineからのデータを<br>abc.localとしてhttpsで送信
サクッとまとめると
- redmineサーバのリバースプロキシーとしてnginxを利用
- クライアント~nginxは常時SSL通信
- nginx ~ redmineはhttp通信
これにより、SSLを導入する箇所をnginxサーバのみとします。
前提
以下を用意しています。
- nginxサーバ (仮IP: 192.168.1.30)
- mkcertでローカル証明書を導入済み
- redmineサーバ(apacheで稼働)(仮IP: 192.168.1.99)
- ローカルDNSに以下を登録します。(自分の環境に読み替えます)
- abc.local - 192.168.1.30
- xyz.local - 192.168.1.99
環境
ともにUbuntu Linux 20.04系で動いています。
手順
全て管理者権限で実施します
redmineサーバでの設定(apache)
以下、ファイルを編集します。
vi /etc/apache2/sites-available/redmine.conf
ファイル内容
<Location /redmine>
PassengerBaseURI /redmine
PassengerAppRoot /var/lib/redmine
Require all granted
</Location>
Alias /redmine /var/lib/redmine/public
<VirtualHost 192.168.1.99:80>
ServerName abc.local
ErrorLog /var/log/redmine/error.log
CustomLog /var/log/redmine/access.log combined
RewriteEngine On
RewriteCond %{HTTP_HOST} ^abc\.local
RewriteRule ^/$ http://abc.local/redmine/ [R]
</VirtualHost>
設定反映
a2ensite redmine.conf
apache2ctl configtest
#Syntax OKを確認
systemctl restart apache2
nginxサーバでの設定
hostsファイル追記
vi /etc/hosts
追記内容
192.168.1.30 abc.local
nginx confファイル作成
vi /etc/nginx/sites-available/redmine.conf
ファイル内容
upstream abc {
server 192.168.1.99:80;
}
server {
listen 80;
server_name abc.local;
server_tokens off;
return 301 https://$host$request_uri;
access_log /var/log/nginx/redmine/access.log;
error_log /var/log/nginx/redmine/error.log warn;
}
server {
listen 443 ssl http2;
server_name abc.local;
server_tokens off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_dhparam /etc/nginx/dhparam.pem;
#openssl dhparam -out /etc/nginx/dhparam.pem 2048 として作成します(環境によっては5分以上かかります)
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security 'max-age=63072000';
ssl_certificate /etc/certs/local.crt;
# 証明書のパスに読み替えます
ssl_certificate_key /etc/private/local.key;
# 秘密鍵のパスに読み替えます
access_log /var/log/nginx/redmine/ssl_access.log;
error_log /var/log/nginx/redmine/ssl_error.log warn;
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;
proxy_set_header X-Forwarded-Proto https;
proxy_max_temp_file_size 10240m;
client_max_body_size 10240m;
proxy_buffer_size 10240m;
proxy_buffers 10 10240m;
proxy_busy_buffers_size 10240m;
proxy_redirect off;
set $proxy_target 'abc';
location / {
proxy_pass http://$proxy_target;
}
}
設定反映
ln -s /etc/nginx/sites-available/redmine.conf /etc/nginx/site-enabled/redmine.conf
nginx -t
# syntax is ok と test is successfulを確認します
systemctl restart nginx -t
確認
ローカルNWに接続されているクライアントのブラウザから
http://abc.local
にアクセスし、
- https://abc.local/redmine の内容が出てくること
- SSL通信ができていること
を確認します。