AWS ALBパターン
- 下記のようにLet’s Encryptを使用して1台で運用しているが、ALB使用ではマネジドサービスのメリットがあるので切り替え検討。
- 説明や操作は参考サイトへ(お世話になっております)
- デメリット
- ドメインごとALB作成が必要 ・・・ 冗長化やLet’s Encryptの依存性とトレードオフか
-
IF
-
ホストヘッダーを選択: リダイレクト対象のドメインを指定
-
THEN
-
リダイレクト先
-
ホスト欄にリダイレクト対象のドメインを指定
-
できること例
-
http://domain.com -> https://domain.com or https://www.domain.com
-
https://domain.com -> https://domain.com or https://www.domain.com
参考
Let’s Encryptパターン
運用をシンプルにしたい
ネイキッドドメインをwwwのサブドメインにリダイレクトしたいが、証明書設定がないと止まる。
https://domain.com -> ブラウザが怒る(証明書警告) -> https://www.domain.com
wwwのサブドメインは証明書費用かけず運用中。
- AWSのRoute53(CNAME) + Elastic Beanstalk + CloudFront + Certificate Manager
SSL必須の時代になり、証明書付きのネイキッドドメインのケースが増えてきた。
ネイキッドドメインのDNSレコードはIPしか指定できないため、とりあえず下記のようなセットで対応していた。
- S3リダイレクト用バケット + CloudFront + Certificate Manager
EC2の一台に
サイトごと、二重の設定作業やコストが増えるので構成を変えてみた。
- リダイレクト用EC2(IP指定のため)
- サイトごとLet’s Encrypt設定(このくらいは我慢)
証明書はLet’s Encryptのwebrootオプションにする理由
- ドメインオーナーではない(DNSレコード登録できない)
- サーバ管理者である
/etc/httpd/conf.d/domain.com.conf
<VirtualHost *:80>
ServerName domain.com
DocumentRoot /var/www/html/domain.com
</VirtualHost>
<VirtualHost *:443>
ServerName domain.com:443
DocumentRoot /var/www/html/domain.com
SSLEngine on
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile /etc/letsencrypt/live/domain.com/cert.pem
SSLCertificateKeyFile //etc/letsencrypt/live/domain.com/privkey.pem
SSLCACertificateFile /etc/letsencrypt/live/domain.com/chain.pem
</VirtualHost>
/var/www/html/domain.com/index.html
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
しばらくお待ちください。
</body>
</html>
/var/www/html/domain.com/.htaccess
RewriteCond %{REQUEST_URI} !(^/.well-known/) がないとwww.にリダイレクトされてしまうので発行に失敗する
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteCond %{HTTP_HOST} !^www.
RewriteCond %{REQUEST_URI} !(^/\.well-known/)
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{SERVER_PORT} 443
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
やっと証明書発行
- テストドメイン: domain.com
certbot-auto certonly --webroot -w /var/www/html/domain.com -d domain.com -m infra@xxx.com --agree-tos
crontab -l
0 3 * * * /usr/bin/certbot-auto renew && /sbin/service httpd reload
メモ
- テンプレートとする元ファイルから簡単追加
/var/www/html/default/.htaccess
/var/www/html/default/index.html
- cmd
mkdir /var/www/html/{domain}
cp -aT /var/www/html/default /var/www/html/{domain}
監視
cronにより自動更新だが、たまに失敗するので監視は回しておく
サーバー証明書有効期限監視
参考
追記 証明書定期更新をhookで使用時
cron
10 3 * * * /etc/letsencrypt/renewal/aaa.bbb.info.sh
毎日更新をトライする
/etc/letsencrypt/renewal/aaa.bbb.info.sh
# !/bin/sh
certbot certonly \
-d aaa.bbb.info \
--email infra@aaa.bbb.info \
--agree-tos \
--preferred-challenges dns \
--keep-until-expiring \
--text \
--configurator certbot-external-auth:out \
--certbot-external-auth:out-public-ip-logging-ok \
--certbot-external-auth:out-handler /etc/letsencrypt/renewal-hooks/pre/aaa.bbb.info.sh
/sbin/service httpd restart
- 期限内になると更新
- --preferred-challenges dns にしたのでCNAME更新が必要
- hookでRoute53レコードを更新
/etc/letsencrypt/renewal-hooks/pre/aaa.bbb.info.sh
# !/bin/sh
set -e
cmd="$1"
shift
ret=`aws sts assume-role --role-arn arn:aws:iam::xxxx427341:role/route53-register --role-session-name aws3-ec2`
export AWS_ACCESS_KEY_ID=`echo $ret | jq -r .Credentials.AccessKeyId`
export AWS_SECRET_ACCESS_KEY=`echo $ret | jq -r .Credentials.SecretAccessKey`
export AWS_SESSION_TOKEN=`echo $ret | jq -r .Credentials.SessionToken`
case "$cmd" in
perform)
HOSTED_ZONE_ID="/hostedzone/xxxx5NZ9H"
FILENAME=`date "+%Y%m%d%H%M%S"`.json
DIR=/var/log/letsencrypt/
# 環境変数チェック
if [ -z "$domain" ] || [ -z "$validation" ]; then
echo "Undefined environment variable"
exit 1
fi
# 設定用jsonファイルを書き出し
cat <<EOT > $DIR$FILENAME
{
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "_acme-challenge.$domain",
"Type": "TXT",
"TTL": 60,
"ResourceRecords": [
{
"Value": "\"$validation\""
}
]
}
}
]
}
EOT
# jsonファイルをアップロードしてTXTレコードを追加
aws route53 change-resource-record-sets --hosted-zone-id "$HOSTED_ZONE_ID" --change-batch file://$DIR$FILENAME
# DNS反映待ち
sleep 60
;;
*)
;;
esac
- STS(aws sts assume-role)で他アカウントのRoute53を参照できる