f66b40c86b40db48d0601a287abe2f7dcecbaaa8
[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 -p PORT Port to listen on, default 443
35 -f PORT Enable proxy to PORT on localhost
36 -r 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 proxy_port=
54 extra_settings=
55 temp=$(getopt -l help: c:f:p:r:h "$@") || usage 1
56 eval set -- "$temp"
57 while true; do
58 case $1 in
59 -c) cert_dir="$2"; shift 2 ;;
60 -p) port="$2"; shift 2 ;;
61 -f) proxy_port="$2"; shift 2 ;;
62 -r) root="$2"; shift 2 ;;
63 --) shift; break ;;
64 -h|--help) usage ;;
65 *) echo "$0: Internal error!" ; exit 1 ;;
66 esac
67 done
68
69 if (( ${#@} == 2 )); then
70 read -r extra_settings h <<<"${@}"
71 else
72 read -r h <<<"${@}"
73 fi
74
75 if [[ ! $h ]]; then
76 echo "$0: error: expected domain arg"
77 usage 1
78 fi
79
80 if [[ ! $root ]]; then
81 root=/var/www/$h/html
82 fi
83
84
85 ##### end command line parsing ########
86
87 sudo rm -f /etc/nginx/sites-enabled/default
88
89 if nginx -V |& grep -- '--with-http_v2_module\b' &>/dev/null; then
90 http2_arg=http2
91 fi
92
93 sudo dd of=/etc/nginx/sites-enabled/$h.conf <<EOF
94 # ssecurty settings taken from
95 # https://mozilla.github.io/server-side-tls/ssl-config-generator/
96 # using modern config. last checked 2017/2/20
97 server {
98 server_name $h www.$h;
99 root $root;
100 listen $port ssl $http2_arg;
101 listen [::]:$port ssl $http2_arg;
102
103 # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
104 ssl_certificate $cert_dir/$h-chained.pem;
105 ssl_certificate_key $cert_dir/$h-domain.key;
106 ssl_session_timeout 1d;
107 ssl_session_cache shared:SSL:50m;
108 ssl_session_tickets off;
109
110 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
111 ssl_dhparam $cert_dir/dh2048.pem;
112
113 # modern configuration. tweak to your needs.
114 ssl_protocols TLSv1.2;
115 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';
116 ssl_prefer_server_ciphers on;
117
118 # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
119 add_header Strict-Transport-Security max-age=15768000;
120
121 # OCSP Stapling ---
122 # fetch OCSP records from URL in ssl_certificate and cache them
123 ssl_stapling on;
124 ssl_stapling_verify on;
125
126 # ian: todo: something is missing here, stapling is not enabled
127 # per ssllabs.com test. need to put root cert in chain?.
128 # ssl labs still says we are A+.
129 # https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
130 ## verify chain of trust of OCSP response using Root CA and Intermediate certs
131 ssl_trusted_certificate $cert_dir/$h-chained.pem;
132
133 # ian: left commented out, our local dns is expected to work fine.
134 #resolver <IP DNS resolver>;
135 EOF
136 if [[ $extra_settings ]]; then
137 cat $extra_settings | sudo tee -a /etc/nginx/sites-enabled/$h.conf
138 fi
139
140 if [[ $proxy_port ]]; then
141 sudo tee -a /etc/nginx/sites-enabled/$h.conf <<EOF
142 location / {
143 proxy_set_header Host \$host;
144 proxy_set_header X-Real-IP \$remote_addr;
145 proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
146 proxy_set_header X-Forwarded-Ssl on;
147 proxy_set_header X-Forwarded-Port $port;
148 proxy_pass http://127.0.0.1:$proxy_port;
149 }
150 EOF
151 fi
152
153
154 sudo tee -a /etc/nginx/sites-enabled/$h.conf <<EOF
155 }
156 EOF
157 sudo mkdir -p /var/www/$h/html
158 sudo chown -R ian:ian /var/www/$h
159 sudo service nginx restart