Source code for netjsonconfig.backends.openvpn.openvpn

from ...schema import X509_FILE_MODE
from ..base.backend import BaseVpnBackend
from . import converters
from .parser import OpenVpnParser, config_suffix, vpn_pattern
from .renderer import OpenVpnRenderer
from .schema import schema


class OpenVpn(BaseVpnBackend):
    """
    OpenVPN 2.x Configuration Backend
    """

    schema = schema
    converters = [converters.OpenVpn]
    parser = OpenVpnParser
    renderer = OpenVpnRenderer
    list_identifiers = ['name']
    # BaseVpnBackend attributes
    vpn_pattern = vpn_pattern
    config_suffix = config_suffix

[docs] @classmethod def auto_client( cls, host, server, ca_path=None, ca_contents=None, cert_path=None, cert_contents=None, key_path=None, key_contents=None, ): """ Returns a configuration dictionary representing an OpenVPN client configuration that is compatible with the passed server configuration. :param host: remote VPN server :param server: dictionary representing a single OpenVPN server configuration :param ca_path: optional string representing path to CA, will consequently add a file in the resulting configuration dictionary :param ca_contents: optional string representing contents of CA file :param cert_path: optional string representing path to certificate, will consequently add a file in the resulting configuration dictionary :param cert_contents: optional string representing contents of cert file :param key_path: optional string representing path to key, will consequently add a file in the resulting configuration dictionary :param key_contents: optional string representing contents of key file :returns: dictionary representing a single OpenVPN client configuration """ # client defaults client = { "mode": "p2p", "nobind": True, "resolv_retry": "infinite", "tls_client": True, } # remote port = server.get('port') or 1195 client['remote'] = [{'host': host, 'port': port}] # proto if server.get('proto') == 'tcp-server': client['proto'] = 'tcp-client' else: client['proto'] = 'udp' # determine if pull must be True if 'server' in server or 'server_bridge' in server: client['pull'] = True # tls_client if 'tls_server' not in server or not server['tls_server']: client['tls_client'] = False # ns_cert_type ns_cert_type = {None: '', '': '', 'client': 'server'} client['ns_cert_type'] = ns_cert_type[server.get('ns_cert_type')] # remote_cert_tls remote_cert_tls = {None: '', '': '', 'client': 'server'} client['remote_cert_tls'] = remote_cert_tls[server.get('remote_cert_tls')] tls_auth = server.get('tls_auth') if tls_auth: if len(tls_auth.strip().split(' ')) == 2: # The field contains path to auth key and direction. # auto_client does not support such format. pass else: # The TLS Auth key is present in the field. # Copy the TLS Auth key. Convertor will handle # parsing it into file. client['tls_auth'] = tls_auth copy_keys = [ 'name', 'dev_type', 'dev', 'comp_lzo', 'auth', 'cipher', 'ca', 'cert', 'key', 'pkcs12', 'mtu_test', 'fragment', 'mssfix', 'keepalive', 'persist_tun', 'mute', 'persist_key', 'user', 'group', 'mute_replay_warnings', 'secret', 'reneg_sec', 'tls_timeout', 'tls_cipher', 'float', 'fast_io', 'verb', "auth_nocache", ] for key in copy_keys: if key in server: client[key] = server[key] if 'script_security' in server: # From OpenWrt 21 onwards, "script_security" of "2" # is required for functioning of OpenVPN tunnels. client['script_security'] = 2 if 'log' in server: # The "/var/log/openvpn" directory is not present # on OpenWrt, hence the location of the log is changed. client['log'] = server['log'].replace('/var/log/openvpn/', '/var/log/') files = cls._auto_client_files( client, ca_path, ca_contents, cert_path, cert_contents, key_path, key_contents, ) return {'openvpn': [client], 'files': files}
@classmethod def _auto_client_files( cls, client, ca_path=None, ca_contents=None, cert_path=None, cert_contents=None, key_path=None, key_contents=None, ): """ returns a list of NetJSON extra files for automatically generated clients produces side effects in ``client`` dictionary """ files = [] if ca_path and ca_contents: client['ca'] = ca_path files.append(dict(path=ca_path, contents=ca_contents, mode=X509_FILE_MODE)) if cert_path and cert_contents: client['cert'] = cert_path files.append( dict(path=cert_path, contents=cert_contents, mode=X509_FILE_MODE) ) if key_path and key_contents: client['key'] = key_path files.append( dict( path=key_path, contents=key_contents, mode=X509_FILE_MODE, ) ) return files