-
Notifications
You must be signed in to change notification settings - Fork 9
/
secure_nginx_on_Ubuntu_16_04_with_ssl_using_letsencrypt
executable file
·182 lines (156 loc) · 7.32 KB
/
secure_nginx_on_Ubuntu_16_04_with_ssl_using_letsencrypt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/bin/bash -eu
# Setup script for a web server using nginx secured by letsencrypt ssl
# on Ubuntu 16.04-64 (in this case Digital Ocean droplet)
# Essentially automates the process shown in this tutorial:
# https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04
# Assumes you already have a secured machine and user with sudo privileges
# as per https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04
# Requires a bit of interaction; it is theoretically possible to automate the
# answers to the letsencrypt prompts using Expect, but a huge hassle. Better
# to stick around and answer the questions.
echo
echo Welcome to an automated web server securing process. Please stick around!
echo You will need to answer some questions from the letsencrypt prompts.
echo This procedure is based on, and more or less automates, the tutorial here:
echo https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04
echo
count=0
var="arg$count"
echo Please enter your domain name
read arg$count
echo
echo Please enter any subdomain names you may have.
echo Don\'t include the domain name, only the prefix,
echo For example, to include sub.example.com on your certificate, just type sub
# horrible way to get a list of subdomains without knowing how many beforehand
while [ ! -z ${!var} ]; do
let count=count+1
var="arg$count"
read arg$count
if [ ! -z ${!var} ]; then
echo If you have more subdomains, please enter them. If not, just press enter!
fi
done
# Echo the domain name and list of all subdomains back to the user for confirmation
subdomains=$((count-1))
domain_name=$arg0
echo it looks like you have domain $domain_name and $subdomains subdomains:
readcount=1
var="arg$readcount"
while [ ! -z ${!var} ]; do
let readcount=readcount+1
echo "${!var}.$domain_name"
var="arg$readcount"
done
# Quit if the user is not happy with the domain name and list of subdomains
echo
read -p "is this correct? (y/n)" -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
exit 1
fi
echo
echo what email address do you want to use for your letsencrypt cert?
read email
echo updating distro
sudo apt -y update
sudo apt -y upgrade
# Install Nginx as per https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04
if ! type "nginx"; then
echo installing nginx
sudo apt install -y nginx
else echo Nginx seems to be already installed
fi
echo allowing nginx through the UFW firewall
sudo ufw allow 'Nginx HTTP'
# Secure Nginx for HTTPS traffic using LetsEncrypt as per https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04
if ! type "letsencrypt"; then
echo installing letsencrypt
sudo apt install -y letsencrypt
else echo letsencrypt seems to be already installed
fi
# Add a location to the nginx config, don't do twice (if-fi) and make a backup
if [ ! -f /etc/nginx/sites-available/defaultBAK ] ; then
echo backing up /etc/nginx/sites-available/default
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/defaultBAK
echo adding location block to /etc/nginx/sites-available/default
sudo sed -i '0,/server {/s/server {/server {\n location ~ \/.well-known {\n allow all;\n }/' /etc/nginx/sites-available/default
else echo there seems to already be a backup of /etc/nginx/sites-available/default, which probably means this script has already been run. Not modifying the file.
fi
echo restarting Nginx
sudo systemctl restart nginx
if [ ! -d /etc/letsencrypt/live ]; then
echo running letsencrypt
#TODO add all the subdomains to this command
sudo letsencrypt certonly -n -v --agree-tos -m $email -a webroot --webroot-path=/var/www/html -d $domain_name -d www.$domain_name
echo backing up letsencrypt folder
sudo cp -r /etc/letsencrypt/live/ /etc/letsencrypt/liveBAK
else echo it looks like letsencrypt has already been run!
fi
echo doing whatever openssl dhparam does
if [ ! -f /etc/ssl/certs/dhparam.pem ]; then
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
fi
if [ ! -f /etc/nginx/snippets/ssl-$domain_name.conf ]; then
echo creating snippet to configure nginx with new cert
echo "ssl_certificate /etc/letsencrypt/live/$domain_name/fullchain.pem;" > sslconf
echo "ssl_certificate_key /etc/letsencrypt/live/$domain_name/privkey.pem;" >> sslconf
sudo mv sslconf /etc/nginx/snippets/ssl-$domain_name.conf
else echo it looks like the snippets have already been created
fi
if [ ! -f /etc/nginx/snippets/ssl-params.conf ]; then
echo creating ssl-params.conf
cat > ssl-params.conf <<EOF
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
EOF
sudo mv ssl-params.conf /etc/nginx/snippets/ssl-params.conf
else echo the ssl-params file already exists
fi
if [ ! -f /etc/nginx/sites-available/defaultBAK2 ]; then
echo Backing up /etc/nginx/sites-available/default
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/defaultBAK2
sudo sed -i "0,/server_name _;/s/server_name _;/server_name $domain_name www.$domain_name;\n return 301 https:\/\/\$server_name\$request_uri;/" /etc/nginx/sites-available/default
echo "server {" | sudo tee -a /etc/nginx/sites-available/default
echo " listen 443 ssl http2 default_server;" | sudo tee -a /etc/nginx/sites-available/default
echo " listen [::]:443 ssl http2 default_server;" | sudo tee -a /etc/nginx/sites-available/default
echo " include snippets/ssl-$domain_name.conf;" | sudo tee -a /etc/nginx/sites-available/default
echo " include snippets/ssl-params.conf;" | sudo tee -a /etc/nginx/sites-available/default
echo "}" | sudo tee -a /etc/nginx/sites-available/default
else echo the server name is already set
fi
echo allowing nginx full and disallowing http
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
echo restarting nginx
sudo systemctl restart nginx
echo
echo ****************************************************************
echo You should probably set up a cron job to renew your certificate.
echo as described at the end of this tutorial:
echo https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04
echo ****************************************************************
echo
echo To see if the installation worked, open $domain_name from a browser
echo and see if you see the nginx welcome page. The address bar should show
echo https://$domain_name
echo even if you only enter $domain_name
echo
echo The nginx welcome page lives at /usr/share/nginx/html/index.html