Skip to content

Commit

Permalink
T6486: T6379: Rewrite generate openvpn client-config (#3926)
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

(cherry picked from commit fe50f1a)

Co-authored-by: Viacheslav Hletenko <v.gletenko@vyos.io>
  • Loading branch information
mergify[bot] and sever-sever authored Aug 2, 2024
1 parent ede841f commit 4a226cd
Showing 1 changed file with 64 additions and 49 deletions.
113 changes: 64 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-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,25 @@
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)

0 comments on commit 4a226cd

Please sign in to comment.