Redmineコンテナのhttps化


社内開発用にdockerコンテナで立てたRedmineサイトをSSL化したので備忘録に。
dockerコンテナでなければnginxでSSL処理して、WordPressにプロクシーしてWordpressの設定でサイトURLをhttpsにすればよかったと思う。

しかし、dockerコンテナでssl化となると単純にいかず調べてみたところ、
1. docker-composeでnginxコンテナも一緒に立ててSSL処理をコンテナ内部でも行うようにする。wordpressコンテナ側はhttpsでリクエストが来る前提で単純設定のみで行う。
2. nginxはプロセスで動かしhttpsでリクエスト処理はこの中だけで完結させ、httpでwordpressコンテナにプロクシーする。wordpress側は各URIはhttpsになるようにしつつ、サイトURLはプロクシーURLのhttpで行えるようにする。

docker経験が浅いのでいまだcomposeが理解できず、2の方法をとりました。

ハマッたこと

たぶん正攻法でないやり方だったため、wordpressの中でサイトURLとリンクURLを分ける必要にかられ、データの修正だけでは対応できずソースをいじる必要にかられたこと。
nginxでもしかしたらクライアントに返す

要件

  • Redmineコンテナのイメージは「74th/redmine-all-in-one」を使った。
  • httpsでRedmineにアクセスできるようにする。
  • ただし、同一サーバに別サイトも立てるのでサブディレクトリでアクセスできるように。

コンテナで立てたRedmineのサブディレクトリ化の方法ではまった。

Redmineコンテナのサブディレクトリアクセス化

実際は半日ほどはまったが、実際やることは少ない。

立てたRedmineコンテナにbashで侵入。

docker exec -it redmine bash

vimが入ってないのでインストール。

apt-get update
apt-get install vim
apt-get install lsof

apacheの設定ファイルにbaseurl変更を追加。

/etc/apache2/apache2.conf
RackBaseURI /redmine
RailsBaseURI /redmine

バーチャルホストのドキュメントルートを変更する。

/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
-    DocumentRoot /var/lib/redmine/public
+    DocumentRoot /var/www/html

apacheのデフォルトのドキュメントルートにエイリアスをはる。

ln -s /var/lib/redmine/public /var/www/html/redmine

apacheを再起動

service apache2 restart

ここまでで「http://ホスト:[Redmineコンテナのバインドポート]/redmine/」でRedmineサイトがアクセスできることを確認する。

SSL証明書を取得

LetsEncryptで取得。Webサーバが立っているわけではないので、初期取得はスタンドアローンモードで行い、自動更新はサーバモードで行う。
尚当たり前であるが、これ以降の操作はコンテナ内ではなく、Dockerを動かしているサーバで実施する。

certbotのインストール

wget https://dl.eff.org/certbot-auto
chmod 700 certbot-auto

AMLを公式サポートしていないため部分的に書き換えが必要。
エディタで開いて、

elif [ -f /etc/issue ] && grep -iq "Amazon Linux" /etc/issue ; then
  Bootstrap() {
    ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
  }
  BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"

の部分を下記のように書き換える。

 elif grep -i "Amazon Linux" /etc/issue > /dev/null 2>&1 || \
   grep 'cpe:.*:amazon_linux:2' /etc/os-release > /dev/null 2>&1; then
  Bootstrap() {
    ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
  }
  BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"

書き換えたらpathが通っている場所に移して、ウィザードを立ち上げて入力して証明書を取得する。

sudo mv ./certbot-auto /usr/local/bin
certbot-auto certonly --standalone -d [ドメイン名] --debug

取得した証明書一式は/etc/letsencrypt/live/[ドメイン名]/ 以下に保存されている。

証明書の自動更新設定

まずはコマンドを打って更新が可能か確認
ここではnginxがプロクシで暗号化通信をする前提で。

/usr/local/bin/certbot-auto certonly --standalone -d [ドメイン名] --keep --pre-hook 'systemctl stop nginx' --post-hook 'systemctl start nginx'

証明書ファイルの更新日時が刷新されていればOK。
上記をシェル化しておきクーロンに設定しておく。

crontab -e
0  0  */10  *  * root cd /root; ./update-letsencrypt.sh >> /root/upd-encrypt.log 2>&1

nginxのインストールと設定

インストール

sudo amazon-linux-extras install nginx1.12

取得した証明書を組み込み、Redmineサイトへのプロクシー設定を行う。

nginx.conf
    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

+        ssl_certificate "/etc/letsencrypt/live/domain/fullchain.pem";
+        ssl_certificate_key "/etc/letsencrypt/live/domain/privkey.pem";

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

+        #Redmineサーバ
+        location ^~ /redmine/ {    #"/redmine/"で前方一致する場合
+            proxy_pass http://domain:8080/redmine/;
+        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

nginxを再起動して確認します。

systemctl restart nginx

問題なくhttpsでアクセスできることが確認できたら、httpアクセスをhttpsに矯正する
設定をnginxに追加する。

nginx.conf
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
+        rewrite ^ https://$server_name$request_uri? permanent;

以上です。