Skip to content

Commit

Permalink
T6486: T6379: Rewrite generate openvpn client-config
Browse files Browse the repository at this point in the history
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
  • Loading branch information
sever-sever committed Jul 2, 2024
1 parent e270712 commit 0bffdb0
Showing 1 changed file with 66 additions and 49 deletions.
115 changes: 66 additions & 49 deletions src/op_mode/generate_ovpn_client_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,53 @@
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-active' or 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 '' }}
<ca>
-----BEGIN CERTIFICATE-----
Expand All @@ -79,7 +90,7 @@
"""

config = ConfigTreeQuery()
config = Config()
base = ['interfaces', 'openvpn']

if not config.exists(base):
Expand All @@ -89,10 +100,22 @@

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
Expand All @@ -114,33 +137,27 @@
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']

# Clear out terminal first
print('\x1b[2J\x1b[H')
client = Template(client_config, trim_blocks=True).render(config)
print(client)

0 comments on commit 0bffdb0

Please sign in to comment.