Сервис по выдаче и автоматическому обновлению бесплатных SSL-сертификатов. Для Windows пока нет стандартной процедуры, но есть сторонние разработки.
Вариант для Apache on Ubuntu 16.04 (xenial)
Чтобы сделать сертификат для домена, отличающегося от имени сервера, запустить certbot с параметром –domain, например
certbot --apache --domain test.example.org
Проверять актуальность сертификата и обновлять при необходимости каждый день в 8:00 и 20:00.
nano /etc/crontab
Добавить туда
0 8,20 * * * root letsencrypt renew
Штука в том, что порты 80 и 443 заняты, и certbot должен работать на другом порту (здесь: 54321). Помимо этого, нужно настроить Haproxy на проброс его URL на localhost сервера Haproxy. Затем необходимо слепить сертификат с ключом в единый .pem и положить их в каталог, куда Haproxy смотрит.
# На фронтенде :80 # Let's Encrypt URL acl letsencrypt_url path_beg /.well-known/acme-challenge/ # Не пробрасывать на HTTPS http-request redirect scheme https if !{ ssl_fc } !no-https-domains !letsencrypt_url # Let's Encrypt backend use_backend be_letsencrypt if letsencrypt_url # Бэкенд backend be_letsencrypt server letsencrypt 127.0.0.1:54321
# Получить сертификат для example.com и www.example.com certbot certonly --standalone --preferred-challenges http-01 --http-01-port 54321 --keep --agree-tos --expand -m ssl@example.com -d example.com -d www.example.com :' Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for example.com and www.example.com Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem This certificate expires on 2022-08-18. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - If you like Certbot, please consider supporting our work by: * Donating to ISRG / Let`s Encrypt: https://letsencrypt.org/donate * Donating to EFF: https://eff.org/donate-le - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '
«Certbot has set up a scheduled task to automatically renew this certificate in the background.»
Если Certbot установлен через snap, то вместо cron он добавляет задачи на обновление сертификата в systemd timer. Посмотреть:
systemctl list-timers
https://eff-certbot.readthedocs.io/en/stable/using.html#automated-renewals
Использование таймеров systemd вместо заданий cron
#!/bin/bash LE_CERT_DIR=/etc/letsencrypt/live HAPROXY_CERT_DIR=/etc/ssl/certs/haproxy # Cat the certificate chain and the private key together for haproxy for path in $(find $LE_CERT_DIR/* -type d -exec basename {} \;); do cat $LE_CERT_DIR/$path/{fullchain.pem,privkey.pem} > $HAPROXY_CERT_DIR/${path}.pem done
https://certbot.eff.org/instructions?ws=haproxy&os=ubuntufocal
https://eff-certbot.readthedocs.io/en/stable/using.html#certbot-command-line-options
https://gist.github.com/lmmendes/7fad9a2c8f389b39b6661d0945b72cb7
https://www.digitalocean.com/community/tutorials/how-to-secure-haproxy-with-let-s-encrypt-on-ubuntu-14-04
https://www.digitalocean.com/community/tutorials/how-to-use-certbot-standalone-mode-to-retrieve-let-s-encrypt-ssl-certificates-on-ubuntu-20-04
#!/bin/bash for d in "$@"; do domains+="-d $d " done certbot certonly --standalone --preferred-challenges http-01 --http-01-port 54321 --keep --agree-tos --expand -m ssl@example.com $domains && \ cat /etc/letsencrypt/live/$1/{fullchain.pem,privkey.pem} > /etc/ssl/certs/haproxy/$1.pem && \ systemctl reload haproxy
Использование:
chmod u+x /scripts/haproxy-cert-issue.sh # Файл сертификата будет назван по имени первого аргумента (/etc/ssl/certs/haproxy/example.com.pem) # Все аргументы будут добавлены в команду как домены (-d example.com -d www.example.com и т. д.) /scripts/haproxy-cert-issue.sh example.com www.example.com example2.com www.example2.com
#!/bin/bash cat $RENEWED_LINEAGE/{fullchain.pem,privkey.pem} > /etc/ssl/certs/haproxy/$(basename $RENEWED_LINEAGE).pem # --deploy-hook DEPLOY_HOOK # Command to be run in a shell once for each # successfully issued certificate. For this command, the # shell variable $RENEWED_LINEAGE will point to the # config live subdirectory (for example, # "/etc/letsencrypt/live/example.com") containing the # new certificates and keys; the shell variable # $RENEWED_DOMAINS will contain a space-delimited list # of renewed certificate domains (for example, # "example.com www.example.com") (default: None)
Перезапуск HAProxy
### /scripts/haproxy-reload-if-new-certs.sh #!/bin/bash if [[ $(find /etc/ssl/certs/haproxy/* -mtime -1) ]] then systemctl reload haproxy.service fi # to cron echo -e "\n# Reload HAProxy if there are new certs\n0 3\t* * *\troot\t/scripts/haproxy-reload-if-new-certs.sh" >> /etc/crontab
Сама она не умеет (asa5545X). Сетевики должны прокинуть на ней 80-й порт на внутренний/DMZ-сервер, завести отдельную учётку и разрешить для этой учётки некоторые команды и вход на ASA по ssh.
Далее всё делается на сервере.
# Необходимо установить certbot и expect для автоматизации работы с Cisco через ssh. sudo snap install --classic certbot sudo apt install expect -y # Выпустить сертификат certbot certonly --standalone --preferred-challenges http-01 --keep --agree-tos --expand -m ssl@example.com -d vpn.example.com
Конфиг состоит из 3 файлов.
# скрипт, выполняющийся при обновлении сертификата touch /etc/letsencrypt/renewal-hooks/deploy/vpncert-asa.sh chmod 700 /etc/letsencrypt/renewal-hooks/deploy/vpncert-asa.sh # скрипт expect touch /scripts/vpncert-install.exp chmod 700 /scripts/vpncert-install.exp # пароль экспорта сертификата для openssl touch /scripts/vpncert-asa.txt chmod 600 /scripts/vpncert-asa.txt # Записать пароль в файл пароля nano /scripts/vpncert-asa.txt
#!/bin/bash openssl pkcs12 -export \ -password file:/scripts/vpncert-asa.txt \ -in $RENEWED_LINEAGE/fullchain.pem \ -inkey $RENEWED_LINEAGE/privkey.pem \ -out /root/gate.pfx && \ openssl base64 -in /root/gate.pfx -out /root/gate.base64 && \ /scripts/vpncert-install.exp
#!/usr/bin/expect -f set timeout 5 set send_slow {10 .001} set sshUser "sshuser" set sshIP "192.168.1.254" set sshPass "sshPass12345" set exportPass [exec cat /scripts/vpncert-asa.txt] #set log "/root/vpncert.log" #log_file -noappend $log #log_user 0 spawn ssh -o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostKeyAlgorithms=+ssh-rsa -o StrictHostKeyChecking=no $sshUser@$sshIP expect "password:" send -- "$sshPass\r" expect ">" send -- "enable\r" expect "Password:" send -- "$sshPass\r" expect "#" #log_user 1 send -- "configure terminal\r" expect "(config)#" send -- "no crypto ca trustpoint ca_le\r" expect { "]:" {send -- "yes\r"; exp_continue} "(config)#" } send -- "crypto ca trustpoint ca_le\r" expect "trustpoint)#" send -- "enrollment terminal\r" expect "#" send -- "exit\r" expect "(config)#" #log_user 0 send -- "crypto ca import ca_le pkcs12 $exportPass\r" expect "itself:" send -- [exec cat /root/gate.base64]\n send -s "quit\r" # % The CA cert is not self-signed. # % Do you also want to create trustpoints for CAs higher in the hierarchy? [yes/no]: # OR # % You already have RSA or ECDSA keys named ca_le. # % If you replace them, all device certs issued using these keys # % will be removed. # % Do you really want to replace them? [yes/no]: expect { "]:" {send -- "yes\r"; exp_continue} "(config)#" } #log_user 1 send -- "ssl trust-point ca_le outside\r" expect "(config)#" send -- "exit\r" expect "#" send -- "exit\r" expect eof
expect(1)
Expect command and how to automate shell scripts like magic
SSL Certificate Installation on the ASA: Installation of a PEM Certificate with the CLI