zaki work log

作業ログやら生活ログやらなんやら

[Ansible] acme_certificateモジュールでLet's Encryptから証明書を発行しApacheでHTTPSサーバー構築

httpdパッケージでApacheをインストール・HTTPS対応し、Let's Encryptの証明書の発行と設定までAnsibleで設定、できるのかな?と思って試したらうまくいった。

Let's Encryptで証明書を作成するには、ACMEプロトコルを利用し、このACMEプロトコルを操作するためのacme_certificateモジュールがAnsibleには(バージョン2.10ではcommunity.cryptoコレクションに)用意されている。

docs.ansible.com

証明書発行部分は外部からのHTTPアクセスに対応できれば良いので、特にApacheである必要はなくNginxでも何でもよい。

環境

(a2.10) [zaki@cloud-dev acme (master)]$ cat /etc/centos-release
CentOS Linux release 7.9.2009 (Core)
(a2.10) [zaki@cloud-dev acme (master)]$ ansible --version
ansible 2.10.2
config file = /home/zaki/src/ansible-sample/acme/ansible.cfg
configured module search path = ['/home/zaki/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /home/zaki/src/ansible-sample/venv/a2.10/lib64/python3.6/site-packages/ansible
executable location = /home/zaki/src/ansible-sample/venv/a2.10/bin/ansible
python version = 3.6.8 (default, Nov 16 2020, 16:55:22) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
  • ターゲットノード(webサーバー)
[root@instance-20200127-2223 ~]# cat /etc/oracle-release 
Oracle Linux Server release 7.9

ドメインは別途設定。

ターゲットノードはOracle CloudのAlways Free枠のインスタンス
グローバルIPとAレコードを設定したFQDNがあれば仕組み的に特に環境は問わない。
外部からの80/TCP443/TCPは全許可。
(証明書発行が済んだら制限して良い)

内容はRPM系のLinux OSになってるので、APT系の場合はコマンドやパスが異なる場合は読み替えること。

playbook

実際に動作確認したものをGitHubにあげていますので急いでる方はこちらをどうぞ。

github.com

流れ

基本的な流れはacme_certificateモジュールのExamplesを見れば良かった。

httpdのインストールとHTTPS対応

Yum系のLinuxの場合は、mod_sslパッケージを入れればlocalhost用証明書付きで/etc/httpd/conf.d/ssl.conf/etc/httpd/conf.modules.d/00-ssl.confも作成される。

証明書がダミーという点を除いて、起動すれば443/TCPでListenする。

なおapache2_moduleモジュールも存在するが、このモジュールで必要なa2enmodAPT系でapache2をインストールすると付属するが、Yumhttpdには含まれてなかった。

Let's Encryptで証明書発行

ExamplesとPlaybookを見た方が早いですが、大まかな流れは以下の通り。

  1. Let's Encrypt用のアカウントキーを作成
  2. サーバー証明書秘密鍵を作成
  3. サーバー証明書秘密鍵から証明書署名要求(CSR)を作成
  4. 作成したアカウントキーとCSRでLet's EncryptにACMEのチャレンジ要求
  5. チャレンジ要求のレスポンスの内容でトークンファイルをwebサーバー上に作成
    • 62-71行目
    • レスポンスはregisterを使えば簡単に参照できる
    • デフォルトのHTTP-01チャレンジに対するトークンファイルは http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN> に作成する
    • 平たく言うと、Let's Encryptが「このファイルをあなたのサーバー上で用意してね。後からそれが設置されてるか見に行く(HTTPアクセスする)よ。設定されてたら証明書作ってあげるね」と言っているので、その通りにする
  6. チャレンジの検証を要求し、証明書を取得する
    • 73-81行目
    • パラメタはチャレンジ要求時とほぼ同じだがdataに最初のレスポンス内容を追加している
  7. webサーバーで鍵のパスを設定する
    • 83-92行目
    • 証明書(crtファイル)が作成されたので、Apacheの設定のSSLCertificateFileSSLCertificateKeyFileの設定で証明書ファイルのパスを設定する

要点

f:id:zaki-hmkc:20210118073427p:plain

f:id:zaki-hmkc:20210118073437p:plain