addd1d4a277740f60e683f1d5be529844ab72be9
[basic-https-conf] / nginx-site
1 #!/bin/bash
2 # Copyright (C) 2016 Ian Kelling
3
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 [[ $EUID == 0 ]] || exec sudo -E "$BASH_SOURCE" "$@"
17
18 set -eE -o pipefail
19 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
20
21
22 usage() {
23 cat <<EOF
24 Usage: ${0##*/} [OPTIONS] [EXTRA_SETTINGS_FILE] DOMAIN
25 Note: this is less tested and mature than the apache site script.
26
27 Setup nginx config with https using
28 ssl config provided by let's encrypt and my standard
29 location for storing certs.
30
31 EXTRA_SETTINGS_FILE can be - for stdin
32 -c CERT_DIR In priority: this arg, $ACME_TINY_WRAPPER_CERT_DIR,
33 $HOME/webservercerts, if the other options aren't set.
34 -f [ADDR:]PORT Enable proxy to [ADDR:]PORT. ADDR default is 127.0.0.1
35 -p PORT Port to listen on, default 443
36 -r DIR DocumentRoot
37 -h|--help Print help and exit
38
39 TODO: add https redir site.
40
41 Note: Uses GNU getopt options parsing style
42 EOF
43 exit $1
44 }
45
46 ##### begin command line parsing ########
47
48 cert_dir="$ACME_TINY_WRAPPER_CERT_DIR"
49 if [[ ! $cert_dir ]]; then
50 cert_dir=$HOME/webservercerts
51 fi
52 port=443
53 extra_settings=
54 temp=$(getopt -l help: c:f:p:r:h "$@") || usage 1
55 eval set -- "$temp"
56 while true; do
57 case $1 in
58 -c) cert_dir="$2"; shift 2 ;;
59 -f) proxy="$2"; shift 2 ;;
60 -p) port="$2"; shift 2 ;;
61 -r) root="$2"; shift 2 ;;
62 --) shift; break ;;
63 -h|--help) usage ;;
64 *) echo "$0: Internal error!" ; exit 1 ;;
65 esac
66 done
67
68 if (( ${#@} == 2 )); then
69 read -r extra_settings h <<<"${@}"
70 else
71 read -r h <<<"${@}"
72 fi
73
74 if [[ ! $h ]]; then
75 echo "$0: error: expected domain arg"
76 usage 1
77 fi
78
79 if [[ ! $root ]]; then
80 root=/var/www/$h/html
81 fi
82
83 if [[ $proxy ]]; then
84 [[ $proxy == *:* ]] || proxy=127.0.0.1:$proxy
85 fi
86
87
88 ##### end command line parsing ########
89
90 rm -f /etc/nginx/sites-enabled/default
91
92 if nginx -V |& grep -- '--with-http_v2_module\b' &>/dev/null; then
93 http2_arg=http2
94 fi
95
96 echo "$0: creating /etc/nginx/sites-enabled/$h.conf"
97 cat >/etc/nginx/sites-enabled/$h.conf <<EOF
98 # ssecurty settings taken from
99 # https://mozilla.github.io/server-side-tls/ssl-config-generator/
100 # using modern config. last checked 2017/2/20
101 server {
102 server_name $h www.$h;
103 root $root;
104 listen $port ssl $http2_arg;
105 listen [::]:$port ssl $http2_arg;
106
107 # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
108 ssl_certificate $cert_dir/$h-chained.pem;
109 ssl_certificate_key $cert_dir/$h-domain.key;
110 ssl_session_timeout 1d;
111 ssl_session_cache shared:SSL:50m;
112 ssl_session_tickets off;
113
114 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
115 ssl_dhparam $cert_dir/dh2048.pem;
116
117 # modern configuration. tweak to your needs.
118 ssl_protocols TLSv1.2;
119 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';
120 ssl_prefer_server_ciphers on;
121
122 # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
123 add_header Strict-Transport-Security max-age=15768000;
124
125 # OCSP Stapling ---
126 # fetch OCSP records from URL in ssl_certificate and cache them
127 ssl_stapling on;
128 ssl_stapling_verify on;
129
130 # ian: todo: something is missing here, stapling is not enabled
131 # per ssllabs.com test. need to put root cert in chain?.
132 # ssl labs still says we are A+.
133 # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
134 ## verify chain of trust of OCSP response using Root CA and Intermediate certs
135 ssl_trusted_certificate $cert_dir/$h-chained.pem;
136
137 # ian: left commented out, our local dns is expected to work fine.
138 #resolver <IP DNS resolver>;
139 EOF
140 if [[ $extra_settings ]]; then
141 cat $extra_settings >>/etc/nginx/sites-enabled/$h.conf
142 fi
143
144 if [[ $proxy ]]; then
145 cat >>/etc/nginx/sites-enabled/$h.conf <<EOF
146 location / {
147 proxy_set_header Host \$host;
148 proxy_set_header X-Real-IP \$remote_addr;
149 proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
150 proxy_set_header X-Forwarded-Ssl on;
151 proxy_set_header X-Forwarded-Port $port;
152 proxy_pass http://$proxy;
153 }
154 EOF
155 fi
156
157
158 cat >>/etc/nginx/sites-enabled/$h.conf <<EOF
159 }
160 EOF
161 mkdir -p /var/www/$h/html
162 chown -R ian:ian /var/www/$h
163 service nginx restart