-
-
Save thisismitch/7c91e9b2b63f837a0c4b to your computer and use it in GitHub Desktop.
global | |
log /dev/log local0 | |
log /dev/log local1 notice | |
chroot /var/lib/haproxy | |
stats socket /run/haproxy/admin.sock mode 660 level admin | |
stats timeout 30s | |
user haproxy | |
group haproxy | |
daemon | |
maxconn 2048 | |
tune.ssl.default-dh-param 2048 | |
# Default SSL material locations | |
ca-base /etc/ssl/certs | |
crt-base /etc/ssl/private | |
# Default ciphers to use on SSL-enabled listening sockets. | |
# For more information, see ciphers(1SSL). This list is from: | |
# https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ | |
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS | |
ssl-default-bind-options no-sslv3 | |
defaults | |
log global | |
mode http | |
option httplog | |
option dontlognull | |
timeout connect 5000 | |
timeout client 50000 | |
timeout server 50000 | |
errorfile 400 /etc/haproxy/errors/400.http | |
errorfile 403 /etc/haproxy/errors/403.http | |
errorfile 408 /etc/haproxy/errors/408.http | |
errorfile 500 /etc/haproxy/errors/500.http | |
errorfile 502 /etc/haproxy/errors/502.http | |
errorfile 503 /etc/haproxy/errors/503.http | |
errorfile 504 /etc/haproxy/errors/504.http | |
option forwardfor | |
option http-server-close | |
frontend www-http | |
bind haproxy_www_public_IP:80 | |
reqadd X-Forwarded-Proto:\ http | |
default_backend www-backend | |
frontend www-https | |
bind haproxy_www_public_IP:443 ssl crt /etc/haproxy/certs/example.com.pem | |
reqadd X-Forwarded-Proto:\ https | |
acl letsencrypt-acl path_beg /.well-known/acme-challenge/ | |
use_backend letsencrypt-backend if letsencrypt-acl | |
default_backend www-backend | |
backend www-backend | |
redirect scheme https if !{ ssl_fc } | |
server www-1 www_1_private_IP:80 check | |
server www-2 www_2_private_IP:80 check | |
backend letsencrypt-backend | |
server letsencrypt 127.0.0.1:54321 |
#!/bin/bash | |
web_service='haproxy' | |
config_file='/usr/local/etc/le-renew-haproxy.ini' | |
domain=`grep "^\s*domains" $config_file | sed "s/^\s*domains\s*=\s*//" | sed 's/(\s*)\|,.*$//'` | |
http_01_port='54321' | |
combined_file="/etc/haproxy/certs/${domain}.pem" | |
le_path='/opt/letsencrypt' | |
exp_limit=30; | |
if [ ! -f $config_file ]; then | |
echo "[ERROR] config file does not exist: $config_file" | |
exit 1; | |
fi | |
cert_file="/etc/letsencrypt/live/$domain/fullchain.pem" | |
key_file="/etc/letsencrypt/live/$domain/privkey.pem" | |
if [ ! -f $cert_file ]; then | |
echo "[ERROR] certificate file not found for domain $domain." | |
fi | |
exp=$(date -d "`openssl x509 -in $cert_file -text -noout|grep "Not After"|cut -c 25-`" +%s) | |
datenow=$(date -d "now" +%s) | |
days_exp=$(echo \( $exp - $datenow \) / 86400 |bc) | |
echo "Checking expiration date for $domain..." | |
if [ "$days_exp" -gt "$exp_limit" ] ; then | |
echo "The certificate is up to date, no need for renewal ($days_exp days left)." | |
exit 0; | |
else | |
echo "The certificate for $domain is about to expire soon. Starting Let's Encrypt (HAProxy:$http_01_port) renewal script..." | |
$le_path/letsencrypt-auto certonly --agree-tos --renew-by-default --config $config_file --http-01-port $http_01_port | |
echo "Creating $combined_file with latest certs..." | |
sudo bash -c "cat /etc/letsencrypt/live/$domain/fullchain.pem /etc/letsencrypt/live/$domain/privkey.pem > $combined_file" | |
echo "Reloading $web_service" | |
/usr/sbin/service $web_service reload | |
echo "Renewal process finished for domain $domain" | |
exit 0; | |
fi |
# This is an example of the kind of things you can do in a configuration file. | |
# All flags used by the client can be configured here. Run Let's Encrypt with | |
# "--help" to learn more about the available options. | |
# Use a 4096 bit RSA key instead of 2048 | |
rsa-key-size = 4096 | |
# Uncomment and update to register with the specified e-mail address | |
email = you@example.com | |
# Uncomment and update to generate certificates for the specified | |
# domains. | |
domains = example.com, www.example.com | |
# Uncomment to use a text interface instead of ncurses | |
# text = True | |
# Uncomment to use the standalone authenticator on port 443 | |
# authenticator = standalone | |
standalone-supported-challenges = http-01 | |
# Uncomment to use the webroot authenticator. Replace webroot-path with the | |
# path to the public_html / webroot folder being served by your web server. | |
# authenticator = webroot | |
# webroot-path = /usr/share/nginx/html |
Does this gist still work with the specified port?
certbot/certbot#2697 seems to suggest that when specifying a port, a web server will be created; however, the authentication request will still be sent through port 80?
@WilliamHua I'm not using this script - but from the looks of it:
the acl rule letsencrypt-acl will intercept any request made on the https port that is to the challenge folder (.well-known/acme-challenge) and redirect it to the correct (standalone) port. So letsencrypt should respond to requests sent to port 443 (doesn't look like it's configured to forward them on port 80 though).
@thisismitch thanks for this gist!
Can you please briefly explain, what the line
server letsencrypt 127.0.0.1:54321
in the haproxy.cfg
does exactly? Is the "letsencrypt" just setting a symbolic name? And how do I make sure there is actually something listening on port 54321?
how to use this for multiple domain with multiple lets encrypt?
You should get rid of 3DES. https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ stopped recommending it