Play Framework と AWS CloudFront 用の Pound + Letsencrypt

Play Framework と AWS CloudFront 用の Pound + Letsencrypt

背景

AWS CloudFront で実装された2 つの CDN (siteassetsおよび)からアセットを提供する古い Play Framework Web アプリがあります。courseassetsポンドWeb アプリケーションと同じ VM 上で実行され、使用されている古いバージョンの Play Framework は SSL を処理しないため、SSL エンドポイントとしてのみ機能します。Pound はポート 80 と 443 にバインドします。Play Web アプリケーションはポート 9000 にバインドします。

以前は、CDN アセットと Web アプリケーションに Symantec SSL ワイルドカード証明書を使用していました。Symantec SSL 証明書の有効期限があと数日しか残っていないため、AWS Certificate Manager を使用して CDN 用の単一ドメイン SSL 証明書をプロビジョニングし、Letsencrypt を使用して Web アプリケーション用の単一ドメイン SSL 証明書を提供することにしました。Letsencrypt 証明書の有効期限は 90 日間のみであるため、自動的に更新する必要があります。

Pound は PEM 形式の SSL 証明書を必要としますが、Letsencrypt には PEM 形式を提供する便利な方法がないようです。Letsencrypt には、Apache httpd、Tomcat、その他のよく知られているフレームワークの場合のような Play Framework 用の特別な規定はありません。

Pound が使用する SSL 証明書を更新するために、Web アプリケーションをオフラインにしたくありません。

現在のポンド構成

以下は、私の現在/etc/pound/pound.cfgの Pound バージョンです2.7f-0ubuntu1。この設定は数年前のものであり、おそらく更新する必要があり、Pound もおそらく更新する必要があります。

# Global options

User    "root"
Group   "root"

# Logging: (goes to syslog by default)
#  0  no logging
#  1  normal
#  2  extended
#  3  Apache-style (common log format)
#  4 (same as 3 but without the virtual host information)
#  5 (same as 4 but with information about the Service and BackEnd used)
LogLevel 5

# Check backend every X secs:
Alive    30

# Use hardware-accelleration card supported by openssl(1):
#SSLEngine  "<hw>"

# poundctl control socket
Control "/var/run/poundctl.socket"

# Redirect all http requests on port 80 to https on port 443
# The Play Framework webapp never sees these redirected requests because Pound handles them
ListenHTTP
  Address 0.0.0.0
  Port 80
  Err500 "/usr/local/etc/pound_error_500"
  Err503 "/usr/local/etc/pound_error_500"
  Service
    Redirect 301 "https://www.scalacourses.com"
  End
End

# Redirect all requests on port 443 to the Play Framework webapp on port 9443
ListenHTTPS
  Address 0.0.0.0
  Port 443
  Err500 "/usr/local/etc/pound_error_500"
  Err503 "/usr/local/etc/pound_error_500"
  Cert "/var/work/training/cadenza/conf/ssl/scalacourses.com.pound.pem"
  Disable SSLv3
  Ciphers "EECDH+ECDSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!eNULL:!LOW:!aNULL:!MD5:!DSS"
  SSLAllowClientRenegotiation     0
  SSLHonorCipherOrder 1
  HeadRemove "X-Forwarded-Proto"
  HeadRemove "x-forwarded-proto"
  AddHeader "x-forwarded-proto: https"
  Service
    BackEnd
      #HTTPS
      Address 127.0.0.1
      Port 9000
    End
  End
End

質問

  1. certbot ACME クライアント バージョン 0.17.0 は、次の方法でインストールされました: sudo apt install certbot

    私はそれを見るcertbot バージョン 0.21.0が利用可能です。Ubuntu 17.10 で提供されているデフォルトの代わりに、この新しいバージョンを使用する必要がありますか?

  2. Debian PPA で入手可能な Pound の適切なバージョンはありますか? 以前は自分で Pound をビルドする必要がありましたが、ビルド済みのバージョンを使用したいと考えています。https://launchpad.net/ubuntu/+source/poundバージョン 2.7-1.3 があります...これは最も安定したバージョンですか?
  3. の Pound 構成にはどのような変更が必要ですか/etc/pound/pound.cfg? 明らかに、次の行を更新する必要があります。 Cert "/var/work/training/cadenza/conf/ssl/scalacourses.com.pound.pem"

    Pound が更新されると、この行を更新する必要がある可能性があります。 Ciphers "EECDH+ECDSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!eNULL:!LOW:!aNULL:!MD5:!DSS"

    他にどのような行を追加、削除、または変更する必要があるでしょうか? Pound は として実行すべきではないことはわかっていますrootが、それは個別に処理できます。

  4. Pound用のLetsencrypt SSL証明書を最初にプロビジョニングするためのスクリプトが必要です。証明書ボットLetsencrypt が使用するプログラムはポート 80 にバインドしようとしますが、Pound はこのポートにバインドします。SSL 証明書をアップグレードするために Web アプリケーションを停止したくありません。Pound と同じ VM で実行する方法はありますか。それとも、別の VM で実行し、準備ができたら PEM 形式で生成された証明書をコピーする必要がありますか。

  5. SSL 証明書を更新するために、45 日ごとに cron 経由で呼び出すことができるスクリプトが必要です。

答え1

ローカルホスト(127.0.0.1:80)でリッスンする小さなhttpd(Nginx、Apacheなど)を設定し、このhttpdを実行しているユーザーがディレクトリ[DOCUMENT_ROOT]/.well-known/acme-challenge/に書き込みできるようにします。次に、pound configで以下を作成します。

サービス「letsencrypt」
    HeadRequire "ホスト: .*"
    URL「/.w​​ell-known/acme-challenge/.*」
    バックエンド
        アドレス 127.0.0.1
        ポート80
    終わり
終わり

他のすべてのルールに優先します。これで、次のようなことができるはずです。

certbot-auto certonly --email [email protected] -d www.example.com -d example.com --verbose --agree-tos --webroot --webroot-path /var/www/localhost/htdocs/

「/var/www/localhost」をローカルの httpd の Document_root に変更してください。これは一度だけ行う必要があります。その後は次のようにします。

# add --dry-run to test it certbot-auto renew --post-hook "/etc/init.d/pound restart" for i in ls /etc/letsencrypt/live/; do cp /etc/letsencrypt/live/$i/privkey.pem /opt/pound_certs/$i.pem ; cat /etc/letsencrypt/live/$i/fullchain.pem >> /opt/pound_certs/$i.pem ; done

もちろん、後で pound 構成に pem ファイルを追加することを忘れないでください ;-) post-hook が遅すぎることはわかっています。ただし、Letsencrypt は古い証明書が期限切れになる 10 日前に新しい証明書を発行します。したがって、これを毎日 cronjob で実行するようにすれば、まったく問題ありません。

答え2

  1. 現在のバージョンはcertbot問題なく動作します。最新バージョンは必要ありません。
  2. 最近のソースからの Pound のプレビルド バージョンについてはまだわかりません。
  3. ラインを変更するだけで済みましたCert。これは、まだ Pound をアップグレードしていないため当然のことです。
  4. DNS チャレンジが使用される場合、スクリプトはポート 80 またはポート 443 にバインドされないため、どの VM でも実行できます。

certbot53以下は私が書いたスクリプトです。jed/certbot-route53DNSチャレンジによる認証に使用します。このスクリプトは広報私が提出したバージョンでは、certbot-route532 つのバグが修正されています。

#!/bin/bash

#STAGING=--staging
CERT_DIR=/etc/pound/certbot
DOMAIN=scalacourses.com
MAIL_ADDR='[email protected]'
SCRIPT_NAME=certbot-route53.sh

if [ ! -d "$CERT_DIR/letsencrypt" ]; then sudo mkdir -p $CERT_DIR/letsencrypt; fi
sudo chmod 777 "$CERT_DIR/letsencrypt"

cd $CERT_DIR

if [ ! -f "$CERT_DIR/$SCRIPT_NAME" ]; then
  sudo curl -sL https://git.io/vylLx -o $SCRIPT_NAME
  sudo chmod a+x certbot-route53.sh
fi

./$SCRIPT_NAME \
  --agree-tos \
  --manual-public-ip-logging-ok \
  --domains $DOMAIN,www.$DOMAIN \
  --renew-by-default \
  --email $MAIL_ADDR $STAGING

PRIV_KEY="$CERT_DIR/letsencrypt/live/$DOMAIN/privkey.pem"
FULL_CHAIN="$CERT_DIR/letsencrypt/live/$DOMAIN/fullchain.pem"
COMBINED="$CERT_DIR/combined-for-pound.pem"
cat "$PRIV_KEY" "$FULL_CHAIN" | sudo tee "$COMBINED" > /dev/null
  1. 現在、同じスクリプトを cron ジョブで再実行しています。つまり、証明書をアップグレードするのではなく、置き換えているのです。証明書をアップグレードするメリットが何なのかは不明です。以下はcron、2 か月ごとに自分のユーザー ID としてスクリプトを実行するエントリです。次のように入力した後、これを入力しましたsudo crontab -e

    0 0 1 */2 * su mslinn /usr/local/bin/certbot53
    

関連情報