Usage: ${0##*/} [OPTIONS] [EXTRA_SETTINGS_FILE] apache2|nginx DOMAIN
apache/nginx config & let's encrypt
If using tls then it expects certbot to be installed and in PATH. Also,
certbot cronjob should be taken care of outside this script. In the
Usage: ${0##*/} [OPTIONS] [EXTRA_SETTINGS_FILE] apache2|nginx DOMAIN
apache/nginx config & let's encrypt
If using tls then it expects certbot to be installed and in PATH. Also,
certbot cronjob should be taken care of outside this script. In the
-debian package, it installs a systemd timer, which I (Ian Kelling) use
-and modify to email me on failure. You can see how I do this in my git
-repo distro-setup, and log-quiet.
+debian package, it installs a systemd timer. If a script exists (I
+expect it only on my , Ian Kelling's sytem) we install a systemd timer
+to on failure. You can see the relevant script in my git repo
+distro-setup, and log-quiet.
+
+
+/a/bin/distro-setup/certbot-renew-hook
+
-f [ADDR:]PORT Enable proxy to [ADDR:]PORT. ADDR default is 127.0.0.1
-i Insecure, no ssl.
-p PORT Main port to listen on, default 443. 80 implies -i.
-f [ADDR:]PORT Enable proxy to [ADDR:]PORT. ADDR default is 127.0.0.1
-i Insecure, no ssl.
-p PORT Main port to listen on, default 443. 80 implies -i.
- case $1 in
- -e) email="$2"; shift 2 ;;
- -f) proxy="$2"; shift 2 ;;
- -i) ssl=false; shift ;;
- -p) port="$2"; shift 2 ;;
- -r) root="$2"; shift 2 ;;
- -s) symlinkarg=+; shift ;;
- --) shift; break ;;
- -h|--help) usage ;;
- *) echo "$0: Internal error!" ; exit 1 ;;
- esac
+ case $1 in
+ -a)
+ listenip="$2:"
+ vhostip="$2"
+ shift 2 ;;
+ -e) email="$2"; shift 2 ;;
+ -f) proxy="$2"; shift 2 ;;
+ -i) ssl=false; shift ;;
+ -p) port="$2"; shift 2 ;;
+ -r) root="$2"; shift 2 ;;
+ -s) symlinkarg=+; shift ;;
+ --) shift; break ;;
+ -h|--help) usage ;;
+ *) echo "$0: Internal error!" ; exit 1 ;;
+ esac
- f=$cert_dir/fullchain.pem
- threedays=259200 # in seconds
- if [[ ! -e $f ]] || ! openssl x509 -checkend $threedays -noout -in $f >/dev/null; then
- # cerbot needs an existing virtualhost.
- $0 -p 80 $t $h
- # when generating an example config, add all relevant security options:
- # --hsts --staple-ocsp --uir --must-staple
- certbot certonly -n --email $email --no-self-upgrade \
- --agree-tos --${t%2} -d $h
- rm $vhost_file
+
+ $this_dir/certbot-setup $t
+
+ f=$cert_dir/fullchain.pem
+ threedays=259200 # in seconds
+ if [[ ! -e $f ]] || ! openssl x509 -checkend $threedays -noout -in $f >/dev/null; then
+ # cerbot needs an existing virtualhost.
+ $0 -p 80 $t $h
+ # when generating an example config, add all relevant security options:
+ # --hsts --staple-ocsp --uir --must-staple
+ certbot certonly -n --email $email --no-self-upgrade \
+ --agree-tos --${t%2} -d $h
+ # cleanup the call to ourselves a short bit ago
+ rm $se/$h.conf
+ fi
+ # these scripts only run on renew, that is kinda dumb.
+ export RENEWED_LINEAGE=/etc/letsencrypt/live/$h
+ for script in /etc/letsencrypt/renewal-hooks/deploy/*; do
+ if [[ -x $script ]]; then
+ "$script"
- rm -f $se/000-default.conf
- # note, we exepct ServerRoot of /etc/apache2
- # apache requires exactly 1 listen directive per port (when no ip is also given),
- # so we have to parse the config to do it programatically.
- listen_80=false
- listen_port=false
- cd /etc/apache2
- conf_files=(apache2.conf)
-
-
- for (( i=0; i < ${#conf_files[@]}; i++ )); do
- f="${conf_files[i]}"
- # note: globs are expanded here.
- conf_files+=( $(sed -rn "s,^\s*Include(Optional)?\s+(\S+).*,\2,p" "$f") )
- case $(readlink -f "$f") in
- $vhost_file|$redir_file) continue ;;
- esac
- for p in $(sed -rn "s,^\s*listen\s+(\S+).*,\1,Ip" "$f"); do
- case $p in
- 80) listen_80=true ;;&
- $port) listen_port=true ;;
- esac
- done
+ rm -f $se/000-default.conf
+ # note, we exepct ServerRoot of /etc/apache2
+ # apache requires exactly 1 listen directive per port (when no ip is also given),
+ # so we have to parse the config to do it programatically.
+ listen_80=false
+ listen_port=false
+ cd /etc/apache2
+ conf_files=(apache2.conf)
+
+
+ for (( i=0; i < ${#conf_files[@]}; i++ )); do
+ f="${conf_files[i]}"
+ # note: globs are expanded here.
+ conf_files+=( $(sed -rn "s,^\s*Include(Optional)?\s+(\S+).*,\2,p" "$f") )
+ case $(readlink -f "$f") in
+ $vhost_file|$redir_file) continue ;;
+ esac
+ for p in $(sed -rn "s,^\s*listen\s+(\S+).*,\1,Ip" "$f"); do
+ case $p in
+ 80) listen_80=true ;;&
+ $port) listen_port=true ;;
+ esac
- # go faster!
- if [[ -e /etc/apache2/mods-available/http2.load ]]; then
- # https://httpd.apache.org/docs/2.4/mod/mod_http2.html
- a2enmod -q http2
- cat >>$vhost_file <<EOF
+ # go faster!
+ if [[ -e /etc/apache2/mods-available/http2.load ]]; then
+ # https://httpd.apache.org/docs/2.4/mod/mod_http2.html
+ a2enmod -q http2
+ cat >>$vhost_file <<EOF
- if [[ $proxy ]]; then
- a2enmod -q proxy proxy_http
- # fyi: trailing slash is important
- # reference: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
- # retry=0: https://stackoverflow.com/questions/683052/why-am-i-getting-an-apache-proxy-503-error
- cat >>$vhost_file <<EOF
+ if [[ $proxy ]]; then
+ a2enmod -q proxy proxy_http
+ # fyi: trailing slash is important
+ # reference: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
+ # retry=0: https://stackoverflow.com/questions/683052/why-am-i-getting-an-apache-proxy-503-error
+ cat >>$vhost_file <<EOF
- echo "$0: creating $redir_file"
- cat >$redir_file <<EOF
+ if (( port == 443 )); then
+ echo "$0: creating $redir_file"
+
+ # note, alternatively:
+ cat >/dev/null <<'EOF'
+#https://webmasters.stackexchange.com/questions/124635/apache-redirect-http-to-https-without-preventing-http
+<If "%{req:Upgrade-Insecure-Requests} == '1'">
+Redirect permanent "/" "https://mydomain.ltd/"
+</If>
+# or, with generic rewrite, we use this on gnu.org
+RewriteEngine on
+RewriteCond %{HTTP:Upgrade-Insecure-Requests} "^1$"
+RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=307]
+EOF
+
+ cat >$redir_file <<EOF
- # this is a copy of a file certbot, see below.
- echo "$0: creating $common_ssl_conf"
- cat >$common_ssl_conf <<'EOF'
+ # this is a copy of a file certbot, see below.
+ echo "$0: creating $common_ssl_conf"
+ cat >$common_ssl_conf <<'EOF'
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
-SSLProtocol all -SSLv2 -SSLv3
-SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
-SSLHonorCipherOrder on
-SSLCompression off
+SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
+SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
+SSLHonorCipherOrder off
+SSLSessionTickets off
SSLOptions +StrictRequire
# Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
SSLOptions +StrictRequire
# Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common
-
-#CustomLog /var/log/apache2/access.log vhost_combined
-#LogLevel warn
-#ErrorLog /var/log/apache2/error.log
-
-# Always ensure Cookies have "Secure" set (JAH 2012/1)
-#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"
- upstream=https://raw.githubusercontent.com/certbot/certbot/master/certbot-apache/certbot_apache/options-ssl-apache.conf
- if ! diff -u <(wget -q -O - $upstream) $common_ssl_conf; then
- cat <<EOF
+ upstream=https://raw.githubusercontent.com/certbot/certbot/master/certbot-apache/certbot_apache/_internal/tls_configs/current-options-ssl-apache.conf
+ if ! diff -u <(wget -q -O - $upstream) $common_ssl_conf; then
+ cat <<EOF
- if ! $listen_port; then
- # reference: https://httpd.apache.org/docs/2.4/mod/mpm_common.html#listen
- cat >>$vhost_file <<EOF
-listen ${port}${https_arg}
+ if ! $listen_port; then
+ # reference: https://httpd.apache.org/docs/2.4/mod/mpm_common.html#listen
+ cat >>$vhost_file <<EOF
+listen ${listenip}${port}${https_arg}
- # I rarely look at how much traffic I get, so let's keep that info
- # around for longer than the default of 2 weeks.
- sed -ri --follow-symlinks 's/^(\s*rotate\s).*/\1 365/' /etc/logrotate.d/apache2
+ # I rarely look at how much traffic I get, so let's keep that info
+ # around for longer than the default of 2 weeks.
+ sed -ri --follow-symlinks 's/^(\s*rotate\s).*/\1 365/' /etc/logrotate.d/apache2
- common_ssl_conf=/etc/nginx/common-ssl.conf
-
- rm -f $se/default
- cd /etc/nginx
- [[ -e dh2048.pem ]] || openssl dhparam -out dh2048.pem 2048
-
- if $ssl; then
- ssl_arg=ssl
- if nginx -V |& grep -- '--with-http_v2_module\b' &>/dev/null; then
- # fun fact: nginx can be configured to do http2 without ssl.
- ssl_arg+=" http2"
- fi
+ common_ssl_conf=/etc/nginx/common-ssl.conf
+
+ rm -f $se/default
+ cd /etc/nginx
+ [[ -e dh2048.pem ]] || openssl dhparam -out dh2048.pem 2048
+
+ if $ssl; then
+ ssl_arg=ssl
+ if nginx -V |& grep -- '--with-http_v2_module\b' &>/dev/null; then
+ # fun fact: nginx can be configured to do http2 without ssl.
+ ssl_arg+=" http2"
# let's encrypt gives us a bad nginx config, so use this:
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# using modern config. last checked 2017/4/22
# let's encrypt gives us a bad nginx config, so use this:
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# using modern config. last checked 2017/4/22
# ian: commented out, our local dns is expected to work fine.
#resolver <IP DNS resolver>;
EOF
# ian: commented out, our local dns is expected to work fine.
#resolver <IP DNS resolver>;
EOF
ssl_certificate $cert_dir/fullchain.pem;
ssl_certificate_key $cert_dir/privkey.pem;
include $common_ssl_conf;
EOF
ssl_certificate $cert_dir/fullchain.pem;
ssl_certificate_key $cert_dir/privkey.pem;
include $common_ssl_conf;
EOF