This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
certbot [2019-11-27 17:49:15] mi |
certbot [2022-12-13 12:26:37] (current) mi [Use cron instead of systemd timers] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| = certbot | = certbot | ||
| - | == Install in Jessie | + | == Install |
| + | |||
| + | === install in Jessie | ||
| For Debian 8 (Jessie): | For Debian 8 (Jessie): | ||
| Line 14: | Line 16: | ||
| Not sure if adding this is useful: ''certbot-auto --install-only'' | Not sure if adding this is useful: ''certbot-auto --install-only'' | ||
| - | == Install in Stretch | + | === install in Stretch |
| For Debian 9 (Stretch): | For Debian 9 (Stretch): | ||
| Line 31: | Line 33: | ||
| This will aslo create the ''/etc/letsencrypt/'' and ''/var/lib/letsencrypt/'' directories if needed | This will aslo create the ''/etc/letsencrypt/'' and ''/var/lib/letsencrypt/'' directories if needed | ||
| - | === On a separate IP address | + | Apache can be configured to [[https://httpd.apache.org/docs/2.4/bind.html|listen on specific IPs:ports]] (''Listen IP:port'' in ''/etc/apache2/ports.conf''). |
| - | If a web server is running, but the certificate should be delivered for another IP/name on that host: | + | Or it is possible to use a temporary standalone server started by letsencrypt. The ''--standalone'' option will start it on all IPs. The ''--webroot'' option starts it only on a specific IP. |
| - | * configure Apache to only [[https://httpd.apache.org/docs/2.4/bind.html|listen on specific IPs:ports]] (''Listen IP:port'' in ''/etc/apache2/ports.conf'') | + | === Get certificate on specific IP |
| - | * start a separate web server: | + | |
| + | The ''python3 -m http.server'' command with the ''--bind'' option can only take a single IP. Without the option, it binds to all IPs. | ||
| <code> | <code> | ||
| dir=/var/lib/letsencrypt/tmpwww | dir=/var/lib/letsencrypt/tmpwww | ||
| - | ip=a.b.c.d ## <-- IP to be used for validation | + | ip=1.2.3.4 |
| - | name=ftp.example.com | + | name="example.com,www.example.com" |
| - | email=letsencrypt@example.com | + | email=admin.letsencrypt@example.com |
| mkdir -p "$dir" | mkdir -p "$dir" | ||
| Line 50: | Line 53: | ||
| </code> | </code> | ||
| - | certbot-auto certonly --test-cert --webroot --webroot-path "$dir" -d $name -n --agree-tos -m $email | + | If needed, open firewall on http port 80. Or if scripts exist already, add these hooks to the certbot commands below: |
| - | + | ||
| - | If needed, add firewall scripts to open/close ports: | + | |
| <code> | <code> | ||
| Line 59: | Line 60: | ||
| </code> | </code> | ||
| - | After testing, to replace certificate with a real one: | + | Test with dry-run: |
| + | |||
| + | certbot-auto certonly --dry-run --webroot --webroot-path "$dir" -d $name -n --agree-tos -m $email | ||
| + | |||
| + | Do it: | ||
| + | |||
| + | certbot-auto certonly --webroot --webroot-path "$dir" -d $name -n --agree-tos -m $email | ||
| + | |||
| + | And finally, stop the standalone web server: | ||
| + | |||
| + | kill $pid | ||
| + | |||
| + | Renewals should now work automatically with the cron job and scripts in /etc/letsencrypt/renewal-hooks/ | ||
| + | |||
| + | === Renewal-hooks | ||
| + | |||
| + | These will be used automatically on renew if placed in ''/etc/letsencrypt/renewal-hooks/pre'' and ''.../post'' dirs. | ||
| + | |||
| + | ==== /etc/letsencrypt/renewal-hooks/pre | ||
| + | |||
| + | <file bash fw-certbot-open>#!/bin/bash | ||
| + | |||
| + | # Open firewall to let certbot renew certificates | ||
| + | |||
| + | me=$(basename "$0") | ||
| + | |||
| + | logger -t "$me" "Opening port 80 for certbot" | ||
| + | |||
| + | iptables -I INPUT -p tcp --dport 80 -j NFLOG --nflog-prefix "nfl:ok-certbot " | ||
| + | iptables -I INPUT -p tcp --dport 80 -j ACCEPT -m comment --comment "Allow HTTP for certbot" | ||
| + | </file> | ||
| + | |||
| + | <file bash certbot-webroot-start>#!/bin/bash | ||
| + | |||
| + | # Create webroot and web server for certbot renewal | ||
| + | |||
| + | me=$(basename "$0") | ||
| + | |||
| + | dir=/var/lib/letsencrypt/tmpwww | ||
| + | ips="1.2.3.4 10.11.12.13" ## <-- IPs to be used for validation | ||
| + | |||
| + | mkdir -p "$dir" | ||
| + | cd "$dir" | ||
| + | |||
| + | declare -a pids | ||
| + | |||
| + | for ip in $ips; do | ||
| + | logger -t "$me" "Starting server on $ip in $dir" | ||
| + | |||
| + | nohup python3 -m http.server --bind $ip 80 &>/dev/null & | ||
| + | pid=$! | ||
| + | pids+=($pid) | ||
| + | echo "$pid" > "$dir/certbot-webroot-$$-$pid.pid" | ||
| + | done | ||
| + | |||
| + | </file> | ||
| + | |||
| + | ==== /etc/letsencrypt/renewal-hooks/post | ||
| + | |||
| + | <file bash fw-certbot-open>#!/bin/bash | ||
| + | |||
| + | # Removing firewall rules created for certbot renew certificates | ||
| + | |||
| + | me=$(basename "$0") | ||
| + | |||
| + | logger -t "$me" "Closing port 80 opened for certbot" | ||
| + | |||
| + | iptables -D INPUT -p tcp --dport 80 -j NFLOG --nflog-prefix "nfl:ok-certbot " | ||
| + | iptables -D INPUT -p tcp --dport 80 -j ACCEPT -m comment --comment "Allow HTTP for certbot" | ||
| + | </file> | ||
| + | |||
| + | <file bash certbot-webroot-stop>#!/bin/bash | ||
| + | |||
| + | # Stop webroot web server used for certbot renewal | ||
| + | |||
| + | me=$(basename "$0") | ||
| + | |||
| + | dir=/var/lib/letsencrypt/tmpwww | ||
| + | |||
| + | for f in $dir/certbot-webroot-*.pid; do | ||
| + | logger -t "$me" "Stopping server with pid in $f" | ||
| + | kill $(< "$f") && rm "$f" | ||
| + | # or?: # kill $(ps ax | grep '[p]ython3 -m http.server' | awk '{print $1}') | ||
| + | done | ||
| + | </file> | ||
| + | |||
| + | ==== /etc/letsencrypt/renewal-hooks/deploy | ||
| + | |||
| + | <file bash reload>#!/bin/bash | ||
| + | |||
| + | # Reloading services to refresh certificates | ||
| + | |||
| + | me=$(basename "$0") | ||
| + | |||
| + | logger -t "$me" "Reloading postfix to refresh certificates." | ||
| + | postfix reload | ||
| + | (( $? != 0 )) && logger -t "$me" "ERROR with postfix reload." | ||
| + | |||
| + | logger -t "$me" "Reloading dovecot to refresh certificates." | ||
| + | doveadm reload | ||
| + | (( $? != 0 )) && logger -t "$me" "ERROR with doveadm reload." | ||
| + | |||
| + | logger -t "$me" "Reloading Apache to refresh certificates." | ||
| + | apachectl -t >/dev/null && apachectl graceful | ||
| + | (( $? != 0 )) && logger -t "$me" "ERROR with apachectl." | ||
| + | |||
| + | exit 0 | ||
| + | </file> | ||
| + | Once [[https://github.com/certbot/certbot/issues/6722|this]] has been fixed, these variables might also be used, eg. for logging: | ||
| + | |||
| + | logger -t "$me" "CERTBOT_DOMAIN=$CERTBOT_DOMAIN, CERTBOT_VALIDATION=$CERTBOT_VALIDATION, CERTBOT_TOKEN=$CERTBOT_TOKEN, CERTBOT_AUTH_OUTPUT=$CERTBOT_AUTH_OUTPUT" | ||
| + | |||
| + | |||
| + | ===Other options: | ||
| + | |||
| + | certbot-auto renew --cert-name $name --force-renewal | ||
| + | |||
| + | --test-cert | ||
| - | certbot-auto renew --cert-name $name --force-renewal --server https://acme-v02.api.letsencrypt.org/directory | + | See them all with ''certbot-auto --help all | less'' |
| See also: | See also: | ||
| + | * [[https://docs.python.org/3.5/library/http.server.html#http-server-cli]] "By default, server uses the current directory. The option -d/--directory ( new in version 3.7 ) specifies a directory to which it should serve the files. For example, the following command uses a specific directory: ''python -m http.server --directory /tmp/'' " | ||
| * [[https://github.com/certbot/certbot/issues/255|Standalone configurator: Dealing with existing processes that are listening on some, but not all, interfaces · Issue #255 · certbot/certbot]] | * [[https://github.com/certbot/certbot/issues/255|Standalone configurator: Dealing with existing processes that are listening on some, but not all, interfaces · Issue #255 · certbot/certbot]] | ||
| * [[https://github.com/certbot/certbot/issues/1515|Bind on a specific interface · Issue #1515 · certbot/certbot]] ( https://github.com/certbot/certbot/issues/1515#issuecomment-193790398 ) | * [[https://github.com/certbot/certbot/issues/1515|Bind on a specific interface · Issue #1515 · certbot/certbot]] ( https://github.com/certbot/certbot/issues/1515#issuecomment-193790398 ) | ||
| Line 70: | Line 189: | ||
| * [[https://github.com/certbot/certbot/issues/3489|Ability to set source IP · Issue #3489 · certbot/certbot]] | * [[https://github.com/certbot/certbot/issues/3489|Ability to set source IP · Issue #3489 · certbot/certbot]] | ||
| * [[https://github.com/certbot/certbot/pull/6007|WIP commit of adding a --source-address flag. by signop · Pull Request #6007 · certbot/certbot]] | * [[https://github.com/certbot/certbot/pull/6007|WIP commit of adding a --source-address flag. by signop · Pull Request #6007 · certbot/certbot]] | ||
| + | |||
| + | == Add host to existing certificate | ||
| + | |||
| + | View existing cert. | ||
| + | |||
| + | certbot certificates | ||
| + | |||
| + | Copy all hosts in existing cert. into comma-separated list, and add the new host. Then: | ||
| + | |||
| + | certbot --expand -d main.example.com,other.example.com,new.example.com | ||
| + | |||
| + | (Found on [[https://superuser.com/questions/1432541|How to add a domain to existing certificate generated by Let’s Encrypt/Certbot?]]) | ||
| == Configs | == Configs | ||
| Line 149: | Line 280: | ||
| ===== Use cron instead of systemd timers ===== | ===== Use cron instead of systemd timers ===== | ||
| + | |||
| + | I prefer crontab to the default systemd timers. So to disable the timers and use crontab instead: | ||
| <code bash> | <code bash> | ||
| Line 158: | Line 291: | ||
| m=$(( RANDOM % 60 )); h=$(( RANDOM % 24 )); d=$(( RANDOM % 7 )) | m=$(( RANDOM % 60 )); h=$(( RANDOM % 24 )); d=$(( RANDOM % 7 )) | ||
| - | echo "## Let's Encrypt SSL certificate renewal with certbot" | tee -a /etc/crontab | + | echo "## Let's Encrypt SSL cert. renewal, once per week" | tee -a /etc/crontab |
| - | echo "$m $h * * $d root /usr/bin/certbot -q renew" | tee -a /etc/crontab | + | echo "$m $h * * $d root /usr/bin/certbot -q renew" | tee -a /etc/crontab |
| # dom=$(( 1+ RANDOM % 31 )) mon=$(( 1+ RANDOM % 12 )) | # dom=$(( 1+ RANDOM % 31 )) mon=$(( 1+ RANDOM % 12 )) | ||