diff --git a/files/haproxy/acmetool_sync.sh b/files/haproxy/acmetool_sync.sh deleted file mode 100644 index 0710b43..0000000 --- a/files/haproxy/acmetool_sync.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -acmetool="/usr/bin/acmetool" -wanted_cert_path="/var/lib/acme/desired" -synced_apache_config="/etc/haproxy/synced_apache_config" -synced_iis_config="/etc/haproxy/synced_iis_config" - -if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then - echo "usage: $0 rsync_path_to_apache_config rsync_path_to_iis_config preview_domain" - echo "example:" - echo "$0 \"root@192.168.33.21:/storage/configuration/maps\" \"root@192.168.33.21:/storage/configuration/iis\" preview.dev.atomia.com" - exit 1 -fi - -# Sync all files from /storage/content/ssl to local dir -rsync -a -e "ssh -o StrictHostKeyChecking=no" --delete "$1"/ "$synced_apache_config" -rsync -a -e "ssh -o StrictHostKeyChecking=no" --delete "$2"/ "$synced_iis_config" - -if [ -f "$synced_apache_config/vhost.map" ]; then - cat "$synced_apache_config"/vhost.map | awk '{ print $1 }' | grep -vE "$3"'$' | grep -v '^www\.' | grep -E '^[a-zA-Z0-9.-]+$' \ - | sort -u | awk '{ print $0 " www." $0 }' | while read cert; do - - if [ ! -f `echo "$wanted_cert_path/$cert"-* | cut -d " " -f 1` ]; then - $acmetool --batch want $cert > /dev/null 2>&1 - fi - done -fi - -if [ -f "$synced_iis_config/applicationHost.config" ]; then - grep -F binding "$synced_iis_config/applicationHost.config" | grep -F ":80:" | awk -F ':80:' '{ print $2 }' | cut -d '"' -f 1 \ - | grep -vE "$3"'$' | grep -v '^www\.' | grep -E '^[a-zA-Z0-9.-]+$' | sort -u | awk '{ print $0 " www." $0 }' | while read cert; do - - if [ ! -f `echo "$wanted_cert_path/$cert"-* | cut -d " " -f 1` ]; then - $acmetool --batch want $cert > /dev/null 2>&1 - fi - done -fi diff --git a/files/haproxy/update_acmetool_challenge_script.sh b/files/haproxy/update_acmetool_challenge_script.sh index 7e86f72..4e55e40 100644 --- a/files/haproxy/update_acmetool_challenge_script.sh +++ b/files/haproxy/update_acmetool_challenge_script.sh @@ -1,6 +1,75 @@ #!/bin/sh -thumbprint=`/usr/bin/acmetool account-thumbprint | awk '{ print $1 }'` +# This is a new implementation of the update acmetool challange script. +# We no longer use the actual acme-tool, as it is not good for may domains. +# We switched to certbot, but it does not support getting challange directly so we need to calculate it. + +# We first need to chec if there is already an account, and if not then we create a new one. +if [ ! -f "/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/*/private_key.json" ] +then + logger "Could not find Let's encrypt account info, creating new account with certbot..." + certbot register --agree-tos -m noreply@atomia.com +fi + +# Certbot saves the private_key info in the .json file, so we need a few values from the whole json file, not the whole file. +# We parse the n and e keys from the file which are used in calculation of the jwk (account thumbprint). +n="`cat /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/*/private_key.json | python -c "import sys, json; print json.load(sys.stdin)['n']"`" +e="`cat /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/*/private_key.json | python -c "import sys, json; print json.load(sys.stdin)['e']"`" + +jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' + +# These are the functions that are pulled from. +# https://github.com/Neilpang/acme.sh/blob/master/acme.sh +# That's a Bash implementation of acme utility for Lets encrypt. +_url_replace() { + tr '/+' '_-' | tr -d '= ' +} + +#Usage: multiline +_base64() { + [ "" ] #urgly + if [ "$1" ]; then + logger "base64 multiline:'$1'" + ${ACME_OPENSSL_BIN:-openssl} base64 -e + else + logger "base64 single line." + ${ACME_OPENSSL_BIN:-openssl} base64 -e | tr -d '\r\n' + fi +} + +#Usage: hashalg [outputhex] +#Output Base64-encoded digest +_digest() { + alg="$1" + if [ -z "$alg" ]; then + echo "Usage: _digest hashalg" + return 1 + fi + + outputhex="$2" + + if [ "$alg" = "sha256" ] || [ "$alg" = "sha1" ] || [ "$alg" = "md5" ]; then + if [ "$outputhex" ]; then + ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -hex | cut -d = -f 2 | tr -d ' ' + else + ${ACME_OPENSSL_BIN:-openssl} dgst -"$alg" -binary | _base64 + fi + else + logger "$alg is not supported yet" + return 1 + fi + +} + +__calc_account_thumbprint() { + printf "%s" "$jwk" | tr -d ' ' | _digest "sha256" | _url_replace +} + +# Now we are ready to calculate the thumbprint so we can call the function. +# The thumbprint var will now contain the calculated thumbprint in the format that Let's encrypt needs for verification. +thumbprint=$(__calc_account_thumbprint) + +# Finally we create the lua file that is loaded by haproxy in order for the challange to pass. cat > /usr/lib/stateless_acme_challenge.lua < present, } @@ -120,6 +120,9 @@ apt::ppa { 'ppa:vbernat/haproxy-1.5': require => Package['python-software-properties'] } + apt::ppa { 'ppa:certbot/certbot': + require => Package['software-properties-common'] + } if $ssh_cluster_ip != '' { class { 'ssh::server': @@ -130,6 +133,13 @@ } } + # Acme tool has been replace with the better certbot. + + package { 'certbot': + ensure => present, + require => [ Apt::Ppa['ppa:certbot/certbot'] ] + } + package { 'haproxy': ensure => present, require => [ Apt::Ppa['ppa:vbernat/haproxy-1.5'] ] @@ -204,8 +214,11 @@ command => '/etc/init.d/keepalived restart', } } + + # We need to have the following directories in order + # for our support to work as expected - $acme_conf_dirs = [ '/var/lib/acme', '/var/lib/acme/conf', '/var/lib/acme/haproxy' ] + $acme_conf_dirs = [ '/etc/letsencrypt', '/etc/letsencrypt/conf', '/etc/letsencrypt/live', '/etc/letsencrypt/renewal', '/etc/letsencrypt/archive', '/etc/haproxy/le_certs', '/etc/haproxy/synced_apache_config'] file { $acme_conf_dirs: ensure => directory, owner => root, @@ -213,21 +226,20 @@ mode => '0755', } + # This file is needed by haproxy configuration to actually be + # able to verify the ownership of the domain by LE. + file { '/usr/lib/stateless_acme_challenge.lua': ensure => present, owner => 'root', group => 'root', mode => '0644', + require => [ Package['certbot'], File['/etc/letsencrypt/conf'], File['/usr/bin/update_acmetool_challenge_script.sh'] ], + notify => Exec['acmetool-quickstart'] } - file { '/var/lib/acme/conf/responses': - owner => 'root', - group => 'root', - mode => '0644', - content => template('atomia/haproxy/acmetool-quickstart-responses.erb'), - require => [ Package['acmetool'], File['/var/lib/acme/conf'], File['/usr/bin/update_acmetool_challenge_script.sh'] ], - notify => Exec['acmetool-quickstart'], - } + # This file is used to intially create a lua script that is used + # by haproxy to verify the LE challenge. This script is run only once. file { '/usr/bin/update_acmetool_challenge_script.sh': owner => 'root', @@ -236,16 +248,33 @@ source => 'puppet:///modules/atomia/haproxy/update_acmetool_challenge_script.sh', } + # This file has been changed to erb because we now include the IP adress of + # the apache cluster so we can validate if the domain is pointing to our IP + # and then we try to issue a certificate for that domain. + file { '/usr/bin/acmetool_sync.sh': owner => 'root', group => 'root', mode => '0700', - source => 'puppet:///modules/atomia/haproxy/acmetool_sync.sh', + content => template('atomia/haproxy/acmetool_sync.sh.erb'), } + # The haproxy manifest did not have a renewal at all for lets encrypt. + # So this is added in order to support the renewal of certs. + + file { '/usr/bin/acmetool_renew.sh': + owner => 'root', + group => 'root', + mode => '0700', + content => template('atomia/haproxy/acmetool_renew.sh.erb'), + } + + # This runs the update script that creates the LE account and + # generates the thumbprint which is saved to the lua file, loaded by haproxy. + exec { 'acmetool-quickstart': refreshonly => true, - command => '/usr/bin/acmetool quickstart --batch && /usr/bin/update_acmetool_challenge_script.sh', + command => '/usr/bin/update_acmetool_challenge_script.sh', notify => File['/etc/haproxy/haproxy.cfg'], } @@ -366,6 +395,18 @@ content => $sync_ssl_redirects_cron, require => [ File['/root/.ssh/id_rsa'], File['/etc/haproxy/sync_ssl_redirects.sh'] ] } + + # We need to renew the certificates at some point so we will run the + # script at midnight and start the renewal every day. + + file { '/etc/cron.d/atomia-sync-renew-acmetool': + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + content => '0 0 * * * root flock -n /var/lock/acmerenew.lock /usr/bin/acmetool_renew.sh', + require => [ File['/root/.ssh/id_rsa'], File['/usr/bin/acmetool_renew.sh'] ] + } } @@ -382,7 +423,7 @@ } else { file { '/etc/haproxy/atomia_certificates/default.pem': ensure => file, - source => 'puppet:///modules/atomiacerts/certificates/wildcard_with_key.pem', + source => 'puppet:///atomiacerts/wildcard_with_key.pem', owner => 'root', group => 'root', mode => '0755', @@ -396,7 +437,7 @@ Package['haproxy'], File['/etc/haproxy/atomia_certificates'], File['/usr/lib/stateless_acme_challenge.lua'], - File['/var/lib/acme/haproxy'], + File['/etc/haproxy/le_certs'], File['/etc/haproxy/ssl-redirects.lst'] ], notify => Exec['restart-haproxy'], diff --git a/templates/haproxy/acmetool_renew.sh.erb b/templates/haproxy/acmetool_renew.sh.erb new file mode 100644 index 0000000..4510e42 --- /dev/null +++ b/templates/haproxy/acmetool_renew.sh.erb @@ -0,0 +1,103 @@ +#!/bin/bash + +PATH=$PATH:/usr/sbin +export PATH + +ATO_NETS="<%= @apache_cluster_ip %>/32" + +CERTS_DIR="/etc/haproxy/le_certs" + +# If the ATO_NETS ip is not binded then we need to exit the script as this nodes does not have binded IP +ip a | grep $ATO_NETS > /dev/null +BINDED=$? +if [ $BINDED -eq 1 ] +then + logger "Skipping renew of LE certs, as this nodes does not have apache cluster ip!" + exit 1 +fi + +curdate=$(date +%s) +renewed_cert=0 +revoked_cert=0 + +in_net() { + perl -e ' +use strict; +my $net = shift @ARGV or die "no net"; +my $ip = shift @ARGV or die "no ip"; +my @pair = split("/", $net); +my $pf = $pair[0]; +my $pl = $pair[1]; +$pf =~ s/(\d+)([.]|$)/sprintf("%02X", $1)/ge; +$pf = unpack("N", pack("H8", $pf)); +$pl = unpack("N", pack("b32", "1" x $pl . "0" x (32 - $pl))); +$ip =~ s/(\d+)([.]|$)/sprintf("%02X", $1)/ge; +$ip = unpack("N", pack("H8", $ip)); +exit 1 if ($pf & $pl) ne ($ip & $pl); +' "$1" "$2" +} + +in_ato_nets() { + is_in=no + for net in $ATO_NETS; do + in_net $net "$1" && { + is_in=yes + break + } + done + echo $is_in +} + +cd $CERTS_DIR +ls -tr | \ +while read pem; do + expdate1=$(date --date="$(openssl x509 -enddate -noout -in "$pem"|cut -d= -f 2)" +%s) + expdays=$(( (expdate1-curdate) / 86400)) + + if [ $expdays -le 25 ]; + then + + wanted_cert=`echo -n "$pem" | head -c-4` + + ip="$(dig +short $wanted_cert | head -1)" + + if [ -n "$ip" ] && [ "$(in_ato_nets $ip)" = yes ] ; then + echo "Certificate $wanted_cert expire on $expdate1, in $expdays days !" + echo "Renewing.." + + certbot renew --cert-name $wanted_cert --force-renewal + OUT=$? #0 if renew is succesfull, 1 if it's failed + + if [ $OUT -eq 0 ];then + sudo -E bash -c "cat /etc/letsencrypt/live/$wanted_cert/fullchain.pem /etc/letsencrypt/live/$wanted_cert/privkey.pem > /etc/haproxy/le_certs/$wanted_cert.pem" + chmod 600 /etc/haproxy/le_certs/$wanted_cert.pem + rm /var/log/letsencrypt/letsencrypt.log + find /var/log/letsencrypt/ -size 0 -delete + + ((renewed_cert++)) + fi + else + echo "Certificate $wanted_cert not hosted on this hosting!" + echo "Revoking.." + certbot revoke -d $wanted_cert --cert-path /etc/letsencrypt/live/${wanted_cert}/cert.pem --non-interactive + rm -f /etc/haproxy/le_certs/$wanted_cert.pem + ((revoked_cert++)) + fi + fi + + if [ $revoked_cert -ge 1000 ]; + then + echo "Revoke limit hit - breaking" + echo "Total number of revoked certs is $revoked_cert" + echo "Total number of renewed certs is $renewed_cert" + break + fi + + if [ $renewed_cert -ge 1000 ]; + then + echo "Renew limit hit - breaking" + echo "Total number of revoked certs is $revoked_cert" + echo "Total number of renewed certs is $renewed_cert" + break + fi +done \ No newline at end of file diff --git a/templates/haproxy/acmetool_sync.sh.erb b/templates/haproxy/acmetool_sync.sh.erb new file mode 100644 index 0000000..f167cf9 --- /dev/null +++ b/templates/haproxy/acmetool_sync.sh.erb @@ -0,0 +1,173 @@ +#!/bin/sh + +PATH=$PATH:/usr/sbin +export PATH + +ATO_NETS="<%= @apache_cluster_ip %>/32" + +# Setting up the script to support local and remote +<% if @haproxy_nodes.split(",")[0].downcase == @hostname %> +LB_REMOTE="<%= @haproxy_nodes.split(",")[1] %>" +LB_LOCAL="<%= @haproxy_nodes.split(",")[0] %>" +<% else %> +LB_REMOTE="<%= @haproxy_nodes.split(",")[0] %>" +LB_LOCAL="<%= @haproxy_nodes.split(",")[1] %>" +<% end %> + +certbot="/usr/bin/certbot" +wanted_cert_path="/etc/letsencrypt/live" +synced_apache_config="/etc/haproxy/synced_apache_config" +synced_iis_config="/etc/haproxy/synced_iis_config" +NEW_CERTS=0 + +if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "usage: $0 rsync_path_to_apache_config rsync_path_to_iis_config preview_domain" + echo "example:" + echo "$0 \"root@192.168.33.21:/storage/configuration/maps\" \"root@192.168.33.21:/storage/configuration/iis\" preview.dev.atomia.com" + exit 1 +fi + +# If the ATO_NETS ip is not binded then we need to exit the script as this nodes does not have binded IP +ip a | grep $ATO_NETS > /dev/null +BINDED=$? +if [ $BINDED -eq 1 ] +then + logger "Skipping issuing of LE certs, as this nodes does not have apache cluster ip!" + logger "Doing only rsync from the primary load balancer $LB_REMOTE" + + # We now need to sync our certificates from the LB_REMOTE node as we are not on the main node + # In order for sync to work a certbot user needs to be created on both nodes with the same key + # That user should also have sudo privileges without a password + # Also the certbot private key needs to be added to /root/.ssh/certbot + if [ -n "$LB_REMOTE" ] + then + # Try to login via SSH without password to the remote LB node and pull the certs + ssh -o PasswordAuthentication=no -o BatchMode=yes certbot@$LB_REMOTE -p 2022 -i /root/.ssh/certbot exit &>/dev/null + if [ $? -eq 0 ] + then + # Login success, we are able to login with key to the node + # Rsync pull certs from remote node primary LB + # In order for rsync to work via certbot user we need to add + # the certbot to sudoers certbot ALL= NOPASSWD:/usr/bin/rsync + logger "Rsync now from $LB_REMOTE" + + rsync -a -e "ssh -o StrictHostKeyChecking=no -i /root/.ssh/certbot -p 2022" --rsync-path="sudo rsync" "certbot@$LB_REMOTE:/etc/haproxy/le_certs/" /etc/haproxy/le_certs/ + rsync -a -e "ssh -o StrictHostKeyChecking=no -i /root/.ssh/certbot -p 2022" --rsync-path="sudo rsync" "certbot@$LB_REMOTE:/etc/letsencrypt/archive/" /etc/letsencrypt/archive/ + rsync -a -e "ssh -o StrictHostKeyChecking=no -i /root/.ssh/certbot -p 2022" --rsync-path="sudo rsync" "certbot@$LB_REMOTE:/etc/letsencrypt/renewal/" /etc/letsencrypt/renewal/ + rsync -a -e "ssh -o StrictHostKeyChecking=no -i /root/.ssh/certbot -p 2022" --rsync-path="sudo rsync" "certbot@$LB_REMOTE:/etc/letsencrypt/live/" /etc/letsencrypt/live/ + + logger "Reloading Haproxy" + service haproxy reload + else + # Login failed, we will not sync + logger "Could not login to $LB_REMOTE, skipping sync of LE certificates!" + fi + fi + exit 1 +fi + +#get all ips +CURRENT_IPS=$`hostname -I` + +#convert to newlines and sort files for comm command +echo $ATO_NETS | tr " " "\n" | sort > /tmp/l1.tmp +echo $CURRENT_IPS | tr " " "\n" | sort > /tmp/l2.tmp + +#append /32 on all IPS that hostname -I returns +sed -e 's/$/\/32/' -i /tmp/l2.tmp + +#create new ATO_NETS with lines that match both +ATO_NETS=`comm -12 /tmp/l1.tmp /tmp/l2.tmp | tr "\n" " "` + +#remove temp files +rm /tmp/l1.tmp /tmp/l2.tmp + +#check if ATO_NETS is empty +if [ -z $ATO_NETS ] +then + echo "Empty ATO_NETS, Reloading haproxy" + service haproxy reload + echo "Reloading done, now exiting" + exit +fi + +# Sync all files from /storage/content/ssl to local dir +rsync -a -e "ssh -o StrictHostKeyChecking=no" --delete "$1"/ "$synced_apache_config" +#rsync -a -e "ssh -o StrictHostKeyChecking=no" --delete "$2"/ "$synced_iis_config" + +in_net() { + perl -e ' +use strict; + +my $net = shift @ARGV or die "no net"; +my $ip = shift @ARGV or die "no ip"; + +my @pair = split("/", $net); +my $pf = $pair[0]; +my $pl = $pair[1]; + +$pf =~ s/(\d+)([.]|$)/sprintf("%02X", $1)/ge; +$pf = unpack("N", pack("H8", $pf)); +$pl = unpack("N", pack("b32", "1" x $pl . "0" x (32 - $pl))); + +$ip =~ s/(\d+)([.]|$)/sprintf("%02X", $1)/ge; +$ip = unpack("N", pack("H8", $ip)); + +exit 1 if ($pf & $pl) ne ($ip & $pl); +' "$1" "$2" +} + +in_ato_nets() { + is_in=no + for net in $ATO_NETS; do + in_net $net "$1" && { + is_in=yes + break + } + done + echo $is_in +} + +if [ -f "$synced_apache_config/vhost.map" ]; then + cat "$synced_apache_config"/vhost.map | awk '{ print $1 }' | grep -vE "$3"'$' | grep -v '^www\.' | grep -E '^[a-zA-Z0-9.-]+$' \ + | sort -u | awk '{ print $0 " www." $0 }' | while read cert; do + wanted_cert=$(echo "$cert" | cut -d " " -f 1) + wanted_wwwcert=$(echo "$cert" | cut -d " " -f 2 ) + desired=$(echo "$cert" | cut -d " " -f 1 ) + #echo $wanted_cert $wanted_wwwcert $desired + if [ ! -d `echo "$wanted_cert_path/$desired"` ]; then + # We force 8.8.8.8 because sometimes our DNS does not propagate + # all records immediateley, it's better to ask the outside DNS + # just to be sure that everything has been propagated before + # issuing the SSL certificate + ip1="$(dig +short $wanted_wwwcert @8.8.8.8 | grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b')" + ip2="$(dig +short $wanted_cert @8.8.8.8 | head -1)" + + if [ -n "$ip1" ] && [ "$(in_ato_nets $ip1)" = yes ] && [ -n "$ip2" ] && [ "$(in_ato_nets $ip2)" = yes ] ; then + echo "$wanted_cert_path/$desired" + #echo "wanted cert: $wanted_cert" + #echo "www cert: $wwwcert" + certbot certonly --webroot -w /tmp -d $wanted_cert -d $wanted_wwwcert --non-interactive --agree-tos --email noreply@atomia.com + if [ -d `echo "$wanted_cert_path/$desired"` ]; then + echo "Issuing $wanted_cert" + sudo -E bash -c "cat /etc/letsencrypt/live/$wanted_cert/fullchain.pem /etc/letsencrypt/live/$wanted_cert/privkey.pem > /etc/haproxy/le_certs/$wanted_cert.pem" + chmod 600 /etc/haproxy/le_certs/$wanted_cert.pem + rm /var/log/letsencrypt/letsencrypt.log + find /var/log/letsencrypt/ -size 0 -delete + fi + fi + fi + done + + #Delete broken PEMs + find /etc/haproxy/le_certs/ -size 0 -delete + + #If there is at least one new cert, reload haproxy +# if [ "$NEW_CERTS" -ge "1" ]; then + echo "Reloading haproxy" + service haproxy reload + echo "Reloading done" +# fi +fi + +exit 0 \ No newline at end of file diff --git a/templates/haproxy/haproxy.conf.erb b/templates/haproxy/haproxy.conf.erb index 773037f..4c01b5e 100644 --- a/templates/haproxy/haproxy.conf.erb +++ b/templates/haproxy/haproxy.conf.erb @@ -29,7 +29,7 @@ defaults frontend apachecluster bind <%= @apache_cluster_ip %>:80 - bind <%= @apache_cluster_ip %>:443 ssl crt /etc/haproxy/atomia_certificates/default.pem crt /etc/haproxy/atomia_certificates crt /var/lib/acme/haproxy + bind <%= @apache_cluster_ip %>:443 ssl crt /etc/haproxy/atomia_certificates/default.pem crt /etc/haproxy/atomia_certificates crt /etc/haproxy/le_certs option http-server-close http-request add-header X-Proto https if { ssl_fc } @@ -38,13 +38,15 @@ frontend apachecluster http-request redirect scheme https if enforce_ssl is_http_req + use_backend awstats_servers if { hdr_beg(host) -i awstats. } + acl acme_challenge path_beg /.well-known/acme-challenge/ http-request use-service lua.stateless_acme_challenge if acme_challenge default_backend apache_servers frontend iiscluster bind <%= @iis_cluster_ip %>:80 - bind <%= @iis_cluster_ip %>:443 ssl crt /etc/haproxy/atomia_certificates/default.pem crt /etc/haproxy/atomia_certificates crt /var/lib/acme/haproxy + bind <%= @iis_cluster_ip %>:443 ssl crt /etc/haproxy/atomia_certificates/default.pem crt /etc/haproxy/atomia_certificates crt /etc/haproxy/le_certs option http-server-close http-request add-header X-Proto https if { ssl_fc } @@ -69,7 +71,7 @@ frontend mailcluster frontend webmailcluster bind <%= @mail_cluster_ip %>:80 - bind <%= @mail_cluster_ip %>:443 ssl crt /etc/haproxy/atomia_certificates/default.pem crt /etc/haproxy/atomia_certificates crt /var/lib/acme/haproxy + bind <%= @mail_cluster_ip %>:443 ssl crt /etc/haproxy/atomia_certificates/default.pem crt /etc/haproxy/atomia_certificates crt /etc/haproxy/le_certs option http-server-close http-request add-header X-Proto https if { ssl_fc } @@ -96,13 +98,11 @@ frontend ftpcluster backend apache_servers option forwardfor balance roundrobin - stick-table type ip size 200k expire 30m - stick on src -<% @apache_cluster_nodes.split(",").each_with_index do |node, index| -%> - server apache<%=index+1 %> <%= node %>:80 check - acl acme_challenge path_beg /.well-known/acme-challenge/ - http-request use-service lua.stateless_acme_challenge if acme_challenge + http-request use-service lua.stateless_acme_challenge if acme_challenge + cookie WEBSVR insert +<% @apache_cluster_nodes.split(",").each_with_index do |node, index| -%> + server apache<%=index+1 %> <%= node %>:80 cookie A<%=index+1 %> check inter 3000 <% end -%> backend iis_servers @@ -113,6 +113,10 @@ backend iis_servers server iis<%=index+1 %> <%= node %>:80 check <% end -%> +backend awstats_servers + balance roundrobin + server awstats1 <%= @awstats_cluster_ip %>:80 check + backend mail_servers mode tcp balance roundrobin diff --git a/templates/haproxy/sync_acmetool.cron b/templates/haproxy/sync_acmetool.cron index 444e32f..a448256 100644 --- a/templates/haproxy/sync_acmetool.cron +++ b/templates/haproxy/sync_acmetool.cron @@ -1 +1 @@ -* * * * * root flock -n /var/lock/acmesync.lock /usr/bin/acmetool_sync.sh "<%= @apache_config_sync_source %>" "<%= @iis_config_sync_source %>" "<%= @preview_domain %>" +*/5 * * * * root flock -n /var/lock/acmesync.lock /usr/bin/acmetool_sync.sh "<%= @apache_config_sync_source %>" "<%= @iis_config_sync_source %>" "<%= @preview_domain %>"