こちらの記事ではLet’s EncryptでSSL証明書を取得しサイトを常時SSL化するまでの方法を解説していこうと思います。
今回作業するにあたっての環境と前提条件
前提条件
- ドメインを取得し、IPアドレスと紐づけている
- EC2でサーバーが構築されている
- apacheはインストール済み
- Route53を使用
環境
Amazon Linux 2
SSL証明書を取得する手順
では以下のステップで取得してみましょう。
①certbotをEC2インスタンスにインストール
Certbotは無料のオープンソースツールで、Let’s EncryptからSSL/TLS証明書を自動で取得、設定するパッケージです。
$ sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo yum install -y certbot
Let’s Encryptのワイルドカード証明書を取得する際には、DNS-01チャレンジというドメイン所有権の確認が必要となります。この確認は、DNSレコードを追加することで行います。
Certbotは、このDNSレコードの追加を自動化するためのDNSプラグインを提供しています。Route 53を使用している場合、Route 53用のDNSプラグインをインストールすることで、Certbotが自動的にDNSレコードを追加・削除し、ドメイン所有権の確認を行います。
そのプラグインもインストールします。
$ sudo yum install -y python2-certbot-dns-route53
②IAMユーザーの作成
Certbot が DNS チャレンジを完了するために添付する必要がある IAM ユーザーの最小のアクセス権については、certbot-dns-route-53(https://certbot-dns-route53.readthedocs.io/en/stable/)を参照
ユーザを作成した後はアクセスキーを作成して、アクセスキーとシークレットセスキーをメモしておいてください。(次の作業で使います。)
ユーザー作成する際にポリシーの作成でjsonを選択し、下記のjsonコードを貼り付けてください。
YOURHOSTEDZONEID はRoute53のホストゾーンIDを記載してください。
{
"Version": "2012-10-17",
"Id": "certbot-dns-route53 sample policy",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:GetChange"
],
"Resource": [
"*"
]
},
{
"Effect" : "Allow",
"Action" : [
"route53:ChangeResourceRecordSets"
],
"Resource" : [
"arn:aws:route53:::hostedzone/YOURHOSTEDZONEID"
]
}
]
}
③認証情報を設定
先ほど作ったIAMユーザのアクセスキーとシークレットアクセスキーを`/root/.aws/credentials`に設定します。
$ sudo mkdir /root/.aws
$ sudo nano /root/.aws/credentials
[default]
aws_access_key_id = IAMユーザーアクセスキー
aws_secret_access_key = IAMユーザーシークレットアクセスキー
④証明書を取得
以下を実行するといろいろ質問されます。
example.comは自分のドメインに置き換えてください。
$ sudo certbot certonly --dns-route53 -d example.com -d *.example.com
実行が終えると以下のような結果が結果が出力され、公開鍵と秘密鍵のpemファイルの発行された場所が記載されています。(IMPORTANT NOTES以下のところ)
2つのpemファイルの発行場所はメモしておいてください。(/etc/~のところ)
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Found credentials in shared credentials file: ~/.aws/credentials
Plugins selected: Authenticator dns-route53, Installer None
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): 自分のメールアドレス
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Requesting a certificate for example.com and *.example.com
Performing the following challenges:
dns-01 challenge for example.com
dns-01 challenge for example.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your certificate will expire on 2023-10-28. To obtain a new or
tweaked version of this certificate in the future, simply run
certbot again. To non-interactively renew *all* of your
certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF:
⑤証明書の自動更新の設定
以下のコマンドで毎日午前0時30分と午後12時30分にcertbotの更新のリクエストがされ、ssl証明書の有効期限が30日以内の時だけ更新されます。
$ echo "30 0,12 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew" | sudo tee -a /etc/crontab > /dev/null
WEBサーバー常時SSL化にする手順
WEBサーバー常時SSL化する設定をしていきましょう!
①生成されたSSL証明書をWEBサーバーに設定する
まずApache モジュール mod_ssl
をインストール
$ sudo yum install -y mod_ssl
ssl.confファイルが/etc/httpd/conf.d/ssl.conf
に生成されます。
ssl.confファイルはmod_ssl の設定ファイル。このファイルには、暗号化キーと証明書の場所、許可する TLS プロトコル、受け入れる暗号化アルゴリズムを Apache に指示するディレクティブが含まれています。
それでは先ほど生成されたpemファイルの場所をssl.confに設定しましょう。
$ sudo nano /etc/httpd/conf.d/ssl.conf
SSLCertificateFileとSSLCertificateKeyFileディレクティブを書き換えてください。先ほど証明書を発行した際にメモをしたパスを参考にしてください。
SSLCertificateFileディレクティブには/etc/letsencrypt/live/example.com/fullchain.pem`のパス。
SSLCertificateKeyFileには/etc/letsencrypt/live/example.com/privkey.pem`のパス。
SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem
②http接続された場合にhttps接続に強制リダイレクト
httpd.confもapcheの設定ファイルです。
$ sudo nano /etc/httpd/conf/httpd.conf
httpd.confの最後の行に以下を追加
この設定は、すべてのHTTPリクエストがHTTPSにリダイレクトされますが、Let’s Encryptの証明書更新プロセスで使用される特定のURLパス(/.well-known/acme-challenge/
)はリダイレクトから除外されません。
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
③EC2インスタンスでHTTPS(443ポート)を開放
EC2インスタンスに適用しているセキュリティグループのインバウンドルールを編集しましょう。
④Apacheの設定を再読み込み
最後に、Apacheの設定を再読み込みして、新しい証明書を使用するようにします。これは次のコマンドで行うことができます。
$ sudo systemctl restart httpd.service
SSL証明書の更新テスト
念のためSSL証明書の更新ができるかテストしましょう。
$ sudo certbot renew --dry-run
上記コマンドを実行するとCertbotは更新を試みますが、–dry-runオプションを使用すると実際には何も変更されません。これにより、更新が成功するかどうかを確認できます。
成功すると以下のように結果が出力されます。
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Found credentials in shared credentials file: ~/.aws/credentials
Plugins selected: Authenticator dns-route53, Installer None
Account registered.
Simulating renewal of an existing certificate for example.com and *.example.com
Performing the following challenges:
dns-01 challenge for example.com
dns-01 challenge for example.com
Waiting for verification...
Cleaning up challenges
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/example.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
最後に
今回はAWSで常時SSL化する際に通常はCertificate ManagerとELBサービスを使ってSSL化するのが楽なのですが、できるだけ出費を抑えるために無料でできる方法を調べました。情報が多く色々な方法の記事があり、その中にはエラーが起きてしまうこともあったので、とても時間がかかりました。やはり公式のドキュメントを読むのが一番だと改めて思いました。
この記事が誰かの参考になれば幸いです。
次回はAWSで構築したサーバーのセキュリティの改善をしていこうと思います。
参考にしたドキュメント