用于 Play 框架和 AWS CloudFront 的 Pound + Letsencrypt

用于 Play 框架和 AWS CloudFront 的 Pound + Letsencrypt

背景

我有一个旧的 Play Framework Web 应用程序,它为两个 CDN(siteassetscourseassets)提供资产,这些 CDN 是使用 AWS CloudFront 实现的。与 Web 应用在同一 VM 上运行,仅充当 SSL 端点,因为使用的旧版 Play Framework 不处理 SSL。Pound 绑定到端口 80 和 443。Play Web 应用绑定到端口 9000。

之前,我为 CDN 资产和 Web 应用程序使用了 Symantec SSL 通配符证书。现在 Symantec SSL 证书的有效期只剩几天了,之后它们将不再有效,因此我决定使用 AWS 证书管理器为 CDN 配置单域 SSL 证书,并使用 Letsencrypt 为 Web 应用程序提供单域 SSL 证书。Letsencrypt 证书的有效期仅为 90 天,因此需要自动刷新。

Pound 需要 PEM 格式的 SSL 证书,但 Letsencrypt 似乎没有提供 PEM 格式的便捷方式。Letsencrypt 对 Play Framework 没有任何特殊规定,就像对 Apache httpd、Tomcat 或其他知名框架一样。

为了更新 Pound 使用的 SSL 证书,我不想让 webapp 脱机。

当前磅配置

以下是我目前/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 证书。似乎certbotLetsencrypt 使用的程序想要绑定到端口 80,但 Pound 绑定到此端口,我不想为了升级 SSL 证书而关闭 Web 应用程序。有没有办法在与 Pound 相同的 VM 上运行它,或者我应该在另一台 VM 上运行它并在准备好时复制生成的 PEM 格式的证书?

  5. 需要一个可以每 45 天通过 cron 调用一次的脚本来刷新 SSL 证书。

答案1

设置一个小型 httpd(Nginx、Apache...),监听本地主机(127.0.0.1:80),并使目录 [DOCUMENT_ROOT]/.well-known/acme-challenge/ 对于运行此 httpd 的用户可写。然后在 pound 配置中创建

服务“letsencrypt”
    HeadRequire“主机:。*”
    URL“/.well-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 文件 ;-) 我知道后挂钩来得太晚了。但是 Letsencrypt 会在旧证书过期前 10 天颁发新证书。所以如果你让它每天执行 cronjob,这完全没有问题。

答案2

  1. 当前版本certbot运行良好,不需要最新版本。
  2. 仍然不知道最近的来源是否有 Pound 的预构建版本。
  3. 我只需要改变路线Cert,这是有道理的,因为我还没有升级 Pound。
  4. 该脚本可以在任何虚拟机上运行,​​因为当使用 DNS 质询时它不会绑定到端口 80 或端口 443。

以下是certbot53我编写的脚本jed/certbot-route53通过 DNS 质询进行身份验证。此脚本依赖于公共关系我提交的certbot-route53版本修复了两个错误。

#!/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
    

相关内容