-apache/nginx site automation
+apache/nginx config & let's encrypt
-Uses let's encrypt's https settings, plus a small bit of extra settings,
-and accepts site specific settings in stdin. More focused on apache,
-nginx is missing some features in the apache script.
+The main documentation is availiable via --help and near the top of the
+bash script file next to this file.
Please email me if you have a patches, bugs, feedback, or republish this
somewhere else: Ian Kelling <ian@iankelling.org>.
+++ /dev/null
-#!/bin/bash
-# Copyright (C) 2016 Ian Kelling
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
-
-set -eE -o pipefail
-trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
-
-shopt -s nullglob # used in apache config file expansion
-
-usage() {
- cat <<EOF
-Usage: ${0##*/} [OPTIONS] [EXTRA_SETTINGS_FILE] DOMAIN
-Setup apache virtualhost config with https using
-ssl config provided by let's encrypt and my standard
-location for storing certs.
-
-EXTRA_SETTINGS_FILE can be - for stdin
--c CERT_DIR In priority: this arg, $ACME_TINY_WRAPPER_CERT_DIR,
- $HOME/webservercerts, if the other options aren't set.
--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.
--r DIR DocumentRoot
--h|--help Print help and exit
-
-Note: Uses GNU getopt options parsing style
-EOF
- exit $1
-}
-
-##### begin command line parsing ########
-
-cert_dir="$ACME_TINY_WRAPPER_CERT_DIR"
-if [[ ! $cert_dir ]]; then
- cert_dir=$HOME/webservercerts
-fi
-ssl=true
-extra_settings=
-port=443
-temp=$(getopt -l help ic:f:p:r:h "$@") || usage 1
-eval set -- "$temp"
-while true; do
- case $1 in
- -c) cert_dir="$2"; shift 2 ;;
- -f) proxy="$2"; shift 2 ;;
- -i) ssl=false; shift ;;
- -p) port="$2"; shift 2 ;;
- -r) root="$2"; shift 2 ;;
- --) shift; break ;;
- -h|--help) usage ;;
- *) echo "$0: Internal error!" ; exit 1 ;;
- esac
-done
-
-if (( ${#@} == 2 )); then
- read -r extra_settings h <<<"${@}"
-else
- read -r h <<<"${@}"
-fi
-
-if [[ ! $h ]]; then
- echo "$0: error: expected domain arg"
- usage 1
-fi
-
-if [[ ! $root ]]; then
- root=/var/www/$h/html
-fi
-
-if [[ $proxy ]]; then
- [[ $proxy == *:* ]] || proxy=127.0.0.1:$proxy
-fi
-
-
-##### end command line parsing ########
-
-# taken from the let's encrypt generated site, using
-# ./certbot-auto --apache (should use the test mode to check if there are updates)
-# on 5/29/2016
-
-# I could have also used the mozilla generator this, but it had some open issues
-# with no response
-# so I figured I would check out let's encrypt.
-# It's a little more liberal, but still get's an A in ssl labs,
-# so, meh, I'll use it.
-# https://mozilla.github.io/server-side-tls/ssl-config-generator/
-
-
-rm -f /etc/apache2/sites-enabled/000-default.conf
-
-mkdir -p $root
-vhost_file=/etc/apache2/sites-enabled/$h.conf
-redir_file=/etc/apache2/sites-enabled/httpsredir.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)
-
-
-if [[ $port == 80 ]]; then
- ssl=false
- # remove any thats hanging around
- rm -f $redir_file
-fi
-
-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
-done
-
-if $ssl; then
- https_arg=" https"
-fi
-
-
-echo "$0: creating $vhost_file"
-cat >$vhost_file <<EOF
-<VirtualHost *:$port>
- ServerName $h
- ServerAlias www.$h
- DocumentRoot $root
-EOF
-
-if [[ $extra_settings ]]; then
- cat -- $extra_settings >>$vhost_file
-fi
-
-# go faster!
-if [[ -e /etc/apache2/mods-available/http2.load ]]; then
- # https://httpd.apache.org/docs/2.4/mod/mod_http2.html
- a2enmod http2
- cat >>$vhost_file <<EOF
- Protocols h2 http/1.1
-EOF
-fi
-
-if [[ $proxy ]]; then
- a2enmod proxy proxy_http
- # fyi: trailing slash is important
- # reference: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
- cat >>$vhost_file <<EOF
- ProxyPass "/" "http://$proxy/"
- ProxyPassReverse "/" "http://$proxy/"
-EOF
-fi
-
-
-
-if $ssl; then
- certbot_ssl_conf=/etc/apache2/apache-site-ssl.conf
- cat >>$vhost_file <<EOF
- SSLCertificateFile $cert_dir/$h-chained.pem
- SSLCertificateKeyFile $cert_dir/$h-domain.key
- Include $certbot_ssl_conf
-EOF
-
- # if we are using a non-standard port, setup don't setup
- # irrelevant 443 redirect.
- if [[ $port == "443" ]]; then
- echo "$0: creating $redir_file"
- cat >$redir_file <<'EOF'
-# vhost_combined with %D (request time in microseconds)
-# this file is just a convenient place to drop it.
-LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %D" vhost_time_combined
-<VirtualHost *:80>
- ServerAdmin webmaster@localhost
- DocumentRoot /var/www/html
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
- CustomLog ${APACHE_LOG_DIR}/httpsredir-access.log combined
-
-RewriteEngine on
-# ian: removed so it's for all sites
-#RewriteCond %{SERVER_NAME} =certbot.iank.bid
-RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
-</VirtualHost>
-EOF
- if ! $listen_80; then
- cat >>$redir_file <<'EOF'
-Listen 80
-EOF
- fi
- fi
-
- mkdir -p /etc/letsencrypt
-
- # this is from cerbot, see below.
- echo "$0: creating $certbot_ssl_conf"
- cat >$certbot_ssl_conf <<'EOF'
-# Baseline setting to Include for SSL sites
-
-SSLEngine on
-
-# Intermediate configuration, tweak to your needs
-SSLProtocol all -SSLv2 -SSLv3
-SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
-SSLHonorCipherOrder on
-SSLCompression 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
-
-#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"
-EOF
-
- upstream=https://github.com/certbot/certbot/raw/master/certbot-apache/certbot_apache/options-ssl-apache.conf
- if ! diff -c <(wget -q -O - $upstream) $certbot_ssl_conf; then
- cat <<EOF
-WARNING!!!!!!!!!
-WARNING!!!!!!!!!
-WARNING!!!!!!!!!
-WARNING!!!!!!!!!
-WARNING!!!!!!!!!
-upstream ssl settings differ from the snapshot we have taken!!!
-We diffed with this command:
-diff -c <(wget -q -O - $upstream) $certbot_ssl_conf
-Update this script to take care this warning!!!!!
-EOF
- sleep 1
- fi
-fi # end if $ssl
-
-cat >>$vhost_file <<EOF
- ErrorLog \${APACHE_LOG_DIR}/error.log
- CustomLog \${APACHE_LOG_DIR}/access.log vhost_time_combined
-</VirtualHost>
-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}
-EOF
-fi
-
-
-a2enmod ssl rewrite # rewrite needed for httpredir
-service apache2 restart
-
-# 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
+++ /dev/null
-#!/bin/bash
-# Copyright (C) 2016 Ian Kelling
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-
-# http://www.apache.org/licenses/LICENSE-2.0
-
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
-
-set -eE -o pipefail
-trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
-
-
-usage() {
- cat <<EOF
-Usage: ${0##*/} [OPTIONS] [EXTRA_SETTINGS_FILE] DOMAIN
-Note: this is less tested and mature than the apache site script.
-
-Setup nginx config with https using
-ssl config provided by let's encrypt and my standard
-location for storing certs.
-
-EXTRA_SETTINGS_FILE can be - for stdin
--c CERT_DIR In priority: this arg, $ACME_TINY_WRAPPER_CERT_DIR,
- $HOME/webservercerts, if the other options aren't set.
--f [ADDR:]PORT Enable proxy to [ADDR:]PORT. ADDR default is 127.0.0.1
--p PORT Port to listen on, default 443
--r DIR DocumentRoot
--h|--help Print help and exit
-
-TODO: add https redir site.
-
-Note: Uses GNU getopt options parsing style
-EOF
- exit $1
-}
-
-##### begin command line parsing ########
-
-cert_dir="$ACME_TINY_WRAPPER_CERT_DIR"
-if [[ ! $cert_dir ]]; then
- cert_dir=$HOME/webservercerts
-fi
-port=443
-extra_settings=
-temp=$(getopt -l help: c:f:p:r:h "$@") || usage 1
-eval set -- "$temp"
-while true; do
- case $1 in
- -c) cert_dir="$2"; shift 2 ;;
- -f) proxy="$2"; shift 2 ;;
- -p) port="$2"; shift 2 ;;
- -r) root="$2"; shift 2 ;;
- --) shift; break ;;
- -h|--help) usage ;;
- *) echo "$0: Internal error!" ; exit 1 ;;
- esac
-done
-
-if (( ${#@} == 2 )); then
- read -r extra_settings h <<<"${@}"
-else
- read -r h <<<"${@}"
-fi
-
-if [[ ! $h ]]; then
- echo "$0: error: expected domain arg"
- usage 1
-fi
-
-if [[ ! $root ]]; then
- root=/var/www/$h/html
-fi
-
-if [[ $proxy ]]; then
- [[ $proxy == *:* ]] || proxy=127.0.0.1:$proxy
-fi
-
-
-##### end command line parsing ########
-
-rm -f /etc/nginx/sites-enabled/default
-
-if nginx -V |& grep -- '--with-http_v2_module\b' &>/dev/null; then
- http2_arg=http2
-fi
-
-echo "$0: creating /etc/nginx/sites-enabled/$h.conf"
-cat >/etc/nginx/sites-enabled/$h.conf <<EOF
-# ssecurty settings taken from
-# https://mozilla.github.io/server-side-tls/ssl-config-generator/
-# using modern config. last checked 2017/2/20
-server {
- server_name $h www.$h;
- root $root;
- listen $port ssl $http2_arg;
- listen [::]:$port ssl $http2_arg;
-
- # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
- ssl_certificate $cert_dir/$h-chained.pem;
- ssl_certificate_key $cert_dir/$h-domain.key;
- ssl_session_timeout 1d;
- ssl_session_cache shared:SSL:50m;
- ssl_session_tickets off;
-
- # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
- ssl_dhparam $cert_dir/dh2048.pem;
-
- # modern configuration. tweak to your needs.
- ssl_protocols TLSv1.2;
- ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
- ssl_prefer_server_ciphers on;
-
- # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
- add_header Strict-Transport-Security max-age=15768000;
-
- # OCSP Stapling ---
- # fetch OCSP records from URL in ssl_certificate and cache them
- ssl_stapling on;
- ssl_stapling_verify on;
-
- # ian: todo: something is missing here, stapling is not enabled
- # per ssllabs.com test. need to put root cert in chain?.
- # ssl labs still says we are A+.
- # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
- ## verify chain of trust of OCSP response using Root CA and Intermediate certs
- ssl_trusted_certificate $cert_dir/$h-chained.pem;
-
- # ian: left commented out, our local dns is expected to work fine.
- #resolver <IP DNS resolver>;
-EOF
-if [[ $extra_settings ]]; then
- cat $extra_settings >>/etc/nginx/sites-enabled/$h.conf
-fi
-
-if [[ $proxy ]]; then
- cat >>/etc/nginx/sites-enabled/$h.conf <<EOF
- location / {
- proxy_set_header Host \$host;
- proxy_set_header X-Real-IP \$remote_addr;
- proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Ssl on;
- proxy_set_header X-Forwarded-Port $port;
- proxy_pass http://$proxy;
- }
-EOF
-fi
-
-
-cat >>/etc/nginx/sites-enabled/$h.conf <<EOF
-}
-EOF
-mkdir -p /var/www/$h/html
-chown -R ian:ian /var/www/$h
-service nginx restart
--- /dev/null
+#!/bin/bash
+# Copyright (C) 2016 Ian Kelling
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+[[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+shopt -s nullglob # used in apache config file expansion
+
+usage() {
+ cat <<EOF
+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.
+
+
+EXTRA_SETTINGS_FILE can be - for stdin
+-e EMAIL Contact address for let's encrypt. Default is
+ root@\$(hostname -A|awk '{print $1}')
+ which is root@$(hostname -A|awk '{print $1}') on this host.
+-f [ADDR:]PORT Enable proxy to [ADDR:]PORT. ADDR default is 127.0.0.1
+-i Insecure, no ssl. Not implemented for nginx.
+-p PORT Main port to listen on, default 443. 80 implies -i.
+-r DIR DocumentRoot
+-h|--help Print help and exit
+
+Note: Uses GNU getopt options parsing style
+EOF
+ exit $1
+}
+
+##### begin command line parsing ########
+
+ssl=true
+extra_settings=
+port=443
+temp=$(getopt -l help e:i:f:p:r:h "$@") || usage 1
+eval set -- "$temp"
+while true; do
+ 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 ;;
+ --) shift; break ;;
+ -h|--help) usage ;;
+ *) echo "$0: Internal error!" ; exit 1 ;;
+ esac
+done
+
+if (( ${#@} == 3 )); then
+ read -r extra_settings t h <<<"${@}"
+else
+ read -r t h <<<"${@}"
+fi
+
+case $t in
+ apache2|nginx) : ;;
+ *) echo "$0: error: expected apache2 or nginx arg"; usage 1 ;;
+esac
+
+if [[ ! $h ]]; then
+ echo "$0: error: expected domain and type arg"
+ usage 1
+fi
+
+if [[ ! $root ]]; then
+ root=/var/www/$h/html
+fi
+
+if [[ $proxy ]]; then
+ [[ $proxy == *:* ]] || proxy=127.0.0.1:$proxy
+fi
+
+if [[ ! $email ]]; then
+ email=root@$(hostname -A|awk '{print $1}')
+fi
+
+
+##### end command line parsing ########
+
+se=/etc/$t/sites-enabled
+cert_dir=/etc/letsencrypt/live/$h
+
+mkdir -p $root
+vhost_file=$se/$h.conf
+redir_file=$se/$h-redir.conf
+
+if [[ $port == 80 ]]; then
+ ssl=false
+ # remove any thats hanging around
+ rm -f $redir_file
+fi
+
+
+if $ssl; then
+ f=$cert_dir/fullchain.pem
+ if [[ ! -e $f ]] || openssl x509 -checkend 86400 -noout -in $f; then
+ $0 -p 80 $t $h
+ # adds every security option
+ certbot certonly -n --hsts --staple-ocsp --uir --must-staple --email $email --staple-ocsp --no-self-upgrade --agree-tos --apache -d $h
+ rm $vhost_file
+ fi
+fi
+
+
+if [[ $t == apache2 ]]; then
+ 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
+ echo "$f"
+ 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
+ done
+
+
+ cat >$vhost_file <<EOF
+<VirtualHost *:$port>
+ ServerName $h
+ ServerAlias www.$h
+ DocumentRoot $root
+EOF
+
+ if [[ $extra_settings ]]; then
+ cat -- $extra_settings >>$vhost_file
+ fi
+
+ # go faster!
+ if [[ -e /etc/apache2/mods-available/http2.load ]]; then
+ # https://httpd.apache.org/docs/2.4/mod/mod_http2.html
+ a2enmod http2
+ cat >>$vhost_file <<EOF
+ Protocols h2 http/1.1
+EOF
+ fi
+
+ if [[ $proxy ]]; then
+ a2enmod proxy proxy_http
+ # fyi: trailing slash is important
+ # reference: https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html
+ cat >>$vhost_file <<EOF
+ ProxyPass "/" "http://$proxy/"
+ ProxyPassReverse "/" "http://$proxy/"
+EOF
+ fi
+
+
+
+ if $ssl; then
+ https_arg=" https"
+ common_ssl_conf=/etc/apache2/common-ssl.conf
+ cat >>$vhost_file <<EOF
+ SSLCertificateFile $cert_dir/fullchain.pem
+ SSLCertificateKeyFile $cert_dir/privkey.pem
+ Include $common_ssl_conf
+ # From cerbot generated config example, taken 4/2017,
+ # should be rechecked once a year or so.
+ Header always set Strict-Transport-Security "max-age=31536000"
+ SSLUseStapling on
+ Header always set Content-Security-Policy upgrade-insecure-requests
+EOF
+
+ cat >/etc/apache2/conf-enabled/local-custom.conf <<'EOF'
+# vhost_combined with %D (request time in microseconds)
+# this file is just a convenient place to drop it.
+LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %D" vhost_time_combined
+SSLStaplingCache shmcb:/var/run/apache2/stapling_cache(128000)
+EOF
+
+ echo "$0: creating $redir_file"
+ cat >$redir_file <<EOF
+<VirtualHost *:80>
+ ServerName $h
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www/html
+
+ ErrorLog \${APACHE_LOG_DIR}/error.log
+ CustomLog \${APACHE_LOG_DIR}/access.log vhost_time_combined
+
+ RewriteEngine on
+ RewriteCond %{SERVER_NAME} =$h
+ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
+</VirtualHost>
+EOF
+ if ! $listen_80; then
+ cat >>$redir_file <<'EOF'
+Listen 80
+EOF
+ fi
+
+ # this is a copy of a file certbot, see below.
+ echo "$0: creating $common_ssl_conf"
+ cat >$common_ssl_conf <<'EOF'
+# Baseline setting to Include for SSL sites
+
+SSLEngine on
+
+# Intermediate configuration, tweak to your needs
+SSLProtocol all -SSLv2 -SSLv3
+SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
+SSLHonorCipherOrder on
+SSLCompression 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
+
+#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"
+EOF
+
+ upstream=https://github.com/certbot/certbot/raw/master/certbot-apache/certbot_apache/options-ssl-apache.conf
+ if ! diff -c <(wget -q -O - $upstream) $common_ssl_conf; then
+ cat <<EOF
+WARNING!!!!!!!!!
+WARNING!!!!!!!!!
+WARNING!!!!!!!!!
+WARNING!!!!!!!!!
+WARNING!!!!!!!!!
+upstream ssl settings differ from the snapshot we have taken!!!
+We diffed with this command:
+diff -c <(wget -q -O - $upstream) $common_ssl_conf
+Update this script to take care this warning!!!!!
+EOF
+ sleep 1
+ fi
+ fi # end if $ssl
+
+ cat >>$vhost_file <<'EOF'
+ ErrorLog ${APACHE_LOG_DIR}/error.log
+ CustomLog ${APACHE_LOG_DIR}/access.log vhost_time_combined
+</VirtualHost>
+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}
+EOF
+ fi
+
+
+ a2enmod ssl rewrite # rewrite needed for httpredir
+ service apache2 restart
+
+ # 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
+fi ###### end if apache
+
+if [[ $t == nginx ]]; then
+ 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 nginx -V |& grep -- '--with-http_v2_module\b' &>/dev/null; then
+ http2_arg=http2
+ fi
+
+ cat >$common_ssl_conf <<'EOF'
+# 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
+ssl_session_timeout 1d;
+ssl_session_cache shared:SSL:50m;
+ssl_session_tickets off;
+
+# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
+ssl_dhparam /etc/nginx/dh2048.pem;
+
+# modern configuration. tweak to your needs.
+ssl_protocols TLSv1.2;
+ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
+ssl_prefer_server_ciphers on;
+
+# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
+add_header Strict-Transport-Security max-age=15768000;
+
+# OCSP Stapling ---
+# fetch OCSP records from URL in ssl_certificate and cache them
+ssl_stapling on;
+ssl_stapling_verify on;
+
+## verify chain of trust of OCSP response using Root CA and Intermediate certs
+# ian: commented out, unnecessary for le certs or my nginx ver.
+#ssl_trusted_certificate $cert_dir/fullchain.pem;;
+
+# ian: commented out, our local dns is expected to work fine.
+#resolver <IP DNS resolver>;
+EOF
+ cat >$vhost_file <<EOF
+server {
+ server_name $h www.$h;
+ root $root;
+ listen $port ssl $http2_arg;
+ listen [::]:$port ssl $http2_arg;
+
+ # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
+ ssl_certificate $cert_dir/fullchain.pem;
+ ssl_certificate_key $cert_dir/privkey.pem;
+ include $common_ssl_conf;
+EOF
+ if [[ $extra_settings ]]; then
+ cat $extra_settings >>$vhost_file
+ fi
+
+ if [[ $proxy ]]; then
+ cat >>$vhost_file <<EOF
+ location / {
+ proxy_set_header Host \$host;
+ proxy_set_header X-Real-IP \$remote_addr;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Ssl on;
+ proxy_set_header X-Forwarded-Port $port;
+ proxy_pass http://$proxy;
+ }
+EOF
+ fi
+
+ cat >>$vhost_file <<EOF
+}
+EOF
+
+ cat >$redir_file <<EOF
+server {
+ server_name $h www.$h;
+ listen 80 $http2_arg;
+ listen [::]:80 $http2_arg;
+ return 301 https://$server_name$request_uri;
+}
+EOF
+
+ service nginx restart
+
+fi ####### end if nginx