From 4a226cd2897f2588377024998d1fc4adf18b3cdd Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:39:56 +0300 Subject: T6486: T6379: Rewrite generate openvpn client-config (#3926) This command helps to generate users `.ovpn` files Rewrite `generate openvpn client-config` to use Config() It needs to get the default values as `ConfigTreeQuery` is not supporting default values. Fixed "ignores configured protocol type" if TCP is used Fixed lzo, was used even if lzo not configured Fixed encryption is not parse the dict (cherry picked from commit fe50f1a9292b34e168b35453f2cfc2aee2ca4843) Co-authored-by: Viacheslav Hletenko --- src/op_mode/generate_ovpn_client_file.py | 113 +++++++++++++++++-------------- 1 file changed, 64 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/op_mode/generate_ovpn_client_file.py b/src/op_mode/generate_ovpn_client_file.py index 2d96fe217..974f7d9b6 100755 --- a/src/op_mode/generate_ovpn_client_file.py +++ b/src/op_mode/generate_ovpn_client_file.py @@ -19,42 +19,53 @@ import argparse from jinja2 import Template from textwrap import fill -from vyos.configquery import ConfigTreeQuery +from vyos.config import Config from vyos.ifconfig import Section client_config = """ client nobind -remote {{ remote_host }} {{ port }} +remote {{ local_host if local_host else 'x.x.x.x' }} {{ port }} remote-cert-tls server -proto {{ 'tcp-client' if protocol == 'tcp-active' else 'udp' }} -dev {{ device }} -dev-type {{ device }} +proto {{ 'tcp-client' if protocol == 'tcp-passive' else 'udp' }} +dev {{ device_type }} +dev-type {{ device_type }} persist-key persist-tun verb 3 # Encryption options +{# Define the encryption map #} +{% set encryption_map = { + 'des': 'DES-CBC', + '3des': 'DES-EDE3-CBC', + 'bf128': 'BF-CBC', + 'bf256': 'BF-CBC', + 'aes128gcm': 'AES-128-GCM', + 'aes128': 'AES-128-CBC', + 'aes192gcm': 'AES-192-GCM', + 'aes192': 'AES-192-CBC', + 'aes256gcm': 'AES-256-GCM', + 'aes256': 'AES-256-CBC' +} %} + {% if encryption is defined and encryption is not none %} -{% if encryption.cipher is defined and encryption.cipher is not none %} -cipher {{ encryption.cipher }} -{% if encryption.cipher == 'bf128' %} -keysize 128 -{% elif encryption.cipher == 'bf256' %} -keysize 256 +{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %} +cipher {% for algo in encryption.ncp_ciphers %} +{{ encryption_map[algo] if algo in encryption_map.keys() else algo }}{% if not loop.last %}:{% endif %} +{% endfor %} + +data-ciphers {% for algo in encryption.ncp_ciphers %} +{{ encryption_map[algo] if algo in encryption_map.keys() else algo }}{% if not loop.last %}:{% endif %} +{% endfor %} {% endif %} -{% endif %} -{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %} -data-ciphers {{ encryption.ncp_ciphers }} -{% endif %} {% endif %} {% if hash is defined and hash is not none %} auth {{ hash }} {% endif %} -keysize 256 -comp-lzo {{ '' if use_lzo_compression is defined else 'no' }} +{{ 'comp-lzo' if use_lzo_compression is defined else '' }} -----BEGIN CERTIFICATE----- @@ -79,7 +90,7 @@ comp-lzo {{ '' if use_lzo_compression is defined else 'no' }} """ -config = ConfigTreeQuery() +config = Config() base = ['interfaces', 'openvpn'] if not config.exists(base): @@ -89,10 +100,22 @@ if not config.exists(base): if __name__ == '__main__': parser = argparse.ArgumentParser() - parser.add_argument("-i", "--interface", type=str, help='OpenVPN interface the client is connecting to', required=True) - parser.add_argument("-a", "--ca", type=str, help='OpenVPN CA cerificate', required=True) - parser.add_argument("-c", "--cert", type=str, help='OpenVPN client cerificate', required=True) - parser.add_argument("-k", "--key", type=str, help='OpenVPN client cerificate key', action="store") + parser.add_argument( + "-i", + "--interface", + type=str, + help='OpenVPN interface the client is connecting to', + required=True, + ) + parser.add_argument( + "-a", "--ca", type=str, help='OpenVPN CA cerificate', required=True + ) + parser.add_argument( + "-c", "--cert", type=str, help='OpenVPN client cerificate', required=True + ) + parser.add_argument( + "-k", "--key", type=str, help='OpenVPN client cerificate key', action="store" + ) args = parser.parse_args() interface = args.interface @@ -114,33 +137,25 @@ if __name__ == '__main__': if not config.exists(['pki', 'certificate', cert, 'private', 'key']): exit(f'OpenVPN certificate key "{key}" does not exist!') - ca = config.value(['pki', 'ca', ca, 'certificate']) + config = config.get_config_dict( + base + [interface], + key_mangling=('-', '_'), + get_first_key=True, + with_recursive_defaults=True, + with_pki=True, + ) + + ca = config['pki']['ca'][ca]['certificate'] ca = fill(ca, width=64) - cert = config.value(['pki', 'certificate', cert, 'certificate']) + cert = config['pki']['certificate'][cert]['certificate'] cert = fill(cert, width=64) - key = config.value(['pki', 'certificate', key, 'private', 'key']) + key = config['pki']['certificate'][key]['private']['key'] key = fill(key, width=64) - remote_host = config.value(base + [interface, 'local-host']) - - ovpn_conf = config.get_config_dict(base + [interface], key_mangling=('-', '_'), get_first_key=True) - - port = '1194' if 'local_port' not in ovpn_conf else ovpn_conf['local_port'] - proto = 'udp' if 'protocol' not in ovpn_conf else ovpn_conf['protocol'] - device = 'tun' if 'device_type' not in ovpn_conf else ovpn_conf['device_type'] - - config = { - 'interface' : interface, - 'ca' : ca, - 'cert' : cert, - 'key' : key, - 'device' : device, - 'port' : port, - 'proto' : proto, - 'remote_host' : remote_host, - 'address' : [], - } - -# Clear out terminal first -print('\x1b[2J\x1b[H') -client = Template(client_config, trim_blocks=True).render(config) -print(client) + + config['ca'] = ca + config['cert'] = cert + config['key'] = key + config['port'] = '1194' if 'local_port' not in config else config['local_port'] + + client = Template(client_config, trim_blocks=True).render(config) + print(client) -- cgit v1.2.3