CentOS 7 で Let's Encrypt

  • 2016-07-23T10:23 自動更新について追記、パッケージ名やコマンド名を更新しました。

CentOS 7 で動かしてるサーバーがあって、サーバー証明書には StartSSL を使ってたんだけど、それを Let's Encrypt に乗り換えてみた。

インストール

公式には git-clone するやり方が書いてあるけど、CentOSでは EPEL のパッケージが使えるので、こっちを使う。EPEL の導入は省略。

# yum -y install certbot

証明書の発行

パッケージなので certbot-auto ではなくて、certbot を使う。それ以外は同じ。プラグインは webroot と standalone が使える。すでにサービスが動いているので webroot を使うことにする。

# certbot certonly --webroot -w /var/www/html -d example.org -d www.example.org

証明書のインストール

certbot certonly コマンドを実行すると以下のファイルができるので、ソフトウェアに合わせて設定すればいい。

パス
/etc/letsencrypt/live/(ドメイン)
cert.pem
証明書
privkey.pem
証明書の秘密鍵
chain.pem
中間証明書
fullchain.pem
中間証明書とルート証明書
Apache

プラグインがないので手動でインストールしないといけない。

SSLCertificateFile /etc/letsencrypt/live/example.org/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.org/chain.pem

再読み込み。

# systemctl reload httpd.service
OpenLDAP

こいつでちょっとハマった。

# ls -ld /etc/letsencrypt/{archive,live}
drwx------. 2 root root 48 Apr 30 22:28 /etc/letsencrypt/archive
drwx------. 2 root root 48 Apr 30 22:28 /etc/letsencrypt/live
# ps aux | grep slapd
ldap      7519  0.0  1.4 817420 14552 ?        Ssl  Apr30   0:00 /usr/sbin/slapd -u ldap -h ldapi:/// ldap:/// ldaps:///
root      7755  0.0  0.0 112644   960 pts/2    R+   01:07   0:00 grep --color=auto slapd

slapd は ldap ユーザーで動いているけど、証明書のあるディレクトリは root でしかアクセス出来ない (live の中身は archive へのリンクになっている)。所有権を直接変えることもできるけど、他のサービスとぶつかると嫌なので ACL を使うことにする。

# setfacl -m u:ldap:rx /etc/letsencrypt/{archive,live}
# ls -ld /etc/letsencrypt/{archive,live}
drwxr-x---+ 4 root root 48 Apr 30 22:28 /etc/letsencrypt/archive
drwxr-x---+ 4 root root 48 Apr 30 22:28 /etc/letsencrypt/live
# getfacl /etc/letsencrypt/{archive,live}
getfacl: Removing leading '/' from absolute path names
# file: etc/letsencrypt/archive
# owner: root
# group: root
user::rwx
user:ldap:r-x
group::---
mask::r-x
other::---

# file: etc/letsencrypt/live
# owner: root
# group: root
user::rwx
user:ldap:r-x
group::---
mask::r-x
other::---

LDIF ファイルを書いて OLC で設定変更する。

dn: cn=config
changeType: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/live/example.org/cert.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/live/example.org/privkey.pem
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/live/example.org/chain.pem
# ldapmodify -H ldapi:/// -Y EXTERNAL -f change_tls.ldif

だけじゃだめで、サービスを再起動する。

# systemctl restart slapd.service

証明書の更新

証明書を更新するには、certbot renew を実行して、サービスの再読み込みや再起動する。

# certbot renew
(記録しそこねたけど、メッセージが表示される)
# systemctl reload httpd.service
# systemctl restart slapd.service

CentOS 7 なので、自動更新には cron ではなくて systemd を使う。

  • /etc/systemd/system/certbot.service
[Unit]
Description=Let's Encrypt certificate renewal

[Service]
Type=oneshot
ExecStart=/bin/certbot renew
ExecStartPost=/bin/systemctl reload httpd.service
ExecStartPost=/bin/systemctl restart slapd.service

certbot renew で更新されるのは有効期限まで 30 日未満のものだけなので、毎週実行されるようにする。

  • /etc/systemd/system/certbot.timer
[Unit]
Description=Let's Encrypt weekly certificate renewal

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
# systemctl enable certbot.timer
# systemctl --type=timer --all
UNIT                         LOAD   ACTIVE   SUB     DESCRIPTION
certbot.timer                loaded inactive dead    Let's Encrypt monthly certificate renewal
systemd-readahead-done.timer loaded inactive dead    Stop Read-Ahead Data Collection 10s After Completed Startup
systemd-tmpfiles-clean.timer loaded active   waiting Daily Cleanup of Temporary Directories

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.