#!/usr/bin/env python3 # # 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 # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # 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 os from sys import exit from copy import deepcopy import vyos.defaults import vyos.certbot_util from vyos.config import Config from vyos import ConfigError from vyos.util import call from vyos.template import render config_file = '/etc/nginx/sites-available/default' default_server_block = { 'id' : '', 'address' : '*', 'port' : '443', 'name' : ['_'], 'api' : {}, 'vyos_cert' : {}, 'certbot' : False } def get_config(): server_block_list = [] conf = Config() if not conf.exists('service https'): return None else: conf.set_level('service https') 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(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) vyos_cert_data = {} if conf.exists('certificates system-generated-certificate'): vyos_cert_data = vyos.defaults.vyos_cert_data if vyos_cert_data: for block in server_block_list: block['vyos_cert'] = vyos_cert_data certbot = False certbot_domains = [] if conf.exists('certificates certbot domain-name'): certbot_domains = conf.return_values('certificates certbot domain-name') if certbot_domains: certbot = True for domain in certbot_domains: sub_list = vyos.certbot_util.choose_server_block(server_block_list, domain) if sub_list: for sb in sub_list: sb['certbot'] = True # 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 conf.exists('api-restrict virtual-host'): vhosts = conf.return_values('api-restrict virtual-host') api_data['vhost'] = vhosts[:] 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): if https is None: return None if https['certbot']: for sb in https['server_block_list']: if sb['certbot']: return None raise ConfigError("At least one 'virtual-host <id> server-name' " "matching the 'certbot domain-name' is required.") return None def generate(https): if https is None: return None if 'server_block_list' not in https or not https['server_block_list']: https['server_block_list'] = [default_server_block] render(config_file, 'https/nginx.default.tmpl', https, trim_blocks=True) return None def apply(https): if https is not None: call('sudo systemctl restart nginx.service') else: call('sudo systemctl stop nginx.service') if __name__ == '__main__': try: c = get_config() verify(c) generate(c) apply(c) except ConfigError as e: print(e) exit(1)