LoginSignup
0
0

More than 3 years have passed since last update.

リダイレクトサービス構築 AWS ALBパターン、Let’s Encryptパターン(複数の証明書付きネイキッドドメインを1台のサーバで管理)

Last updated at Posted at 2019-12-02

AWS ALBパターン

  • 下記のようにLet’s Encryptを使用して1台で運用しているが、ALB使用ではマネジドサービスのメリットがあるので切り替え検討。
  • 説明や操作は参考サイトへ(お世話になっております)
  • デメリット
    • ドメインごとALB作成が必要 ・・・ 冗長化やLet’s Encryptの依存性とトレードオフか

ロードバランサー -> リストー -> ルールの表示/編集
2020-06-10 13.37.52 ap-northeast-1.console.aws.amazon.com b18979972105.png

参考


Let’s Encryptパターン

nakeddomain.png

運用をシンプルにしたい

ネイキッドドメインを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を参照できる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0