Libra + Letsencrypt para Play Framework e AWS CloudFront

Libra + Letsencrypt para Play Framework e AWS CloudFront

Fundo

Eu tenho um webapp antigo do Play Framework que atende ativos de dois CDNs ( siteassetse courseassets), que são implementados com AWS CloudFront.Libraé executado na mesma VM que o webapp e atua apenas como um endpoint SSL porque a versão antiga do Play Framework usada não suporta SSL. Pound se liga às portas 80 e 443. O webapp Play se liga à porta 9000.

Anteriormente, eu usava um certificado curinga SSL da Symantec para os ativos CDN e o webapp. Agora que faltam apenas alguns dias para os certificados SSL da Symantec deixarem de ser válidos, decidi usar o AWS Certificate Manager para provisionar certificados SSL de domínio único para os CDNs e usar o Letsencrypt para fornecer um certificado SSL de domínio único para o aplicativo web. Os certificados Letsencrypt duram apenas 90 dias, portanto precisam ser atualizados automaticamente.

Pound deseja certificados SSL no formato PEM, mas Letsencrypt não parece ter uma maneira conveniente de fornecer um formato PEM. Letsencrypt não possui nenhuma provisão especial para Play Framework da mesma forma que faz para Apache httpd, Tomcat ou outras estruturas bem conhecidas.

Não quero colocar o webapp offline para atualizar o certificado SSL usado pelo Pound.

Configuração atual da libra

A seguir está minha /etc/pound/pound.cfgversão atual para Libra 2.7f-0ubuntu1. Esta configuração tem alguns anos e provavelmente precisará ser atualizada, e Pound provavelmente também deverá ser atualizado.

# 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

Questões

  1. O cliente certbot ACME versão 0.17.0 foi instalado via: sudo apt install certbot

    eu vejo issocertificadobot versão 0.21.0está disponível. Devo usar esta versão mais recente em vez do padrão fornecido pelo Ubuntu 17.10?

  2. Existe uma versão razoável do Pound disponível em um PPA Debian? Anteriormente eu mesmo tinha que construir o Pound, mas preferiria usar uma versão pré-construída.https://launchpad.net/ubuntu/+source/poundtem a versão 2.7-1.3... esta é a melhor versão estável?
  3. Quais mudanças são necessárias na configuração do Pound em /etc/pound/pound.cfg? Claramente esta linha precisará ser atualizada: Cert "/var/work/training/cadenza/conf/ssl/scalacourses.com.pound.pem"

    Esta linha pode precisar ser atualizada quando Pound for atualizado: 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"

    Que outras linhas podem precisar ser adicionadas, excluídas ou modificadas? Eu sei que Pound não deveria ser executado como root, mas isso pode ser tratado separadamente.

  4. Precisa de um script para provisionar inicialmente o certificado SSL Letsencrypt para Pound. Parece que ocertificadobotO programa usado por Letsencrypt deseja vincular-se à porta 80, mas Pound vincula-se a essa porta e não quero desativar o webapp para atualizar o certificado SSL. Existe uma maneira de executá-lo na mesma VM que Pound ou devo executá-lo em outra VM e copiar o certificado gerado no formato PEM quando estiver pronto?

  5. Precisa de um script que possa ser invocado via cron a cada 45 dias para atualizar os certificados SSL.

Responder1

Configure um pequeno httpd (Nginx, Apache...) que escute no localhost (127.0.0.1:80) e torne o diretório [DOCUMENT_ROOT]/.well-known/acme-challenge/ gravável para o usuário que está executando este httpd. Do que na configuração libra criar

Serviço "letsencrypt"
    HeadRequire "Host: .*"
    URL "/.bem conhecido/acme-challenge/.*"
    Processo interno
        Endereço 127.0.0.1
        Porta 80
    Fim
Fim

antes de todas as outras regras. Agora você deve ser capaz de fazer algo como

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

Por favor, altere "/var/www/localhost" para Document_root do seu httpd local. Você só tem que fazer isso uma vez. E mais tarde você pode fazer algo como

# 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

E claro, não se esqueça de adicionar o arquivo pem na configuração do libra mais tarde ;-) Eu sei que o pós-hook chega tarde demais. No entanto, Letsencrypt emitirá novos certificados 10 dias antes de os antigos expirarem. Então, se você deixar fazer um cronjob todos os dias, isso não será problema algum.

Responder2

  1. A versão atual certbotfunciona bem, não há necessidade da mais recente.
  2. Ainda não sei sobre uma versão pré-construída do Pound de fontes recentes.
  3. Eu só tive que mudar a Certlinha, o que faz sentido porque (ainda) não atualizei o Pound.
  4. O script pode ser executado em qualquer VM porque não se vincula à porta 80 ou à porta 443 quando um desafio de DNS é usado.

A seguir está certbot53um script que escrevi para usarjed/certbot-route53para autenticação via desafio DNS. Este script depende de umRPque enviei para certbot-route53corrigir dois bugs.

#!/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. Atualmente estou executando novamente o mesmo script por meio de um cron job. Isso significa que não estou atualizando os certificados, mas sim substituindo-os. Não está claro qual pode ser o benefício de atualizar um certificado. Aqui está a cronentrada, que executa o script como meu ID de usuário a cada 2 meses; Eu digitei isso depois de digitar sudo crontab -e:

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

informação relacionada