LoginSignup
6
7

More than 5 years have passed since last update.

Dockerコンテナで起動するnginxをLets encryptを利用してHTTPS化する

Last updated at Posted at 2017-03-11

修正点

6/28 再度試したところ、letsencryptで証明書を取得するところの選択肢1,2が逆転していました・・・十分注意して確認の上操作していただければと思います。
3/14 letsencryptの証明書を取得するときの引数が一つ抜けていたので修正。大変失礼致しました。

はじめに

前回の続きでnginxコンテナをhttps化対応させます。
証明書はみんな大好きLet's encryptを利用します。

構成

構成の検討

  • はじめはローカルにクライアントソフトを入れて、とか考えてたんですが、DockerイメージでLet's encryptの証明書を取得できる物があるようなので、それを利用する事を考えます。
  • let's encryptで証明書を取得する時、そのホストが該当するDNS名でアクセスできる必要があります。
  • アクセスするポートは80番か、443番でいいようなので、80番をlet's encrypt用、443をnginx用となるように構成を変更します。

構成イメージ

Kobito.MhEsn0.png

設計

フォルダ構造

項目 備考
コンフィグの置き場所 $(pwd)/nginx/etc/nginx/ 以下にconf.dをフォルダを用意しておき、マウントさせます。
証明書の置き場所 /etc/letsencrypt このディレクトリ以下に取得した証明書を配置します。
コンテンツの置き場所 $(pwd)/www コンテンツはカレントディレクトリ直下のwwwディレクトリに配置します。

nginx

  • あまり難しい設定は実施せず、最低限のもののみ投入します。
項目 備考
listen 443 ssl default_server 80番はlistenせず、443のみ待ち受けるものとします。
ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem 証明書のパスを指定します
ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem 証明書のパスを指定します。
server_name ドメイン名 指定したドメイン名で待ち受けるようにします。
root /usr/share/nginx/html コンテナ内のドキュメントルートを/usr/share/nginx/htmlとします。
index index.html インデックスファイルはindex.htmlのみとします。

Docker

  • 同様に最低限のものとします。(前回書いた共通の項目はここには記載しません)
項目 備考
-v $(pwd)/nginx/etc/nginx/conf.d:/etc/nginx/conf.d:ro conf.dディレクトリをマウントします。
-v $(pwd)/www:/usr/share/nginx/html:ro カレントディレクトリ直下にあるwwwディレクトリを/usr/share/nginx/htmlにマウントします。
-v /etc/letsencrypt:/etc/letsencrypt:ro let's encryptで取得した証明書ディレクトリをコンテナ側にマウントします。

設定

let's encrypt証明書の取得

  • 一旦nginxコンテナを止めた上で、該当するDNS名が設定されているホスト上で下記を実行します。
$ docker run -it --rm -p 80:80 --name letsencrypt ¥
      -v "/etc/letsencrypt:/etc/letsencrypt" ¥
      -v "/var/lib/letsencrypt:/var/lib/letsencrypt" ¥
      quay.io/letsencrypt/letsencrypt:latest certonly --preferred-challenges http-01
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Failed to find apache2ctl in PATH: /opt/certbot/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

How would you like to authenticate with the ACME CA?
-------------------------------------------------------------------------------
1: Place files in webroot directory (webroot)
2: Spin up a temporary webserver (standalone)
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):対象のドメイン名を入力
Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for 対象のドメイン名
Waiting for verification...
Cleaning up challenges
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/対象のドメイン名/fullchain.pem. Your
   cert will expire on 2017-06-08. To obtain a new or tweaked version
   of this certificate in the future, simply run certbot again. To
   non-interactively renew *all* of your certificates, run "certbot
   renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
  • これでホスト側の/etc/letsencrypt配下に証明書が生成されてますね!

  • ちなみに更新するときは、下記でいけるようです。(実際には期限が来ていないのでまだ更新はできていません。)

$ docker run -it --rm -p 80:80 --name letsencrypt ¥
      -v "/etc/letsencrypt:/etc/letsencrypt" ¥
      -v "/var/lib/letsencrypt:/var/lib/letsencrypt" ¥
      quay.io/letsencrypt/letsencrypt:latest renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/対象のドメイン名.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/対象のドメイン名/fullchain.pem (skipped)
No renewals were attempted.
  • 自動更新のcronを仕込んでも良いのですが、初回は手動でやりたいので、一旦は仕込みません。

nginxの設定

  • /etc/nginx/conf.d/default.confは下記のような設定とします。
server {
    listen 443 ssl default_server;
    ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;

    server_name ドメイン名;

    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

コンテナの起動

  • --logXXX系のオプションは前回のfluentdの名残なので、不要であれば消して貰えればと思います。
$ docker run --name nginx -v /etc/localtime:/etc/localtime:ro ¥
      -p 443:443 -v $(pwd)/nginx/etc/nginx/conf.d:/etc/nginx/conf.d:ro ¥
      -v $(pwd)/www:/usr/share/nginx/html:ro ¥
      -v /etc/letsencrypt:/etc/letsencrypt:ro ¥
      --log-driver=fluentd --log-opt=fluentd-address=XX.XX.XX.YY:24224 ¥
      --log-opt=tag=docker.{{.FullID}} -d nginx

最後に

  • 簡単に証明書の取得ができるletsencryptは素晴らしいですね。
  • 今回はDockerホストが1つだったため考慮してませんが、実際には証明書をnfs等に配置しておいて、ホストがコケたときは別のホスト上でnginxを再起動することなどを考慮したほうが良いかと思います。

参考

6
7
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
6
7