summaryrefslogtreecommitdiff
path: root/src/conf_mode/https.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/https.py')
-rwxr-xr-xsrc/conf_mode/https.py144
1 files changed, 52 insertions, 92 deletions
diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py
index 84d1a7691..da7193c9b 100755
--- a/src/conf_mode/https.py
+++ b/src/conf_mode/https.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2019 VyOS maintainers and contributors
+# Copyright (C) 2019-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
@@ -13,88 +13,26 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-#
-import sys
import os
-import jinja2
+from sys import exit
+from copy import deepcopy
+from jinja2 import FileSystemLoader, Environment
import vyos.defaults
import vyos.certbot_util
+
from vyos.config import Config
+from vyos.defaults import directories as vyos_data_dir
from vyos import ConfigError
+from vyos.util import call
-config_file = '/etc/nginx/sites-available/default'
-
-# Please be careful if you edit the template.
-config_tmpl = """
-
-### Autogenerated by https.py ###
-# Default server configuration
-#
-server {
- listen 80 default_server;
- listen [::]:80 default_server;
- server_name _;
- return 301 https://$server_name$request_uri;
-}
-
-{% for server in server_block_list %}
-server {
-
- # SSL configuration
- #
-{% if server.address == '*' %}
- listen {{ server.port }} ssl;
- listen [::]:{{ server.port }} ssl;
-{% else %}
- listen {{ server.address }}:{{ server.port }} ssl;
-{% endif %}
-
-{% for name in server.name %}
- server_name {{ name }};
-{% endfor %}
-
-{% if server.certbot %}
- ssl_certificate /etc/letsencrypt/live/{{ server.certbot_dir }}/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/{{ server.certbot_dir }}/privkey.pem;
- include /etc/letsencrypt/options-ssl-nginx.conf;
- ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
-{% elif server.vyos_cert %}
- include {{ server.vyos_cert.conf }};
-{% else %}
- #
- # Self signed certs generated by the ssl-cert package
- # Don't use them in a production server!
- #
- include snippets/snakeoil.conf;
-{% endif %}
-
- # proxy settings for HTTP API, if enabled; 503, if not
- location ~ /(retrieve|configure|config-file|image) {
-{% if server.api %}
- proxy_pass http://localhost:{{ server.api.port }};
- proxy_buffering off;
-{% else %}
- return 503;
-{% endif %}
- }
-
- error_page 501 502 503 =200 @50*_json;
-
- location @50*_json {
- default_type application/json;
- return 200 '{"error": "Start service in configuration mode: set service https api"}';
- }
-
-}
-{% endfor %}
-"""
+config_file = '/etc/nginx/sites-available/default'
default_server_block = {
+ 'id' : '',
'address' : '*',
'port' : '443',
'name' : ['_'],
@@ -111,22 +49,23 @@ def get_config():
else:
conf.set_level('service https')
- if conf.exists('listen-address'):
- for addr in conf.list_nodes('listen-address'):
- server_block = {'address' : addr}
- server_block['port'] = '443'
- server_block['name'] = ['_']
- if conf.exists('listen-address {0} listen-port'.format(addr)):
- port = conf.return_value('listen-address {0} listen-port'.format(addr))
+ if not conf.exists('virtual-host'):
+ server_block_list.append(default_server_block)
+ else:
+ for vhost in conf.list_nodes('virtual-host'):
+ server_block = deepcopy(default_server_block)
+ server_block['id'] = vhost
+ if conf.exists(f'virtual-host {vhost} listen-address'):
+ addr = conf.return_value(f'virtual-host {vhost} listen-address')
+ server_block['address'] = addr
+ if conf.exists(f'virtual-host {vhost} listen-port'):
+ port = conf.return_value(f'virtual-host {vhost} listen-port')
server_block['port'] = port
- if conf.exists('listen-address {0} server-name'.format(addr)):
- names = conf.return_values('listen-address {0} server-name'.format(addr))
+ if conf.exists(f'virtual-host {vhost} server-name'):
+ names = conf.return_values(f'virtual-host {vhost} server-name')
server_block['name'] = names[:]
server_block_list.append(server_block)
- if not server_block_list:
- server_block_list.append(default_server_block)
-
vyos_cert_data = {}
if conf.exists('certificates system-generated-certificate'):
vyos_cert_data = vyos.defaults.vyos_cert_data
@@ -149,17 +88,33 @@ def get_config():
# certbot organizes certificates by first domain
sb['certbot_dir'] = certbot_domains[0]
+ api_somewhere = False
api_data = {}
if conf.exists('api'):
+ api_somewhere = True
api_data = vyos.defaults.api_data
if conf.exists('api port'):
port = conf.return_value('api port')
api_data['port'] = port
- if api_data:
- for block in server_block_list:
- block['api'] = api_data
+ if conf.exists('api-restrict virtual-host'):
+ vhosts = conf.return_values('api-restrict virtual-host')
+ api_data['vhost'] = vhosts[:]
- https = {'server_block_list' : server_block_list, 'certbot': certbot}
+ if api_data:
+ # we do not want to include 'vhost' key as part of
+ # vyos.defaults.api_data, so check for key existence
+ vhost_list = api_data.get('vhost')
+ if vhost_list is None:
+ for block in server_block_list:
+ block['api'] = api_data
+ else:
+ for block in server_block_list:
+ if block['id'] in vhost_list:
+ block['api'] = api_data
+
+ https = {'server_block_list' : server_block_list,
+ 'api_somewhere': api_somewhere,
+ 'certbot': certbot}
return https
def verify(https):
@@ -170,7 +125,7 @@ def verify(https):
for sb in https['server_block_list']:
if sb['certbot']:
return None
- raise ConfigError("At least one 'listen-address x.x.x.x server-name' "
+ raise ConfigError("At least one 'virtual-host <id> server-name' "
"matching the 'certbot domain-name' is required.")
return None
@@ -178,10 +133,15 @@ def generate(https):
if https is None:
return None
+ # Prepare Jinja2 template loader from files
+ tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'https')
+ fs_loader = FileSystemLoader(tmpl_path)
+ env = Environment(loader=fs_loader, trim_blocks=True)
+
if 'server_block_list' not in https or not https['server_block_list']:
https['server_block_list'] = [default_server_block]
- tmpl = jinja2.Template(config_tmpl, trim_blocks=True)
+ tmpl = env.get_template('nginx.default.tmpl')
config_text = tmpl.render(https)
with open(config_file, 'w') as f:
f.write(config_text)
@@ -190,9 +150,9 @@ def generate(https):
def apply(https):
if https is not None:
- os.system('sudo systemctl restart nginx.service')
+ call('sudo systemctl restart nginx.service')
else:
- os.system('sudo systemctl stop nginx.service')
+ call('sudo systemctl stop nginx.service')
if __name__ == '__main__':
try:
@@ -202,4 +162,4 @@ if __name__ == '__main__':
apply(c)
except ConfigError as e:
print(e)
- sys.exit(1)
+ exit(1)