自室のサーバに専用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サーバのみとします。

前提

以下を用意しています。

  1. nginxサーバ (仮IP: 192.168.1.30)
  • mkcertでローカル証明書を導入済み
  1. redmineサーバ(apacheで稼働)(仮IP: 192.168.1.99)
  2. ローカルDNSに以下を登録します。(自分の環境に読み替えます)
  3. abc.local - 192.168.1.30
  4. 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通信ができていること

を確認します。