設定例付き!Let’s EncryptでGetSSLを導入する方法を徹底解説

Linux

メンテナンスを請け負っている会社は当初はSSL/TLSの暗号化通信に自己署名したいわゆるオレオレ証明書を使っていました。外部に公開するコンテンツもなく、メールも社内のやり取りに使うくらいなので、暗号化ができていれば十分という導入当初の要件があったためです。

ですが、やっぱり証明書の警告が煩わしいということで、SSL/TLSv2,v3対応の際にフリーの認証局Let’s Encryptの証明書を使おうということになりました。Let’s Encryptについての説明はこちらを参照してください。

Let’s Encryptで一番おすすめされているクライアントはCertbotなのですが、訳あって使えず。他の推奨クライアントであるGetSSLを利用しました。利用したバージョンはv2.43です。

なぜGetSSLなのか

Let’s Encryptで推奨されているクライアントはCertbotというツールですが(Let’s Encrypt ACME クライアント実装)、今回は使えなかったです。

あれこれ調べた結果、Certbotのインストールにはaptやdnfやyumといったパッケージ管理ツールが必要な模様。私が管理しているサーバーは古すぎてそういったパッケージ管理ツールは使えず、Certbotのインストールが不可能でした。

ドキュメントをよく見ると他にも使えるクライアントがあるとのこと。その中からGetSSLを選びました。選んだ理由は次の2点です。

  • 特別な環境を準備しなくてもBashで動く
  • リモートのホストに対しても動作する

GetSSLの導入~設定

設定に必要なことはGetSSLのGitHubページにだいたい書いています。

利用しているDNSサーバーがリモートでAPIなどによる操作に対応していなかったため、ドメイン検証には「well-known な URI で指定した HTTP リソースを公開すること」の方を利用しています。

ちなみに利用しているDNSサーバーがAPI等で操作可能であればドメイン名にワイルドカードを指定した証明書を作成できます(*.mackii.netとか。この場合www.mackii.netでもwww2.mackii.netでも利用できる。)

動作に必要なソフトウェア

getsslの動作にはcurlが必要です。通常であればだいたいデフォルトでインストールされています。

私はインストールをcurlでやろうとしたらエラーになったので(下記参照、原因はCA証明書の期限切れ、およびSSL/TLSv2未対応のため)、仕方なくブラウザでダウンロードしてWinSCPでサーバーへアップロードして無理矢理動かそうとしたら、スンと無言で終了し、実はプログラム内部でもcurlを使っていて、curlが必要だと気付きました。

※ インストールでスンと無言でエラーの例

[root@mackii ~]# curl --silent https://raw.githubusercontent.com/srvrco/getssl/latest/getssl > getssl ; chmod 700 getssl
[root@mackii ~]# ll getssl
-rwx------ 1 root root 0 2022-07-11 16:26 getssl (※ なぜかファイルサイズが0バイト)
[root@mackii ~]# curl https://raw.githubusercontent.com/srvrco/getssl/latest/gets
sl > getssl
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (35) SSL connect error (※ オプション外してみたらSSLでエラー)

おそらくdnfなど近代的なツールが使えない環境であればSSL/TLSのバージョン2や3に対応できなくてcurlも使えなくなって上記の例のようになっている人がいるんでは?と思います。

そんな場合はCA証明書を更新したりnssをアップデートしたりしてcurlを使えるようにしておきましょう!

GetSSLのダウンロード・インストール

READMEの通り、curlでダウンロードして権限付与しましょう。実体がシェルスクリプトなのでインストール作業は特に必要なくダウンロードして権限付与すればOKです。

自分は証明書関連ということでrootユーザーで実施、実行モジュールも/rootフォルダに置きました。/usr/sbinとかに置いてもよかったかも。

[root@mackii ~]# curl --silent https://raw.githubusercontent.com/srvrco/getssl/latest/getssl > getssl ; chmod 700 getssl

設定

設定手順は以下のようになります。

  1. 初期化(設定ファイルの生成)
  2. 設定ファイルの修正
  3. 設定ファイルのテスト実行(staging環境)
  4. 実行(本番環境)
  5. cron設定

初期化

[root@mackii ~]# ./getssl -c 証明書発行対象のドメイン名

上記コマンドを実行すると実行ユーザーのホームフォルダに.getsslのフォルダが作成されます。
フォルダ名の先頭に.(ドット)がついた隠しフォルダになっています。

[root@mackii ~]# ls -la .getssl/
・・・・
drwxr-xr-x   3 root root 4096 2022-06-05 10:20 .
drwxr-x---. 23 root root 4096 2022-06-04 19:39 ..
-rw-r--r--   1 root root 3012 2022-06-05 10:20 getssl.cfg
drwxr-xr-x   3 root root 4096 2022-07-12 04:30 証明書発行対象のドメイン名(初期化コマンドで指定したドメイン名)

実行ユーザーはウェブサーバーのドキュメントルートにフォルダを作成できる権限をもったユーザーでないといけません。権限がないとドメイン認証に必要な.well-knownフォルダが作成できず、エラーになります。動作についてはこちらで解説しています。

設定ファイルの編集

設定ファイルは2種類あります。

  1. ~/.getssl/getssl.cfg
  2. ~/.getssl/ドメイン名/getssl.cfg

1番はデフォルト値を指定する設定ファイル、2番はドメイン個別の設定ファイルです。主に2番の方を編集します。

設定するべき項目を以下に列挙します。

CA

CAの項目は接続先の環境を指定します。staging環境(テスト用の環境)と本番の環境が初期値として設定されています。まずはacme-staging-v02のステージング環境を指定しましょう。本番環境は利用制限があり、設定ファイルを微調整しながら何回も実行していると制限に引っかかってしまうかもしれません。staging環境は同様の制限はありますが本番環境よりはゆるやかです。

【例】
# The staging server is best for testing
CA="https://acme-staging-v02.api.letsencrypt.org"
# This server issues full certificates, however has rate limits
#CA="https://acme-v02.api.letsencrypt.org"
SANS

追加で指定したいドメイン名やサブドメインを指定します。複数ある場合はカンマ区切りで指定します。名前解決できないホストを指定するとエラーになるようです。

【例】
SANS="www.mackii.co.jp, www2.mackii.co.jp"
ACL

Acme Challenge Locationの略です。証明書を発行する対象のドメインをコントロールしているかどうかを認証するため、ウェブサーバーにHTTPリソースを公開する必要があります。ACLはそのリソースの場所を指定する設定になります(詳細はLetsEncryptの仕様を参照)


私の場合getsslを実行するサーバーとフロントのサーバーが異なっていましたのでsshの指定をしました。設定でsshを指定する場合、sshのログインはパスワードではなく秘密鍵でのログイン設定が必要です。

【例】
ACL=('ssh:root@172.16.11.124:/var/www/html/.well-known/acme-challenge')

リモートのサーバーではなく、ローカルのサーバーでacme-challengeを実行したい場合、以下のようにフルパス指定のみ設定します。ここで”/var/www/mackii.co.jp/web/“の個所にははウェブサーバーのDocumentRootを指定します。

【例】
ACL=('/var/www/mackii.co.jp/web/.well-known/acme-challenge')

SANSの設定で複数のドメイン、サブドメインを指定した場合、1番目に初期化コマンドで指定したドメインの設定、その後にSANSで設定したドメインの設定をリスト形式で複数指定します。リスト形式については設定ファイルのコメントみたいにすればOKです。

【例:設定ファイルのコメントより】
ACL=('/var/www/mitj.tv/web/.well-known/acme-challenge'
     'ssh:server5:/var/www/mitj.tv/web/.well-known/acme-challenge'
     'ssh:sshuserid@server5:/var/www/mitj.tv/web/.well-known/acme-challenge'
     'ftp:ftpuserid:ftppassword:mitj.tv:/web/.well-known/acme-challenge')
USE_SINGLE_ACL

ACLの指定が1つの場合はtrueを設定しましょう。

【例】
USE_SINGLE_ACL="true"
DOMAIN_CERT_LOCATION, DOMAIN_KEY_LOCATION

Let’sEcryptからもらった証明書、秘密鍵のファイルをどこに配置するかフルパスを指定します。

私の場合、もう一台のサーバーにも配置が必要なため、以下のように複数指定しています。もう一台のサーバーにはssh経由で配布しています。

【例】
DOMAIN_CERT_LOCATION="/etc/pki/getssl/mackii.co.jp.crt;ssh:root@172.16.11.124:/etc/pki/getssl/mackii.co.jp.crt"
DOMAIN_KEY_LOCATION="/etc/pki/getssl/mackii.co.jp.key;ssh:root@172.16.11.124:/etc/pki/getssl/mackii.co.jp.key"
RELOAD_CMD

新しい証明書、秘密鍵をサーバーに読み込ませるのにreloadが必要な場合、reloadコマンドを指定できます。

私の場合、いろいろ証明書を使いまわしているので盛りだくさん。複数指定の場合、以下のようにリスト形式で指定します。

【例】
RELOAD_CMD=('ssh:root@172.16.11.124:service httpd reload',
'ssh:root@172.16.11.124:service postfix reload',
'ssh:root@172.16.11.124:service dovecot reload',
'service httpd reload',
'service postfix reload',
'service dovecot reload')

staging環境でのテスト

設定ファイルの修正が終わったら、正しく編集できたかテストを実施しましょう。設定ファイルのCAの設定をstaging環境に向けます。(記載の通り進めていたらすでにstagin環境に向いているはず)

以下のようにドメイン名を引数にしてgetsslコマンドを実行します。

[root@mackii ~]# getssl 証明書発行対象のドメイン名

ドメイン検証で問題なければ証明書が作成され、設定ファイルで指定されたパスに配置、reloadが実施されます。

何か不備があれば設定ファイルを見直して再実施しましょう。前回の証明書が残っていたら有効期限がまだあります、のようなメッセージが出て実行してくれません。その場合はfオプションで上書きするか、rオプションで証明書をrevokeしてから再実施しましょう。

[root@mackii ~]# getssl -f 証明書発行対象のドメイン名

ステージング環境で取得した証明書は存在しないCA認証局を利用しているため、暗号化は可能ですがブラウザで警告がでます。利用しないようにしましょう。

実行

設定ファイルに問題がないことが確認出来たら、いよいよ本番環境で利用する証明書を取得します。

CAの設定を本番URLに向くように修正してコマンド実行してください。ステージング環境と同様、ドメイン検証が実施され、証明書の配置、reloadが行われます。

【例】
# The staging server is best for testing
# CA="https://acme-staging-v02.api.letsencrypt.org"
# This server issues full certificates, however has rate limits
CA="https://acme-v02.api.letsencrypt.org"

コマンド

[root@mackii ~]# getssl 証明書発行対象のドメイン名
もしくは
[root@mackii ~]# getssl -f 証明書発行対象のドメイン名

cron設定

本番環境での実行が確認できたら、次は定期的な実行設定をします。Let’sEncryptから発行される小名称の有効期限は90日間です。有効期限切れにならないように定期的な更新が必要です。

以下はREADMEに記載されていた例です。一日一回5時23分にコマンドを実行している例になります。

23  5 * * * /root/getssl -u -a -q

設定はcrontabコマンドで設定ファイルを開き、上記例を記載し保存します。

[root@mackii ~]# crontab -e ※タイプミス-rにならない注意。

以下コマンドで設定が確認できます。

[root@mackii ~]# crontab -l

確認

サーバー証明書の設定が完了したら、実際にブラウザ等でアクセスして確認しましょう。証明書の警告やエラーが出なければ完了です。お疲れ様でした。

(補足) v2.43からv2.49への変更点

当記事で解説しているv2.43から最新版v2.49の変更内容です(2024年7月時点)

v2.44(2021-09-26 ~ 2021-10-01)

  1. 鍵アルゴリズム変更時の鍵ファイル削除(2021-09-26)
    • 鍵アルゴリズムが変更された場合、古い鍵ファイルが削除されるようになりました。
  2. curlのエラー改善(2021-09-30)
    • curlがエラーコード60を返した場合のエラーメッセージが改善されました。
  3. -preferred-chain引数の修正(2021-10-01)
    • -preferred-chain引数に関する問題が修正されました。
  4. ドメインが指定されていない場合のヘルプ表示(2021-10-01)
    • ドメインが指定されていない場合、ヘルプメッセージが表示されるようになりました。

v2.45(2021-10-08 ~ 2022-01-06)

  1. BSDの問題を修正するためのawkを使用したリリースタグの抽出(2021-10-08)
    • BSD環境での問題を修正するため、awkを使用してリリースタグを抽出するようになりました。
  2. 壊れたアップグレードURLの修正(2021-10-11)
    • アップグレードURLが正しく機能するよう修正されました。
  3. fullchainのコピー先の修正(2021-10-22)
    • fullchainがDOMAIN_CHAIN_LOCATIONにコピーされるようになりました。
  4. Solarisの検出とgnuツールの使用(2021-11-10)
    • Solaris環境を検出し、gnuツールを使用するようになりました。
  5. acme-dnsサポートとCNAMEの問題修正(2021-11-12)
    • acme-dnsをサポートし、CNAMEに関する問題が修正されました。
  6. GoDaddy向けの機能強化(2021-12-14)
    • より多くのレベルのドメイン名をサポートし、GODADDY_BASEが不要になり、リソースレコードの実際の削除が可能になりました。
  7. –upgradeオプション使用時の使用方法表示を抑制(2021-12-22)
    • –upgradeオプションが使用された場合、使用方法メッセージが表示されないようになりました。
  8. digの警告表示時に+idnoutを使用しない(2021-12-23)
    • digが警告を表示した場合、+idnoutオプションを使用しないようになりました。
  9. –account-idオプションのサポート(2022-01-06)
    • 新しく–account-idオプションがサポートされました。

v2.46(2022-03-09 ~ 2022-05-18)

  1. ISPConfig APIのサポート(2022-03-09)
    • ISPConfig APIが新しくサポートされました。
  2. Windows ServerおよびIISのサポート(2022-05-03)
    • Windows ServerとIISがサポートされるようになりました。
  3. FTP_ARGSの追加(2022-05-18)
    • FTP_ARGSが追加されました。

v2.47(2022-11-01 ~ 2023-02-22)

  1. FTP_PORTの追加(2022-11-01)
    • FTP_PORTが追加されました。
  2. [SAN]セクションの解析のための改行作成(2023-02-04)
    • [SAN]セクションが正しく解析されるよう、改行が追加されました。
  3. debパッケージの依存関係からcronieを削除(2023-02-22)
    • debパッケージの依存関係からcronieが削除されました。

v2.48(2024-03-18)

  1. CNAMEが見つかった場合のTXTレコードの更新(2024-03-18)
    • CNAMEが見つかった場合、TXTレコードがリフレッシュされるようになりました。
タイトルとURLをコピーしました