フリーで90日有効のSSL証明書を取得できる「Let’s Encrypt」
90日毎に更新する必要があるため、プログラムを実行して証明書の取得ができるようになっている。
公式のプログラム(クライアント)は「https://github.com/letsencrypt/letsencrypt」にあるが、CentOS6以降やUbuntu向けに作られており、古いPythonの環境であるCentOS5では動作させるのが大変である。
公式以外のクライアントを探すと、「List of Client Implementations」に互換クライアント一覧がある。
いろいろある中で、一番制約が薄そうな「Shell script (and a little Perl) client: https://github.com/lukas2511/letsencrypt.sh」を選択。
「opensslコマンド」「curlコマンド」「sedコマンド」があれば動作する。
perlはこの一覧が作られた当初は必要だったようだが、2016/01/04時点では不要。公式のletsencryptコマンドから移行する場合に使用するimport-account.plコマンドを使う時だけ必要なようだ。
1. 「git clone https://github.com/lukas2511/letsencrypt.sh」でプログラム取得
2. SSL証明書発行時に使用する一時ディレクトリの設定
SSL証明書発行時、Let’s Encryptサーバから「http://ドメイン名/.well-known/acme-challenge/~」という
アクセスが行われる。その際のファイルを置く場所を用意する。
ここでは/var/www/letsenryptディレクトリに置くことにする。
(1) /var/www/letsencryptディレクトリ作成
(2) Aapacheの設定で「/etc/httpd/conf.d/letsencrypt.conf」を作成
Alias /.well-known/acme-challenge /var/www/letsencrypt <Directory /var/www/letsencrypt/> </Directory>
(3) Aapacheの再起動
3. config.shを作成
config.sh.exampleを元にconfig.shを作成
といっても、下記の行を書くだけ
WELLKNOWN="/var/www/letsencrypt/"
4. domain.txtを作成
SSL証明書を発行したいドメインをスペース区切りで列挙する。
blog.osakana.net blog2.osakana.net
5. letsencrypt.shを実行
# ./letsencrypt.sh --config /~/letsencrypt.sh/config.sh --cron Using config file /~/letsencrypt.sh/config.sh Processing blog.osakana.net with SAN: blog2.osakana.net + Signing domains... + make directory /~/letsencrypt.sh/certs/blog.osakana.net ... + Generating private key... + Generating signing request... + Requesting challenge for blog.osakana.net... + Responding to challenge for blog.osakana.net... + Challenge is valid! + Requesting challenge for blog2.osakana.net... + Responding to challenge for blog2.osakana.net... + Challenge is valid! + Requesting certificate... + Checking certificate... + Creating fullchain.pem... + Done! #
下記の様にcertsディレクトリ以下にファイルが作成される。
# ls -F certs/ domains.txt import-certs.sh* private_key.pem config.sh domains.txt.example letsencrypt.sh* README.md config.sh.example import-account.pl* LICENSE test.sh* # ls -F certs/ blog.osakana.net/ # ls -F certs/blog.osakana.net/ cert-xxxxxxxxxx.csr chain-xxxxxxxxxx.pem privkey-xxxxxxxxxx.pem cert-xxxxxxxxxx.pem chain.pem@ privkey.pem@ cert.csr@ fullchain-xxxxxxxxxx.pem cert.pem@ fullchain.pem@ #
Apache設定内のSSLファイルの指定では、作成されたファイルのうち、fullchain.pemとprivkey.pem,chain.pemを指定する。
SSLCertificateFile /~/certs/~/fullchain.pem SSLCertificateKeyFile /~/certs/~/privkey.pem SSLCertificateChainFile /~/certs/~/chain.pem
ちなみに、「SSLCertificateChainFile /~/certs/~/chain.pem」を抜いた2行で設定するとChromeやIEでは問題無いが、Firefoxでのみ「sec_error_unknown_issuer」のエラーがでる。
(なお、fullchain.pemとprivkey.pemを指定しているのは、標準のletsencryptを使った場合に生成されるapache用cocnfigファイルで使われていたから)
おまけ:CentOS4で使用する場合に必要になること
・curlの証明書問題
→ /usr/share/ssl/certs/ca-bundle.crt を更新する
→ OpenSSLが古いためにエラーが発生
「curl: (35) error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm」
・OpenSSLが古い
→ /usr/local/openssl1とかに新しいバージョンをインストールして回避
letsencrypt.shの冒頭に、PATHとLD_LIBRARY_PATHを定義して、こちらを優先するように設定
→ こっちのOpenSSLを使うcurlをコンパイル
・trコマンドが古い
letsencrypt.shを実行すると「tr: オプションが違います — _」というエラー
→ 新しいバージョンのtrが含まれるcoreutilsを/usr/localにインストール
・bashコマンドが古い
環境変数操作で「SAN+=~」ということをやってるがCentOS4のBASHでは非対応
letsencrypt.shを修正して、CentOS4でも使える操作に変更
「SAN+=”DNS:${altname}, “」→「SAN=”${SAN}DNS:${altname}, “」
・下記のエラーでうまく行かない
# ./letsencrypt.sh --cron --config /~/letsencrypt.sh/config.sh Using config file /~/letsencrypt.sh/config.sh Processing xxxxxx with SAN: xxxxx + Signing domains... + Generating private key... + Generating signing request... + Requesting challenge for xxxxxx... + ERROR: An error occurred while sending post-request to https://acme-v01.api.letsencrypt.org/acme/new-authz (Status 403) Details: {"type":"urn:acme:error:unauthorized","detail":"No registration exists matching provided key","status":403} + Error: Can't retrieve challenges () #
→ 失敗した時のcertが悪さをしていた
certsディレクトリの中身とprivate_key.pemを削除して再実行したところ成功