LoginSignup
17
14

More than 5 years have passed since last update.

CentOS7上でnginxとDockerとLetsEncryptでSSLをごにょごにょする話

Last updated at Posted at 2016-03-08

LetsEncryptを使ってみたかった。
nginxでHTTPリクエストを受けてリバースプロキシでコンテナのHTTPサーバにproxy_passしている状態からLetsEncryptのSSL証明書を利用したい。

前提

CentOS 7.2(host)
docker 1.8
nginx 1.9
コンテナはFROM centos:centos7でDockerfileを使って立てたもの。

課題

すでに立てているコンテナは80/tcpしか空けていない。
コンテナを作り直すのは嫌だなあ、と考えた。

実現方法

フォルダを共有する方法で、コンテナの鍵フォルダをホスト側に共有し、ホスト側で見えた鍵をnginxで利用する。

ホスト側の操作

共有用のフォルダを作成する

$ sudo mkdir /etc/nginx/cert

まあ、どこでもいいのだが、nginxのところに作った。

コンテナのエクスポートとインポート

$ sudo docker stop <container_id>
$ sudo docker export <container_id> > container_name.tar
$ sudo cat container_name.tar | docker import - <repository>:<tag>

一旦止めてファイルに書き出して、イメージとしてインポートする必要がある。

コンテナの起動

$ sudo docker run --privileged -v /etc/nginx/cert:/etc/letsencrypt/ -d --name <new_container_name> -it -p 20080:80 <repository>:<tag>

-vオプションでコンテナの/etc/letsencrypt/をホストの/etc/nginx/certと共有するように設置した。

nginxの設定と再起動

すでにインストールされている前提なので、インストールは省略。

/etc/nginx/conf.d/virtual.conf
server {
    listen 80;
    server_name www.hogehoge.com;
    location / {
        proxy_pass http://127.0.0.1:20080;
    }
}

nginxを再起動する。

$ sudo systemctl reload nginx

コンテナの操作

コンテナでLetsEncryptをインストールする

すでにコンテナでHTTPサーバが起動している前提。

$ sudo su -
$ cd ~
# git clone https://github.com/letsencrypt/letsencrypt
# cd letsencrypt/
# ./letsencrypt-auto --help
# ./letsencrypt-auto certonly --webroot --webroot-path /var/www/html -d www.hogehoge.com
# exit

大体うまくゆく。

コンテナで証明書を更新するためのcronを設定する

$ sudo crontab -e
00 03 01 * * /root/letsencrypt/letsencrypt-auto certonly --webroot --webroot-path /var/www/html -d www.hogehoge.com --renew-by-default

毎月1日の午前3時にcronが動いて、証明書を更新する。

再度ホスト側の操作

証明書があることを確認する

$ sudo ls -l /etc/nginx/cert/live/www.hogehoge.com/
合計 0
lrwxrwxrwx 1 root root 34  3月  6 00:10 cert.pem -> ../../archive/www.hogehoge.com/cert1.pem
lrwxrwxrwx 1 root root 35  3月  6 00:10 chain.pem -> ../../archive/www.hogehoge.com/chain1.pem
lrwxrwxrwx 1 root root 39  3月  6 00:10 fullchain.pem -> ../../archive/www.hogehoge.com/fullchain1.pem
lrwxrwxrwx 1 root root 37  3月  6 00:10 privkey.pem -> ../../archive/www.hogehoge.com/privkey1.pem

ホストでnginxの再設定と再起動

confを編集する。

/etc/nginx/conf.d/virtual.conf
server {
    listen 80;
    server_name www.hogehoge.com;
    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    listen 443;
    server_name www.hogehoge.com;

    ssl on;
    ssl_certificate     /etc/nginx/cert/live/www.hogehoge.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/cert/live/www.hogehoge.com/privkey.pem;

    ssl_session_timeout  5m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256;
    ssl_prefer_server_ciphers   on;
    add_header Strict-Transport-Security 'max-age=31536000;includeSubDomains;';

    location / {
        proxy_pass http://127.0.0.1:20080;
    }
}

nginxを再起動する。

$ sudo systemctl reload nginx

ホスト側でもcronを走らせる

$ sudo crontab -e
00 04 01 * * /usr/bin/systemctl reload nginx

毎月1日の午前4時にcronが動いて、nginxを再起動する。

これで作業完了

補足

コンテナのDockerfileでは、以下のようにhttpdとcrondのサービスを起動する設定にしておくのがコツ。

Dockerfile
FROM centos:centos7
RUN systemctl enable httpd
RUN systemctl enable crond
EXPOSE 80
17
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
14