SSL証明書更新できず方法変更(ZeroSSL)

以前、SSL証明書を取得しましたが、先月から更新ができず、エラーを起こすようになってしまいました。それによって、本サーバーへのhttpsでのアクセスができなくなってしまいました。

これまで無料の証明書発行をLet’s Encryptに頼っていましたが、いろいろ試行錯誤を繰り返しても更新ができず、Let’s Encryptの代替となるサービスを探しました。いろいろ試していて、Let’s Encrypt自体の問題ではなく、自作サーバーへの承認確認のためのアクセスが何らかの理由でできなくて拒否されていたのだと思います。たぶんLet’s Encryptの承認の確認方法も変わったのだと思います。

これまで、以下のようなメッセージは出なかったと思います。それが、.well-known/acme-challengeというディレクトリを作成してそこにファイルを生成して確認する仕方に替わっているように思いました。このディレクトリが生成されず、アクセス制限などいろいろと試行錯誤したのですが、うまくいきませんでした。
——————————————————
Detail: Fetching http://hobby.mydns.jp/.well-known/acme-challenge/~: Timeout during connect (likely firewall problem)

To fix these errors, please make sure that your domain name was entered correctly and the DNS A/AAAA record(s) for that domain contain(s) the right IP address. Additionally, please check that your computer has a publicly routable IP address and that no firewalls are preventing the server from communicating with the client. If you’re using the webroot plugin, you should also verify that you are serving files from the webroot path you provided.
——————————————————

Let’s Encryptの代替として、ZeroSSLを利用してみることにしました。ZeroSSLはWEB上でSSL証明書を取得できるようです。こちらの手法でも"Let’s Encrypt"と同じくHTTPファイルアップデートモードでの認証がありますが、これもアクセス制限によるものなのか"Let’s Encrypt"と同じエラーメッセージで導入できませんでしたので、DNS認証で取得するようにしました。

DNS認証の場合の動作として、上記リンクの手順で進めていって表示されたNameとPointToの値をドメイン設定サイト(私の場合:mydns)に設定して、審査を受けるようにします。

レコードタイプはCNAME、Name、Point toの情報をドメイン設定サイトに登録します。この時、NextStepのボタンは、ドメイン設定サイトへの登録が終わってから押します。

MyDNSの場合、"Type"はCNAMEを選択、"Hostname"がName、"Content"がPoint toの部分にあたります。"Hostname"の部分はNameのドメインより前の(先頭から"."より前)を記載します。"Content"の部分はPoint toの値全部を記載します。

進めていって、確認が取れればファイルをダウンロードできるようになります。

ダウンロードしたZIPファイルの中身は次の3ファイルとなります。
・ca_bundle.crt
・certificate.crt
・private.key

これらを/etc/ssl/などに保存した後、このファイルに以前の設定はコメントアウトして、新しい設定を追加します。
vi /etc/httpd/conf.d/ssl.conf

#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
# Let's Encrypt #
#SSLCertificateFile /etc/letsencrypt/live/hobby.mydns.jp/cert.pem
# ZeroSSL #
SSLCertificateFile /etc/ssl/certificate.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
# Let's Encrypt #
#SSLCertificateKeyFile /etc/letsencrypt/live/hobby.mydns.jp/privkey.pem
# ZeroSSL #
SSLCertificateKeyFile /etc/ssl/private.key

#   Server Certificate Chain:
#   Point SSLCertificateChainFile at a file containing the
#   concatenation of PEM encoded CA certificates which form the
#   certificate chain for the server certificate. Alternatively
#   the referenced file can be the same as SSLCertificateFile
#   when the CA certificates are directly appended to the server
#   certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
# Let's Encrypt #
#SSLCertificateChainFile /etc/letsencrypt/live/hobby.mydns.jp/chain.pem

#   Certificate Authority (CA):
#   Set the CA certificate verification path where to find CA
#   certificates for client authentication or alternatively one
#   huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
# ZeroSSL #
SSLCACertificateFile /etc/ssl/ca_bundle.crt

設定後、httpdを再起動します。
%>systemctl restart httpd.service
ここまでが、手動での取得方法ですが、これを自動化することにしました。

【自動化】
自動化において、certbotコマンドを使って コマンドラインでSSL 証明書を発行していましたが、certbot が動かなくなってエラーがどうしても解消できなくて途方に暮れていました。面倒でも前述のとおり、ZeroSSLのWEBサイトで手動で更新するしかないのか?と落胆していましたが、別の手段を見つけて、LEGOというもので対応してみようと思いました。

このLEGOのサイトにはmydnsに関する設定も記載されていたので、組み合わせて何とかならないものか?ということでやってみることにしました。
LEGOのインストールは、サイトからダウンロードします。
「lego_v4.4.0_linux_386.tar.gz」をダウンロードし解凍後、/usr/local/bin/にlegoの実行ファイルを置きました。

cp -p /Downloads/lego_v4.4.0_linux_386/lego /usr/local/bin/

続いて、ZeroSSLのAPI Keyを確認します。

その後に、バッチファイルを作成しました。バッチファイル内で"jq"というコマンドを使って処理しているため、先にjqをインストールしておきます。

yum install jq –enablerepo=epel

バッチの作成
vi /etc/ssl/zerossl/lego.sh

------------------------------------------------------
#!/bin/bash

ACCESS_KEY=ZeroSSLのAPI Keyを設定
JSON=$(curl -s -X POST "https://api.zerossl.com/acme/eab-credentials?access_key=$ACCESS_KEY")
EAB_KEY=$(echo "$JSON" | jq -r .eab_kid)
EAB_HMAC_KEY=$(echo "$JSON" | jq -r .eab_hmac_key)

MYDNSJP_MASTER_ID=mydnsログインIDを設定 \
MYDNSJP_PASSWORD=mydnsのログインパスワードを設定 \
/usr/local/bin/lego \
        --dns mydnsjp \
        --path /etc/ssl/zerossl \
    --eab --kid "$EAB_KEY" --hmac "$EAB_HMAC_KEY" \
    --server "https://acme.zerossl.com/v2/DV90" \
    --email "メールアドレス設定" \
    --domains "ドメインを設定" \
    -a run
------------------------------------------------------

このバッチを定期的に実行するようにします。毎月1日の5時に実行するように設定してみます。
vi /etc/crontab

00 05 01 * * root /etc/ssl/zerossl/lego.sh 2>&1 | mail -s "ZeroSSL update information" 通知先メールアドレス && systemctl restart httpd

取得するSSL証明書名が変わるので、/etc/httpd/conf.d/ssl.confを変更します。
vi /etc/httpd/conf.d/ssl.conf

------------------------------------------------------
#   Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate.  If
# the certificate is encrypted, then you will be prompted for a
# pass phrase.  Note that a kill -HUP will prompt again.  A new
# certificate can be generated using the genkey(1) command.
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
# ZeroSSL #
#SSLCertificateFile /etc/ssl/certificate.crt
SSLCertificateFile /etc/ssl/zerossl/certificates/ドメイン名.crt

#   Server Private Key:
#   If the key is not combined with the certificate, use this
#   directive to point at the key file.  Keep in mind that if
#   you've both a RSA and a DSA private key you can configure
#   both in parallel (to also allow the use of DSA ciphers, etc.)
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
# ZeroSSL #
#SSLCertificateKeyFile /etc/ssl/private.key
SSLCertificateKeyFile /etc/ssl/zerossl/certificates/ドメイン名.key

#   Server Certificate Chain:
#   Point SSLCertificateChainFile at a file containing the
#   concatenation of PEM encoded CA certificates which form the
#   certificate chain for the server certificate. Alternatively
#   the referenced file can be the same as SSLCertificateFile
#   when the CA certificates are directly appended to the server
#   certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
# Let's Encrypt #
#SSLCertificateChainFile /etc/letsencrypt/live/hobby.mydns.jp/chain.pem
# ZeroSSL #
#SSLCACertificateFile /etc/ssl/ca_bundle.crt
SSLCACertificateFile /etc/ssl/zerossl/certificates/ドメイン名.issuer.crt

#   Certificate Authority (CA):
#   Set the CA certificate verification path where to find CA
#   certificates for client authentication or alternatively one
#   huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
# ZeroSSL #
#SSLCACertificateFile /etc/ssl/ca_bundle.crt
SSLCACertificateFile /etc/ssl/zerossl/certificates/ドメイン名.issuer.crt
------------------------------------------------------

【補足】
%> httpd -v
Server version: Apache/2.4.6 (CentOS)

SSLCertificateChainFile と SSLCACertificateFile の違い
・SSLCertificateChainFileディレクティブ:サーバー証明書における中間証明書のパスを設定
・SSLCACertificateFileディレクティブ:クライアント証明書における中間証明書のパスを指定
※Apache2.4.8以降はSSLCertificateChainFileディレクティブはない。

privkey.pem:秘密鍵
cert.pem:証明書
chain.pem:中間証明書
fullchain.pem:証明書と中間証明書を連結したファイル
↑「%> cat cert.pem chain.pem > fullchain.pem」

↓今回の自動化で生成されるファイルは3つしかない。発行された証明書にはCA証明書も含まれている。
$domain.crt:サーバー証明書です(CA証明書を含む;fullchain.pemと同等)
$domain.key:サーバー証明書の秘密鍵(= privkey.pem)
$domain.issuer.crt:CA証明書のみ
$domain.json:いくつかのメタ情報が含まれる

◇バージョン2.4.7以前の場合
httpd.conf

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem ←$domain.crt
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem ←$domain.key
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem ←$domain.issuer.crt

◇バージョン2.4.8以降の場合
httpd.conf

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem ←$domain.crt
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem ←$domain.key

UNIX

Posted by 伊藤 輝樹