@@ -71,13 +71,30 @@ def get_ssl_conf(self) -> Dict[str, str]:
71
71
conf [key .strip ()] = value .strip ()
72
72
return conf
73
73
74
- def edit_conf (self , conf_name : str , conf_content : str ) -> None :
74
+ def edit_conf (self ,
75
+ conf_name : str ,
76
+ conf_content : str ,
77
+ cert_path : str = None ,
78
+ key_path : str = None ) -> None :
75
79
with open (f'{ self .app_conf_path } /{ conf_name } .conf' , 'w' ) as f :
76
80
f .write (conf_content .strip () + '\n ' )
81
+
82
+ if cert_path and key_path :
83
+ shutil .copy (cert_path , f'{ self .app_ssl_path } /{ conf_name } .crt' )
84
+ shutil .copy (key_path , f'{ self .app_ssl_path } /{ conf_name } .key' )
85
+ os .remove (cert_path )
86
+ os .remove (key_path )
87
+
77
88
self .reload_nginx ()
78
89
79
- def create_conf (self , domain : str , server : str , description : str , service_type : str ,
80
- allow_origin : str = '*' ) -> None :
90
+ def create_conf (self ,
91
+ domain : str ,
92
+ server : str ,
93
+ description : str ,
94
+ service_type : str ,
95
+ allow_origin : str = '*' ,
96
+ cert_path : str = None ,
97
+ key_path : str = None ) -> None :
81
98
conf = rf"""
82
99
map $http_upgrade $connection_upgrade {{
83
100
default upgrade;
@@ -112,7 +129,8 @@ def create_conf(self, domain: str, server: str, description: str, service_type:
112
129
add_header Cross-Origin-Resource-Policy "same-site";
113
130
114
131
add_header Permissions-Policy ();
115
- add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https: http:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'";
132
+ add_header Content-Security-Policy "default-src 'self'; img-src 'self' data: https: http:; script-src 'self' \
133
+ 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'";
116
134
117
135
proxy_cookie_flags ~ secure httponly samesite=strict;
118
136
@@ -130,6 +148,15 @@ def create_conf(self, domain: str, server: str, description: str, service_type:
130
148
os .makedirs (f'{ self .app_log_path } /{ domain } ' , exist_ok = True )
131
149
with open (f'{ self .app_conf_path } /{ domain } .conf' , 'w' ) as f :
132
150
f .write (conf )
151
+
152
+ if cert_path and key_path :
153
+ shutil .copy (cert_path , f'{ self .app_ssl_path } /{ domain } .crt' )
154
+ shutil .copy (key_path , f'{ self .app_ssl_path } /{ domain } .key' )
155
+ os .remove (cert_path )
156
+ os .remove (key_path )
157
+ else :
158
+ self .generate_ssl (domain )
159
+
133
160
self .reload_nginx ()
134
161
135
162
def generate_ssl (self , domain : str ) -> None :
@@ -156,10 +183,11 @@ def generate_ssl(self, domain: str) -> None:
156
183
DNS.1 = { domain }
157
184
""" )
158
185
subprocess .run ([
159
- 'openssl' , 'req' , '-new' , '-newkey' , 'rsa:4096' , '-sha256' , '-days' , ssl_conf [ 'DAYS' ], '-nodes' , '-x509' ,
160
- '-keyout' , f'{ self .app_ssl_path } /{ domain } .key' ,
186
+ 'openssl' , 'req' , '-new' , '-newkey' , 'rsa:4096' , '-sha256' , '-days' ,
187
+ ssl_conf [ 'DAYS' ], '-nodes' , '-x509' , '-keyout' , f'{ self .app_ssl_path } /{ domain } .key' ,
161
188
'-out' , f'{ self .app_ssl_path } /{ domain } .crt' ,
162
- '-subj' , f"/C={ ssl_conf ['COUNTRY' ]} /ST={ ssl_conf ['STATE' ]} /L={ ssl_conf ['LOCATION' ]} /O={ ssl_conf ['ORGANIZATION-GLOBAL' ]} /OU={ ssl_conf ['ORGANIZATION-UNIT' ]} /CN={ domain } " ,
189
+ '-subj' , f"/C={ ssl_conf ['COUNTRY' ]} /ST={ ssl_conf ['STATE' ]} /L={ ssl_conf ['LOCATION' ]} "
190
+ f"/O={ ssl_conf ['ORGANIZATION-GLOBAL' ]} /OU={ ssl_conf ['ORGANIZATION-UNIT' ]} /CN={ domain } " ,
163
191
'-config' , ext_cnf_path
164
192
], stdout = subprocess .DEVNULL , stderr = subprocess .DEVNULL , check = True )
165
193
os .remove (ext_cnf_path )
@@ -175,6 +203,16 @@ def backup_nginx(self) -> None:
175
203
with tarfile .open (f'{ self .app_scripts_path } /nginx.tar.gz' , 'w:gz' ) as tar :
176
204
tar .add (self .app_nginx_path , arcname = os .path .basename (self .app_nginx_path ))
177
205
206
+ def handle_cert_key_upload (self , cert : Any , key : Any , conf_name : str ) -> tuple [str , str ]:
207
+ if cert and key :
208
+ tmp_cert_path = f'{ self .app_scripts_path } /{ conf_name } .crt'
209
+ tmp_key_path = f'{ self .app_scripts_path } /{ conf_name } .key'
210
+ cert .save (tmp_cert_path )
211
+ key .save (tmp_key_path )
212
+ else :
213
+ tmp_cert_path = tmp_key_path = None
214
+ return tmp_cert_path , tmp_key_path
215
+
178
216
179
217
@bp .route ('/manage' , methods = ['GET' , 'POST' ])
180
218
def manage ():
@@ -184,8 +222,13 @@ def manage():
184
222
if 'new_conf' in request .form :
185
223
new_conf = request .form ['new_conf' ]
186
224
conf_name = request .form ['conf_name' ]
187
- handler .edit_conf (conf_name , new_conf .replace ('\r \n ' , '\n ' ))
188
- conf_list = handler .get_conf_list ()
225
+
226
+ cert = request .files ['cert' ] if 'cert' in request .files else None
227
+ key = request .files ['key' ] if 'key' in request .files else None
228
+ cert_path , key_path = handler .handle_cert_key_upload (cert , key , conf_name )
229
+
230
+ handler .edit_conf (conf_name , new_conf .replace ('\r \n ' , '\n ' ), cert_path , key_path )
231
+
189
232
return render_template ('manage.html' , conf_list = conf_list )
190
233
191
234
action = request .form ['action' ]
@@ -203,32 +246,38 @@ def manage():
203
246
handler .remove_conf (conf_name )
204
247
return render_template ('manage.html' , conf_list = conf_list )
205
248
elif action == 'edit' :
206
- return render_template ('manage.html' , conf_list = conf_list , conf_edit = conf_content , conf_name = conf_name )
249
+ return render_template ('manage.html' , conf_list = conf_list ,
250
+ conf_edit = conf_content , conf_name = conf_name )
207
251
else :
208
252
return render_template ('manage.html' , conf_list = conf_list )
209
253
210
254
211
255
@bp .route ('/create' , methods = ['GET' , 'POST' ])
212
256
def create ():
213
257
if request .method == 'POST' :
258
+ handler = ReverseProxyManager ()
259
+
214
260
domain = request .form ['domain' ]
215
261
server = request .form ['server' ]
216
262
description = request .form ['description' ]
217
263
service_type = request .form ['service_type' ]
218
264
allow_origin = request .form ['allow_origin' ]
219
265
220
266
if domain == '' or server == '' :
221
- return render_template ('create.html' , message = 'Domain and server address are required' , success = False )
267
+ return render_template ('create.html' ,
268
+ message = 'Domain and server address are required' , success = False )
222
269
if allow_origin == '' :
223
270
allow_origin = '*'
224
271
225
- handler = ReverseProxyManager ()
272
+ cert = request .files ['cert' ] if 'cert' in request .files else None
273
+ key = request .files ['key' ] if 'key' in request .files else None
274
+ cert_path , key_path = handler .handle_cert_key_upload (cert , key , domain )
275
+
226
276
if domain in handler .get_conf_list ():
227
277
return render_template ('create.html' , message = 'Domain already exists' , success = False )
228
278
if not handler .address_check (server ):
229
279
return render_template ('create.html' , message = 'Invalid server address' , success = False )
230
- handler .generate_ssl (domain )
231
- handler .create_conf (domain , server , description , service_type , allow_origin )
280
+ handler .create_conf (domain , server , description , service_type , allow_origin , cert_path , key_path )
232
281
233
282
return render_template ('create.html' , message = 'Configuration created' , success = True )
234
283
else :
0 commit comments