-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlets-nginx-proxy.py
executable file
·175 lines (149 loc) · 5.81 KB
/
lets-nginx-proxy.py
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
#!/usr/bin/env python
import os
import sys
import subprocess
import random
random_min = random.randrange(1,59)
print('''
Welcome to the add https to a web service script using nginx
Here is the scenario:
You have a webservice you would like to use a virtual host to
proxy port 80 traffic to your webservice. But now you want
to use https and a lets encrypt cert, this script does that.
It redirects http traffic to https, applies for a lets encrypt
cert, and forwards port 443 traffic to the port you specify.
All you need to provide is the domain name, port, and IP address.
''')
domain_name = raw_input('Please enter the domain name: ')
port = raw_input('Please enter the port [1024-9999]: ')
ip_address = raw_input('Please enter the IP address: ')
print(' ')
nginx_config_raw = '''
map $http_upgrade $connection_upgrade {{
default upgrade;
'' close;
}}
upstream websocket{1} {{
server 127.0.0.1:{1};
}}
server {{
listen {2}:443 ssl;
server_name {0};
ssl_certificate /etc/letsencrypt/live/{0}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{0}/privkey.pem;
location / {{
proxy_pass http://websocket{1};
proxy_read_timeout 600;
proxy_http_version 1.1;
proxy_redirect off;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
if ($request_method = 'OPTIONS') {{
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}}
if ($request_method = 'POST') {{
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
}}
if ($request_method = 'GET') {{
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
}}
}}
}}
server {{
listen {2}:80;
server_name {0};
return 301 https://{0}$request_uri;
}}
'''
nginx_config = nginx_config_raw.format(domain_name, port, ip_address)
nginx_config_available = '/etc/nginx/sites-available/'+domain_name
def write_nginx_config():
f = open(nginx_config_available, 'w')
f.write(nginx_config)
print('Writing nginx config')
f.close()
os.symlink(nginx_config_available, '/etc/nginx/sites-enabled/' + domain_name)
print('Adding symlink from sites-available to sites-enabled')
if (os.path.isfile(nginx_config_available)):
answer = raw_input('nginx config for site exists, overwrite? [Y/n]')
if (answer.lower() == 'y'):
write_nginx_config()
else:
write_nginx_config()
# download let's encrypt
print('Downloading lets encrypt')
subprocess.check_call('wget https://dl.eff.org/certbot-auto', shell=True)
subprocess.check_call('chmod a+x certbot-auto', shell=True)
subprocess.check_call('cp certbot-auto /opt', shell=True)
# shut down nginx
print('Attempting to shut down nginx')
try:
systemd_check = subprocess.check_call('systemctl stop nginx', shell=True)
except:
systemd_check = 1
print("systemd didn't work")
if (systemd_check != 0):
try:
service_check = subprocess.check_call('service nginx stop', shell=True)
except:
service_check = 1
print("service didn't work")
if (systemd_check != 0 and service_check != 0):
try:
initd_check = subprocess.check_call('/etc/init.d/nginx stop', shell=True)
except:
initd_check = 1
print("initd didn't work")
if (systemd_check != 0 and service_check != 0 and initd_check != 0):
print('Could not stop nginx, giving up')
sys.exit(1)
# apply for cert
print('Appling for lets encrypt cert')
subprocess.check_call('./certbot-auto certonly --standalone -d '+domain_name, shell=True)
# start nginx
print('Attempting to restart nginx')
if (systemd_check == 0):
subprocess.check_call('systemctl start nginx', shell=True)
elif (service_check == 0):
subprocess.check_call('service nginx start', shell=True)
elif (initd_check == 0):
subprocess.check_call('/etc/init.d/nginx start', shell=True)
else:
print("couldn't restart nginx")
sys.exit(1)
# print renew script and crontab additions
print('''
To renew this cert you should make a script that contains something like this:
#!/bin/bash
systemctl stop nginx # or equivalent
/opt/certbot-auto renew
systemctl start nginx # or equivalent
You could then save it to
/opt/renew-certs.sh
And then add this to your crontab
{1} 0 1 * * /opt/renew-certs.sh
With the command
crontab -e
To renew your lets encrypt cert once a month
'''.format(domain_name, random_min))