-
-
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 = [email protected] | |
| # 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 |
Thank for the Script, it work is good.
You should get rid of 3DES. https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ stopped recommending it
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?
Thanks for the script! This is quite awesome. I made a fork that will go through multiple config files and their domains, log errors, and even email with mutt if installed.