User Tools

Site Tools


certbot

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
certbot [2019-09-30 14:23:49]
mi
certbot [2022-12-13 12:26:37] (current)
mi [Use cron instead of systemd timers]
Line 1: Line 1:
 = certbot = certbot
  
-== Install in Stretch+== Install 
 + 
 +=== install in Jessie 
 +For Debian 8 (Jessie): 
 + 
 +<​code>​ 
 +apt remove certbot 
 +wget https://​dl.eff.org/​certbot-auto 
 +mv certbot-auto /​usr/​local/​bin/​certbot-auto 
 +chown -c root /​usr/​local/​bin/​certbot-auto 
 +chmod -c 0755 /​usr/​local/​bin/​certbot-auto 
 +</​code>​ 
 + 
 +Not sure if adding this is useful: ''​certbot-auto --install-only''​ 
 + 
 +=== install ​in Stretch
 For Debian 9 (Stretch): For Debian 9 (Stretch):
  
-  ​[ -f /​etc/​apt/​sources.list.d/​stretch-backports.list ] || cat <<'​END'​ > /​etc/​apt/​sources.list.d/​stretch-backports.list +<​code>​ 
-  # https://​backports.debian.org/​Instructions/​ +[ -f /​etc/​apt/​sources.list.d/​stretch-backports.list ] || cat <<'​END'​ > /​etc/​apt/​sources.list.d/​stretch-backports.list 
-  deb http://​deb.debian.org/​debian stretch-backports main +# https://​backports.debian.org/​Instructions/​ 
-  END +deb http://​deb.debian.org/​debian stretch-backports main 
-   +END 
-  apt update + 
-  apt install certbot python-certbot-apache -t stretch-backports+apt update 
 +apt install certbot python-certbot-apache -t stretch-backports 
 +</​code>​ 
 + 
 +== Get first certificate(s) 
 + 
 +This will aslo create the ''/​etc/​letsencrypt/''​ and ''/​var/​lib/​letsencrypt/''​ directories if needed 
 + 
 +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''​). 
 + 
 +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. 
 + 
 +=== Get certificate on specific IP 
 + 
 +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>​ 
 +dir=/​var/​lib/​letsencrypt/​tmpwww 
 +ip=1.2.3.4 
 +name="​example.com,​www.example.com"​ 
 +email=admin.letsencrypt@example.com 
 + 
 +mkdir -p "​$dir"​ 
 +cd "​$dir"​ 
 +python3 -m http.server --bind $ip 80 & 
 +pid=$! 
 +</​code>​ 
 + 
 +If needed, open firewall on http port 80. Or if scripts exist already, add these hooks to the certbot commands below: 
 + 
 +<​code>​ 
 +--pre-hook ​ /​etc/​letsencrypt/​renewal-hooks/​pre/​fw-certbot-open \ 
 +--post-hook /​etc/​letsencrypt/​renewal-hooks/​post/​fw-certbot-close 
 +</​code>​ 
 + 
 +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 
 + 
 +See them all with ''​certbot-auto --help all | less''​ 
 + 
 +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/​1515|Bind on a specific interface · Issue #1515 · certbot/​certbot]] ( https://​github.com/​certbot/​certbot/​issues/​1515#​issuecomment-193790398 ) 
 +  * [[https://​github.com/​certbot/​certbot/​pull/​5990|Add support for specifying source_address to ClientNetwork. by signop · Pull Request #5990 · 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]] 
 + 
 +== 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
  
-  ​ln -sri /​etc/​letsencrypt/​live/​HOST.EXAMPLE.COM/​cert.pem ​      /​etc/​ssl/​ +<​code>​ 
-  ln -sri /​etc/​letsencrypt/​live/​HOST.EXAMPLE.COM/​fullchain.pem ​ /etc/ssl/ +ln -sri /​etc/​letsencrypt/​live/​HOST.EXAMPLE.COM/​cert.pem ​      /​etc/​ssl/​ 
-  ln -sri /​etc/​letsencrypt/​live/​HOST.EXAMPLE.COM/​privkey.pem ​   /​etc/​ssl/​private/​+ln -sri /​etc/​letsencrypt/​live/​HOST.EXAMPLE.COM/​fullchain.pem ​ /etc/ssl/ 
 +ln -sri /​etc/​letsencrypt/​live/​HOST.EXAMPLE.COM/​privkey.pem ​   /​etc/​ssl/​private/​ 
 +</​code>​
  
 === Postfix main.cf === Postfix main.cf
  
-  ​# postconf -n | grep '​smtpd_tls_.*_file'​+<​code>​# postconf -n | grep '​smtpd_tls_.*_file'​ 
 +</​code>​
  
   smtpd_tls_key_file ​ = /​etc/​ssl/​private/​privkey.pem   smtpd_tls_key_file ​ = /​etc/​ssl/​private/​privkey.pem
Line 27: Line 220:
 === Proftpd tls.conf === Proftpd tls.conf
  
-  ​# grep '​^\s*TLSRSACertificate'​ /​etc/​proftpd/​*.conf +<​code>​ 
-  # for example in tls.conf :+# grep '​^\s*TLSRSACertificate'​ /​etc/​proftpd/​*.conf 
 +# for example in tls.conf : 
 +</​code>​
  
   TLSRSACertificateFile /​etc/​ssl/​fullchain.pem   TLSRSACertificateFile /​etc/​ssl/​fullchain.pem
   TLSRSACertificateKeyFile /​etc/​ssl/​private/​privkey.pem   TLSRSACertificateKeyFile /​etc/​ssl/​private/​privkey.pem
  
-  ​# Is this also needed? +<​code>​ 
-  TLSCACertificateFile /​etc/​ssl/​fullchain.pem+# Is this also needed? 
 +TLSCACertificateFile /​etc/​ssl/​fullchain.pem 
 +</​code>​
  
 === Dovecot conf.d/​10-ssl.conf === Dovecot conf.d/​10-ssl.conf
  
-  ​# doveconf -nPS | grep '​^\s*ssl_'​+<​code>  ​# doveconf -nPS | grep '​^\s*ssl_'​
   # or to find the file (eg. /​etc/​dovecot/​conf.d/​10-ssl.conf)   # or to find the file (eg. /​etc/​dovecot/​conf.d/​10-ssl.conf)
   # grep -r '​^\s*ssl_'​ /​etc/​dovecot   # grep -r '​^\s*ssl_'​ /​etc/​dovecot
 +</​code>​
  
   ssl_cert=</​etc/​ssl/​fullchain.pem   ssl_cert=</​etc/​ssl/​fullchain.pem
Line 47: Line 245:
 === Postgresql 9.6/​main/​postgresql.conf === Postgresql 9.6/​main/​postgresql.conf
  
-  # psql -U postgres ​-c "SELECT name, setting, sourcefile, sourceline FROM pg_settings WHERE name LIKE '​ssl_%_file'"​ +Postgresql needs to be able to read these files as user "postgres"​. ​So they must be copied into it'​s ​configdir. and chown'​ed. Best done with a deploy-hook in ''/etc/letsencrypt/renewal-hooks/deploy/''​ :
-  # or in the file postgresql.conf: +
-  # grep '^\s*ssl_.*_file' /etc/postgresql/9.6/main/postgresql.conf ​+
  
-  ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem' # (change requires restart) +<file bash 10-certbot-postgresql>​ 
-  ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key' # (change requires restart)+#​!/​bin/​bash 
 + 
 +## Postgresql needs to be able to read these files as user "​postgres"​. 
 +## So they must be copied into it's config. dir. and chown'​ed. 
 + 
 +verbose=1 
 + 
 +if (( verbose )); then 
 + echo "​Running $0" 
 + v_cp="​-v"​ 
 + v_cw="​-c"​ 
 +fi 
 + 
 +cp $v_cp /etc/letsencrypt/live/m1.almanet.ch/​{fullchain,​privkey}.pem /​etc/​postgresql/​9.6/​main/​ 
 +chown $v_cw postgres:​postgres /​etc/​postgresql/​9.6/​main/​*.pem 
 + 
 +# Reload is not enough! Restart is needed. 
 +# Will not be needed from version 10 
 + 
 +systemctl restart postgresql 
 +</​file>​ 
 + 
 +<​code>#​ psql -U postgres ​-c "​SELECT name, setting, sourcefile, sourceline FROM pg_settings WHERE name LIKE '​ssl_%_file'"​ 
 +# or in the file postgresql.conf:​ 
 +# grep '​^\s*ssl_.*_file'​ /​etc/​postgresql/​9.6/​main/​postgresql.conf  
 +</​code>​ 
 + 
 +  ssl_cert_file = '/​etc/​postgresql/​9.6/​main/​fullchain.pem' ​ # (change requires restart) 
 +  ssl_key_file ​ = '/etc/postgresql/9.6/main/​privkey.pem' ​   # (change requires restart)
  
  
 ===== 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 65: 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 ))
/docs/dokuwiki/data/attic/certbot.1569846229.txt.gz · Last modified: 2019-09-30 14:23:49 by mi