Exemple #1
0
    def add_addr(self, addr):
        """
        Add IP(v6) address to interface. Address is only added if it is not
        already assigned to that interface. Address format must be validated
        and compressed/normalized before calling this function.

        addr: can be an IPv4 address, IPv6 address, dhcp or dhcpv6!
              IPv4: add IPv4 address to interface
              IPv6: add IPv6 address to interface
              dhcp: start dhclient (IPv4) on interface
              dhcpv6: start WIDE DHCPv6 (IPv6) on interface

        Returns False if address is already assigned and wasn't re-added.
        Example:
        >>> from vyos.ifconfig import Interface
        >>> j = Interface('eth0')
        >>> j.add_addr('192.0.2.1/24')
        >>> j.add_addr('2001:db8::ffff/64')
        >>> j.get_addr()
        ['192.0.2.1/24', '2001:db8::ffff/64']
        """
        # XXX: normalize/compress with ipaddress if calling functions don't?
        # is subnet mask always passed, and in the same way?

        # do not add same address twice
        if addr in self._addr:
            return False

        # we can't have both DHCP and static IPv4 addresses assigned
        for a in self._addr:
            if ((addr == 'dhcp' and a != 'dhcpv6' and is_ipv4(a))
                    or (a == 'dhcp' and addr != 'dhcpv6' and is_ipv4(addr))):
                raise ConfigError(
                    ("Can't configure both static IPv4 and DHCP address "
                     "on the same interface"))

        # add to interface
        if addr == 'dhcp':
            self.dhcp.v4.set()
        elif addr == 'dhcpv6':
            self.dhcp.v6.set()
        elif not is_intf_addr_assigned(self.ifname, addr):
            self._cmd(f'ip addr add "{addr}" dev "{self.ifname}"')
        else:
            return False

        # add to cache
        self._addr.append(addr)

        return True
Exemple #2
0
def generate(tftpd):
    # cleanup any available configuration file
    # files will be recreated on demand
    for i in glob(config_file + '*'):
        os.unlink(i)

    # bail out early - looks like removal from running config
    if tftpd is None:
        return None

    # Prepare Jinja2 template loader from files
    tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'tftp-server')
    fs_loader = FileSystemLoader(tmpl_path)
    env = Environment(loader=fs_loader)

    idx = 0
    for listen in tftpd['listen']:
        config = deepcopy(tftpd)
        if is_ipv4(listen):
            config['listen'] = [listen + ":" + tftpd['port'] + " -4"]
        else:
            config['listen'] = ["[" + listen + "]" + tftpd['port'] + " -6"]

        tmpl = env.get_template('default.tmpl')
        config_text = tmpl.render(config)
        file = config_file + str(idx)
        with open(file, 'w') as f:
            f.write(config_text)

        idx = idx + 1

    return None
Exemple #3
0
    def add_addr(self, addr):
        """
        Add IP(v6) address to interface. Address is only added if it is not
        already assigned to that interface.

        addr: can be an IPv4 address, IPv6 address, dhcp or dhcpv6!
              IPv4: add IPv4 address to interface
              IPv6: add IPv6 address to interface
              dhcp: start dhclient (IPv4) on interface
              dhcpv6: start dhclient (IPv6) on interface

        Example:
        >>> from vyos.ifconfig import Interface
        >>> j = Interface('eth0')
        >>> j.add_addr('192.0.2.1/24')
        >>> j.add_addr('2001:db8::ffff/64')
        >>> j.get_addr()
        ['192.0.2.1/24', '2001:db8::ffff/64']
        """

        # cache new IP address which is assigned to interface
        self._addr.append(addr)

        # we can not have both DHCP and static IPv4 addresses assigned to an interface
        if 'dhcp' in self._addr:
            for addr in self._addr:
                # do not change below 'if' ordering esle you will get an exception as:
                #   ValueError: 'dhcp' does not appear to be an IPv4 or IPv6 address
                if addr != 'dhcp' and is_ipv4(addr):
                    raise ConfigError(
                        "Can't configure both static IPv4 and DHCP address on the same interface"
                    )

        if addr == 'dhcp':
            self.dhcp.v4.set()
        elif addr == 'dhcpv6':
            self.dhcp.v6.set()
        else:
            if not is_intf_addr_assigned(self.config['ifname'], addr):
                cmd = 'ip addr add "{}" dev "{}"'.format(
                    addr, self.config['ifname'])
                return self._cmd(cmd)
    def test_snmp(self):
        """ Check if SNMP can be configured and service runs """
        clients = ['192.0.2.1', '2001:db8::1']
        networks = ['192.0.2.128/25', '2001:db8:babe::/48']
        listen = ['127.0.0.1', '::1']

        for auth in ['ro', 'rw']:
            community = 'VyOS' + auth
            self.session.set(base_path +
                             ['community', community, 'authorization', auth])
            for client in clients:
                self.session.set(base_path +
                                 ['community', community, 'client', client])
            for network in networks:
                self.session.set(base_path +
                                 ['community', community, 'network', network])

        for addr in listen:
            self.session.set(base_path + ['listen-address', addr])

        self.session.set(base_path + ['contact', '*****@*****.**'])
        self.session.set(base_path + ['location', 'qemu'])

        self.session.commit()

        # verify listen address, it will be returned as
        # ['unix:/run/snmpd.socket,udp:127.0.0.1:161,udp6:[::1]:161']
        # thus we need to transfor this into a proper list
        config = get_config_value('agentaddress')
        expected = 'unix:/run/snmpd.socket'
        for addr in listen:
            if is_ipv4(addr):
                expected += ',udp:{}:161'.format(addr)
            else:
                expected += ',udp6:[{}]:161'.format(addr)

        self.assertTrue(expected in config)

        # Check for running process
        self.assertTrue("snmpd" in (p.name() for p in process_iter()))
Exemple #5
0
def generate(tftpd):
    # cleanup any available configuration file
    # files will be recreated on demand
    for i in glob(config_file + '*'):
        os.unlink(i)

    # bail out early - looks like removal from running config
    if tftpd is None:
        return None

    idx = 0
    for listen in tftpd['listen']:
        config = deepcopy(tftpd)
        if is_ipv4(listen):
            config['listen'] = [listen + ":" + tftpd['port'] + " -4"]
        else:
            config['listen'] = ["[" + listen + "]" + tftpd['port'] + " -6"]

        file = config_file + str(idx)
        render(file, 'tftp-server/default.tmpl', config)

        idx = idx + 1

    return None
Exemple #6
0
def verify(conf):
    options = conf['options']
    changes = conf['changes']
    actions = conf['actions']

    ifname = options['ifname']
    iftype = options['type']

    if changes['section'] == 'delete':
        if ifname in options['nhrp']:
            raise ConfigError(
                f'Can not delete interface tunnel {iftype} {ifname}, it is used by nhrp'
            )
        # done, bail out early
        return None

    # tunnel encapsulation checks

    if not iftype:
        raise ConfigError(
            f'Must provide an "encapsulation" for tunnel {iftype} {ifname}')

    if changes['type'] in ('modify', 'delete'):
        # TODO: we could now deal with encapsulation modification by deleting / recreating
        raise ConfigError(
            f'Encapsulation can only be set at tunnel creation for tunnel {iftype} {ifname}'
        )

    if iftype != 'sit' and options['6rd-prefix']:
        # XXX: should be able to remove this and let the definition catch it
        print(
            f'6RD can only be configured for sit interfaces not tunnel {iftype} {ifname}'
        )

    # what are the tunnel options we can set / modified / deleted

    kls = get_class(options)
    valid = kls.updates + ['alias', 'addresses-add', 'addresses-del', 'vrf']

    if changes['section'] == 'create':
        valid.extend([
            'type',
        ])
        valid.extend([o for o in kls.options if o not in kls.updates])

    for create in actions['create']:
        if create not in valid:
            raise ConfigError(
                f'Can not set "{create}" for tunnel {iftype} {ifname} at tunnel creation'
            )

    for modify in actions['modify']:
        if modify not in valid:
            raise ConfigError(
                f'Can not modify "{modify}" for tunnel {iftype} {ifname}. it must be set at tunnel creation'
            )

    for delete in actions['delete']:
        if delete in kls.required:
            raise ConfigError(
                f'Can not remove "{delete}", it is an mandatory option for tunnel {iftype} {ifname}'
            )

    # tunnel information

    tun_local = options['local']
    afi_local = get_afi(tun_local)
    tun_remote = options['remote'] or tun_local
    afi_remote = get_afi(tun_remote)
    tun_ismgre = iftype == 'gre' and not options['remote']
    tun_is6rd = iftype == 'sit' and options['6rd-prefix']

    # incompatible options

    if not tun_local and not options['dhcp-interface'] and not tun_is6rd:
        raise ConfigError(
            f'Must configure either local-ip or dhcp-interface for tunnel {iftype} {ifname}'
        )

    if tun_local and options['dhcp-interface']:
        raise ConfigError(
            f'Must configure only one of local-ip or dhcp-interface for tunnel {iftype} {ifname}'
        )

    # tunnel endpoint

    if afi_local != afi_remote:
        raise ConfigError(
            f'IPv4/IPv6 mismatch between local-ip and remote-ip for tunnel {iftype} {ifname}'
        )

    if afi_local != kls.tunnel:
        version = 4 if tun_local == IP4 else 6
        raise ConfigError(
            f'Invalid IPv{version} local-ip for tunnel {iftype} {ifname}')

    ipv4_count = len([ip for ip in options['addresses-add'] if is_ipv4(ip)])
    ipv6_count = len([ip for ip in options['addresses-add'] if is_ipv6(ip)])

    if tun_ismgre and afi_local == IP6:
        raise ConfigError(
            f'Using an IPv6 address is forbidden for mGRE tunnels such as tunnel {iftype} {ifname}'
        )

    # check address family use
    # checks are not enforced (but ip command failing) for backward compatibility

    if ipv4_count and not IP4 in kls.ip:
        print(f'Should not use IPv4 addresses on tunnel {iftype} {ifname}')

    if ipv6_count and not IP6 in kls.ip:
        print(f'Should not use IPv6 addresses on tunnel {iftype} {ifname}')

    # tunnel encapsulation check

    convert = {
        (6, 4, 'gre'): 'ip6gre',
        (6, 6, 'gre'): 'ip6gre',
        (4, 6, 'ipip'): 'ipip6',
        (6, 6, 'ipip'): 'ip6ip6',
    }

    iprotos = []
    if ipv4_count:
        iprotos.append(4)
    if ipv6_count:
        iprotos.append(6)

    for iproto in iprotos:
        replace = convert.get((kls.tunnel, iproto, iftype), '')
        if replace:
            raise ConfigError(
                f'Using IPv6 address in local-ip or remote-ip is not possible with "encapsulation {iftype}". '
                +
                f'Use "encapsulation {replace}" for tunnel {iftype} {ifname} instead.'
            )

    # tunnel options

    incompatible = []
    if afi_local == IP6:
        incompatible.extend([
            'ttl',
            'tos',
            'key',
        ])
    if afi_local == IP4:
        incompatible.extend(['encaplimit', 'flowlabel', 'hoplimit', 'tclass'])

    for option in incompatible:
        if option in options:
            # TODO: raise converted to print as not enforced by vyatta
            # raise ConfigError(f'{option} is not valid for tunnel {iftype} {ifname}')
            print(f'Using "{option}" is invalid for tunnel {iftype} {ifname}')

    # duplicate tunnel pairs

    pair = '{}-{}'.format(options['local'], options['remote'])
    if options['tunnel'].get(iftype, {}).get(pair, 0) > 1:
        raise ConfigError(
            f'More than one tunnel configured for with the same encapulation and IPs for tunnel {iftype} {ifname}'
        )

    return None
Exemple #7
0
def get_config():
    sstp = deepcopy(default_config_data)
    base_path = ['vpn', 'sstp']
    conf = Config()
    if not conf.exists(base_path):
        return None

    conf.set_level(base_path)

    if conf.exists(['authentication', 'mode']):
        sstp['auth_mode'] = conf.return_value(['authentication', 'mode'])

    #
    # local auth
    if conf.exists(['authentication', 'local-users']):
        for username in conf.list_nodes(
            ['authentication', 'local-users', 'username']):
            user = {
                'name': username,
                'password': '',
                'state': 'enabled',
                'ip': '*',
                'upload': None,
                'download': None
            }

            conf.set_level(
                base_path +
                ['authentication', 'local-users', 'username', username])

            if conf.exists(['password']):
                user['password'] = conf.return_value(['password'])

            if conf.exists(['disable']):
                user['state'] = 'disable'

            if conf.exists(['static-ip']):
                user['ip'] = conf.return_value(['static-ip'])

            if conf.exists(['rate-limit', 'download']):
                user['download'] = conf.return_value(
                    ['rate-limit', 'download'])

            if conf.exists(['rate-limit', 'upload']):
                user['upload'] = conf.return_value(['rate-limit', 'upload'])

            sstp['local_users'].append(user)

    #
    # RADIUS auth and settings
    conf.set_level(base_path + ['authentication', 'radius'])
    if conf.exists(['server']):
        for server in conf.list_nodes(['server']):
            radius = {
                'server': server,
                'key': '',
                'fail_time': 0,
                'port': '1812'
            }

            conf.set_level(base_path +
                           ['authentication', 'radius', 'server', server])

            if conf.exists(['fail-time']):
                radius['fail-time'] = conf.return_value(['fail-time'])

            if conf.exists(['port']):
                radius['port'] = conf.return_value(['port'])

            if conf.exists(['key']):
                radius['key'] = conf.return_value(['key'])

            if not conf.exists(['disable']):
                sstp['radius_server'].append(radius)

        #
        # advanced radius-setting
        conf.set_level(base_path + ['authentication', 'radius'])

        if conf.exists(['acct-timeout']):
            sstp['radius_acct_tmo'] = conf.return_value(['acct-timeout'])

        if conf.exists(['max-try']):
            sstp['radius_max_try'] = conf.return_value(['max-try'])

        if conf.exists(['timeout']):
            sstp['radius_timeout'] = conf.return_value(['timeout'])

        if conf.exists(['nas-identifier']):
            sstp['radius_nas_id'] = conf.return_value(['nas-identifier'])

        if conf.exists(['nas-ip-address']):
            sstp['radius_nas_ip'] = conf.return_value(['nas-ip-address'])

        if conf.exists(['source-address']):
            sstp['radius_source_address'] = conf.return_value(
                ['source-address'])

        # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
        if conf.exists(['dynamic-author']):
            dae = {'port': '', 'server': '', 'key': ''}

            if conf.exists(['dynamic-author', 'server']):
                dae['server'] = conf.return_value(['dynamic-author', 'server'])

            if conf.exists(['dynamic-author', 'port']):
                dae['port'] = conf.return_value(['dynamic-author', 'port'])

            if conf.exists(['dynamic-author', 'key']):
                dae['key'] = conf.return_value(['dynamic-author', 'key'])

            sstp['radius_dynamic_author'] = dae

        if conf.exists(['rate-limit', 'enable']):
            sstp['radius_shaper_attr'] = 'Filter-Id'
            c_attr = ['rate-limit', 'enable', 'attribute']
            if conf.exists(c_attr):
                sstp['radius_shaper_attr'] = conf.return_value(c_attr)

            c_vendor = ['rate-limit', 'enable', 'vendor']
            if conf.exists(c_vendor):
                sstp['radius_shaper_vendor'] = conf.return_value(c_vendor)

    #
    # authentication protocols
    conf.set_level(base_path + ['authentication'])
    if conf.exists(['protocols']):
        # clear default list content, now populate with actual CLI values
        sstp['auth_proto'] = []
        auth_mods = {
            'pap': 'auth_pap',
            'chap': 'auth_chap_md5',
            'mschap': 'auth_mschap_v1',
            'mschap-v2': 'auth_mschap_v2'
        }

        for proto in conf.return_values(['protocols']):
            sstp['auth_proto'].append(auth_mods[proto])

    #
    # read in SSL certs
    conf.set_level(base_path + ['ssl'])
    if conf.exists(['ca-cert-file']):
        sstp['ssl_ca'] = conf.return_value(['ca-cert-file'])

    if conf.exists(['cert-file']):
        sstp['ssl_cert'] = conf.return_value(['cert-file'])

    if conf.exists(['key-file']):
        sstp['ssl_key'] = conf.return_value(['key-file'])

    #
    # read in client IPv4 pool
    conf.set_level(base_path + ['network-settings', 'client-ip-settings'])
    if conf.exists(['subnet']):
        sstp['client_ip_pool'] = conf.return_values(['subnet'])

    if conf.exists(['gateway-address']):
        sstp['client_gateway'] = conf.return_value(['gateway-address'])

    #
    # read in client IPv6 pool
    conf.set_level(base_path + ['network-settings', 'client-ipv6-pool'])
    if conf.exists(['prefix']):
        for prefix in conf.list_nodes(['prefix']):
            tmp = {'prefix': prefix, 'mask': '64'}

            if conf.exists(['prefix', prefix, 'mask']):
                tmp['mask'] = conf.return_value(['prefix', prefix, 'mask'])

            sstp['client_ipv6_pool'].append(tmp)

    if conf.exists(['delegate']):
        for prefix in conf.list_nodes(['delegate']):
            tmp = {'prefix': prefix, 'mask': ''}

            if conf.exists(['delegate', prefix, 'delegation-prefix']):
                tmp['mask'] = conf.return_value(
                    ['delegate', prefix, 'delegation-prefix'])

            sstp['client_ipv6_delegate_prefix'].append(tmp)

    #
    # read in network settings
    conf.set_level(base_path + ['network-settings'])
    if conf.exists(['name-server']):
        for name_server in conf.return_values(['name-server']):
            if is_ipv4(name_server):
                sstp['dnsv4'].append(name_server)
            else:
                sstp['dnsv6'].append(name_server)

    if conf.exists(['mtu']):
        sstp['mtu'] = conf.return_value(['mtu'])

    #
    # read in PPP stuff
    conf.set_level(base_path + ['ppp-settings'])
    if conf.exists('mppe'):
        sstp['ppp_mppe'] = conf.return_value(['ppp-settings', 'mppe'])

    if conf.exists(['lcp-echo-failure']):
        sstp['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure'])

    if conf.exists(['lcp-echo-interval']):
        sstp['ppp_echo_interval'] = conf.return_value(['lcp-echo-interval'])

    if conf.exists(['lcp-echo-timeout']):
        sstp['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout'])

    return sstp
def get_config():
    conf = Config()
    base_path = ['service', 'ipoe-server']
    if not conf.exists(base_path):
        return None

    conf.set_level(base_path)
    ipoe = deepcopy(default_config_data)

    for interface in conf.list_nodes(['interface']):
        tmp = {
            'mode': 'L2',
            'name': interface,
            'shared': '1',
            # may need a config option, can be dhcpv4 or up for unclassified pkts
            'sess_start': 'dhcpv4',
            'range': None,
            'ifcfg': '1',
            'vlan_mon': []
        }

        conf.set_level(base_path + ['interface', interface])

        if conf.exists(['network-mode']):
            tmp['mode'] = conf.return_value(['network-mode'])

        if conf.exists(['network']):
            mode = conf.return_value(['network'])
            if mode == 'vlan':
                tmp['shared'] = '0'

                if conf.exists(['vlan-id']):
                    tmp['vlan_mon'] += conf.return_values(['vlan-id'])

                if conf.exists(['vlan-range']):
                    tmp['vlan_mon'] += conf.return_values(['vlan-range'])

        if conf.exists(['client-subnet']):
            tmp['range'] = conf.return_value(['client-subnet'])

        ipoe['interfaces'].append(tmp)

    conf.set_level(base_path)

    if conf.exists(['name-server']):
        for name_server in conf.return_values(['name-server']):
            if is_ipv4(name_server):
                ipoe['dnsv4'].append(name_server)
            else:
                ipoe['dnsv6'].append(name_server)

    if conf.exists(['authentication', 'mode']):
        ipoe['auth_mode'] = conf.return_value(['authentication', 'mode'])

    if conf.exists(['authentication', 'interface']):
        for interface in conf.list_nodes(['authentication', 'interface']):
            tmp = {'name': interface, 'mac': []}
            for mac in conf.list_nodes(
                ['authentication', 'interface', interface, 'mac-address']):
                client = {
                    'address': mac,
                    'rate_download': '',
                    'rate_upload': '',
                    'vlan_id': ''
                }
                conf.set_level(base_path + [
                    'authentication', 'interface', interface, 'mac-address',
                    mac
                ])

                if conf.exists(['rate-limit', 'download']):
                    client['rate_download'] = conf.return_value(
                        ['rate-limit', 'download'])

                if conf.exists(['rate-limit', 'upload']):
                    client['rate_upload'] = conf.return_value(
                        ['rate-limit', 'upload'])

                if conf.exists(['vlan-id']):
                    client['vlan'] = conf.return_value(['vlan-id'])

                tmp['mac'].append(client)

            ipoe['auth_interfaces'].append(tmp)

    conf.set_level(base_path)

    #
    # authentication mode radius servers and settings
    if conf.exists(['authentication', 'mode', 'radius']):
        for server in conf.list_nodes(['authentication', 'radius', 'server']):
            radius = {
                'server': server,
                'key': '',
                'fail_time': 0,
                'port': '1812'
            }

            conf.set_level(base_path +
                           ['authentication', 'radius', 'server', server])

            if conf.exists(['fail-time']):
                radius['fail-time'] = conf.return_value(['fail-time'])

            if conf.exists(['port']):
                radius['port'] = conf.return_value(['port'])

            if conf.exists(['key']):
                radius['key'] = conf.return_value(['key'])

            if not conf.exists(['disable']):
                ipoe['radius_server'].append(radius)

    #
    # advanced radius-setting
    conf.set_level(base_path + ['authentication', 'radius'])
    if conf.exists(['acct-timeout']):
        ipoe['radius_acct_tmo'] = conf.return_value(['acct-timeout'])

    if conf.exists(['max-try']):
        ipoe['radius_max_try'] = conf.return_value(['max-try'])

    if conf.exists(['timeout']):
        ipoe['radius_timeout'] = conf.return_value(['timeout'])

    if conf.exists(['nas-identifier']):
        ipoe['radius_nas_id'] = conf.return_value(['nas-identifier'])

    if conf.exists(['nas-ip-address']):
        ipoe['radius_nas_ip'] = conf.return_value(['nas-ip-address'])

    if conf.exists(['source-address']):
        ipoe['radius_source_address'] = conf.return_value(['source-address'])

    # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
    if conf.exists(['dynamic-author']):
        dae = {'port': '', 'server': '', 'key': ''}

        if conf.exists(['dynamic-author', 'server']):
            dae['server'] = conf.return_value(['dynamic-author', 'server'])

        if conf.exists(['dynamic-author', 'port']):
            dae['port'] = conf.return_value(['dynamic-author', 'port'])

        if conf.exists(['dynamic-author', 'key']):
            dae['key'] = conf.return_value(['dynamic-author', 'key'])

        ipoe['radius_dynamic_author'] = dae

    conf.set_level(base_path)
    if conf.exists(['client-ipv6-pool', 'prefix']):
        for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
            tmp = {'prefix': prefix, 'mask': '64'}

            if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']):
                tmp['mask'] = conf.return_value(
                    ['client-ipv6-pool', 'prefix', prefix, 'mask'])

            ipoe['client_ipv6_pool'].append(tmp)

    if conf.exists(['client-ipv6-pool', 'delegate']):
        for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']):
            tmp = {'prefix': prefix, 'mask': ''}

            if conf.exists(
                ['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']):
                tmp['mask'] = conf.return_value([
                    'client-ipv6-pool', 'delegate', prefix, 'delegation-prefix'
                ])

            ipoe['client_ipv6_delegate_prefix'].append(tmp)

    return ipoe
Exemple #9
0
def get_config():
    snmp = default_config_data
    conf = Config()
    if not conf.exists('service snmp'):
        return None
    else:
        if conf.exists('system ipv6 disable'):
            snmp['ipv6_enabled'] = False

        conf.set_level('service snmp')

    version_data = get_version_data()
    snmp['version'] = version_data['version']

    # create an internal snmpv3 user of the form 'vyosxxxxxxxxxxxxxxxx'
    # os.urandom(8) returns 8 bytes of random data
    snmp['vyos_user'] = '******' + hexlify(os.urandom(8)).decode('utf-8')
    snmp['vyos_user_pass'] = hexlify(os.urandom(16)).decode('utf-8')

    if conf.exists('community'):
        for name in conf.list_nodes('community'):
            community = {
                'name': name,
                'authorization': 'ro',
                'network_v4': [],
                'network_v6': [],
                'has_source': False
            }

            if conf.exists('community {0} authorization'.format(name)):
                community['authorization'] = conf.return_value(
                    'community {0} authorization'.format(name))

            # Subnet of SNMP client(s) allowed to contact system
            if conf.exists('community {0} network'.format(name)):
                for addr in conf.return_values(
                        'community {0} network'.format(name)):
                    if is_ipv4(addr):
                        community['network_v4'].append(addr)
                    else:
                        community['network_v6'].append(addr)

            # IP address of SNMP client allowed to contact system
            if conf.exists('community {0} client'.format(name)):
                for addr in conf.return_values(
                        'community {0} client'.format(name)):
                    if is_ipv4(addr):
                        community['network_v4'].append(addr)
                    else:
                        community['network_v6'].append(addr)

            if (len(community['network_v4']) > 0) or (len(
                    community['network_v6']) > 0):
                community['has_source'] = True

            snmp['communities'].append(community)

    if conf.exists('contact'):
        snmp['contact'] = conf.return_value('contact')

    if conf.exists('description'):
        snmp['description'] = conf.return_value('description')

    if conf.exists('listen-address'):
        for addr in conf.list_nodes('listen-address'):
            port = '161'
            if conf.exists('listen-address {0} port'.format(addr)):
                port = conf.return_value(
                    'listen-address {0} port'.format(addr))

            snmp['listen_address'].append((addr, port))

        # Always listen on localhost if an explicit address has been configured
        # This is a safety measure to not end up with invalid listen addresses
        # that are not configured on this system. See https://phabricator.vyos.net/T850
        if not '127.0.0.1' in conf.list_nodes('listen-address'):
            snmp['listen_address'].append(('127.0.0.1', '161'))

        if not '::1' in conf.list_nodes('listen-address'):
            snmp['listen_address'].append(('::1', '161'))

    if conf.exists('location'):
        snmp['location'] = conf.return_value('location')

    if conf.exists('smux-peer'):
        snmp['smux_peers'] = conf.return_values('smux-peer')

    if conf.exists('trap-source'):
        snmp['trap_source'] = conf.return_value('trap-source')

    if conf.exists('trap-target'):
        for target in conf.list_nodes('trap-target'):
            trap_tgt = {'target': target, 'community': '', 'port': ''}

            if conf.exists('trap-target {0} community'.format(target)):
                trap_tgt['community'] = conf.return_value(
                    'trap-target {0} community'.format(target))

            if conf.exists('trap-target {0} port'.format(target)):
                trap_tgt['port'] = conf.return_value(
                    'trap-target {0} port'.format(target))

            snmp['trap_targets'].append(trap_tgt)

    #
    # 'set service snmp script-extensions'
    #
    if conf.exists('script-extensions'):
        for extname in conf.list_nodes('script-extensions extension-name'):
            conf_script = conf.return_value(
                'script-extensions extension-name {} script'.format(extname))
            # if script has not absolute path, use pre configured path
            if "/" not in conf_script:
                conf_script = default_script_dir + conf_script

            extension = {'name': extname, 'script': conf_script}

            snmp['script_ext'].append(extension)

    #########################################################################
    #                ____  _   _ __  __ ____          _____                 #
    #               / ___|| \ | |  \/  |  _ \  __   _|___ /                 #
    #               \___ \|  \| | |\/| | |_) | \ \ / / |_ \                 #
    #                ___) | |\  | |  | |  __/   \ V / ___) |                #
    #               |____/|_| \_|_|  |_|_|       \_/ |____/                 #
    #                                                                       #
    #     now take care about the fancy SNMP v3 stuff, or bail out eraly    #
    #########################################################################
    if not conf.exists('v3'):
        return snmp
    else:
        snmp['v3_enabled'] = True

    # 'set service snmp v3 engineid'
    if conf.exists('v3 engineid'):
        snmp['v3_engineid'] = conf.return_value('v3 engineid')

    # 'set service snmp v3 group'
    if conf.exists('v3 group'):
        for group in conf.list_nodes('v3 group'):
            v3_group = {
                'name': group,
                'mode': 'ro',
                'seclevel': 'auth',
                'view': ''
            }

            if conf.exists('v3 group {0} mode'.format(group)):
                v3_group['mode'] = conf.return_value(
                    'v3 group {0} mode'.format(group))

            if conf.exists('v3 group {0} seclevel'.format(group)):
                v3_group['seclevel'] = conf.return_value(
                    'v3 group {0} seclevel'.format(group))

            if conf.exists('v3 group {0} view'.format(group)):
                v3_group['view'] = conf.return_value(
                    'v3 group {0} view'.format(group))

            snmp['v3_groups'].append(v3_group)

    # 'set service snmp v3 trap-target'
    if conf.exists('v3 trap-target'):
        for trap in conf.list_nodes('v3 trap-target'):
            trap_cfg = {
                'ipAddr': trap,
                'secName': '',
                'authProtocol': 'md5',
                'authPassword': '',
                'authMasterKey': '',
                'privProtocol': 'des',
                'privPassword': '',
                'privMasterKey': '',
                'ipProto': 'udp',
                'ipPort': '162',
                'type': '',
                'secLevel': 'noAuthNoPriv'
            }

            if conf.exists('v3 trap-target {0} user'.format(trap)):
                # Set the securityName used for authenticated SNMPv3 messages.
                trap_cfg['secName'] = conf.return_value(
                    'v3 trap-target {0} user'.format(trap))

            if conf.exists('v3 trap-target {0} auth type'.format(trap)):
                # Set the authentication protocol (MD5 or SHA) used for authenticated SNMPv3 messages
                # cmdline option '-a'
                trap_cfg['authProtocol'] = conf.return_value(
                    'v3 trap-target {0} auth type'.format(trap))

            if conf.exists(
                    'v3 trap-target {0} auth plaintext-key'.format(trap)):
                # Set the authentication pass phrase used for authenticated SNMPv3 messages.
                # cmdline option '-A'
                trap_cfg['authPassword'] = conf.return_value(
                    'v3 trap-target {0} auth plaintext-key'.format(trap))

            if conf.exists(
                    'v3 trap-target {0} auth encrypted-key'.format(trap)):
                # Sets the keys to be used for SNMPv3 transactions. These options allow you to set the master authentication keys.
                # cmdline option '-3m'
                trap_cfg['authMasterKey'] = conf.return_value(
                    'v3 trap-target {0} auth encrypted-key'.format(trap))

            if conf.exists('v3 trap-target {0} privacy type'.format(trap)):
                # Set the privacy protocol (DES or AES) used for encrypted SNMPv3 messages.
                # cmdline option '-x'
                trap_cfg['privProtocol'] = conf.return_value(
                    'v3 trap-target {0} privacy type'.format(trap))

            if conf.exists(
                    'v3 trap-target {0} privacy plaintext-key'.format(trap)):
                # Set the privacy pass phrase used for encrypted SNMPv3 messages.
                # cmdline option '-X'
                trap_cfg['privPassword'] = conf.return_value(
                    'v3 trap-target {0} privacy plaintext-key'.format(trap))

            if conf.exists(
                    'v3 trap-target {0} privacy encrypted-key'.format(trap)):
                # Sets the keys to be used for SNMPv3 transactions. These options allow you to set the master encryption keys.
                # cmdline option '-3M'
                trap_cfg['privMasterKey'] = conf.return_value(
                    'v3 trap-target {0} privacy encrypted-key'.format(trap))

            if conf.exists('v3 trap-target {0} protocol'.format(trap)):
                trap_cfg['ipProto'] = conf.return_value(
                    'v3 trap-target {0} protocol'.format(trap))

            if conf.exists('v3 trap-target {0} port'.format(trap)):
                trap_cfg['ipPort'] = conf.return_value(
                    'v3 trap-target {0} port'.format(trap))

            if conf.exists('v3 trap-target {0} type'.format(trap)):
                trap_cfg['type'] = conf.return_value(
                    'v3 trap-target {0} type'.format(trap))

            # Determine securityLevel used for SNMPv3 messages (noAuthNoPriv|authNoPriv|authPriv).
            # Appropriate pass phrase(s) must provided when using any level higher than noAuthNoPriv.
            if trap_cfg['authPassword'] or trap_cfg['authMasterKey']:
                if trap_cfg['privProtocol'] or trap_cfg['privPassword']:
                    trap_cfg['secLevel'] = 'authPriv'
                else:
                    trap_cfg['secLevel'] = 'authNoPriv'

            snmp['v3_traps'].append(trap_cfg)

    # 'set service snmp v3 user'
    if conf.exists('v3 user'):
        for user in conf.list_nodes('v3 user'):
            user_cfg = {
                'name': user,
                'authMasterKey': '',
                'authPassword': '',
                'authProtocol': 'md5',
                'authOID': 'none',
                'group': '',
                'mode': 'ro',
                'privMasterKey': '',
                'privPassword': '',
                'privOID': '',
                'privProtocol': 'des'
            }

            # v3 user {0} auth
            if conf.exists('v3 user {0} auth encrypted-key'.format(user)):
                user_cfg['authMasterKey'] = conf.return_value(
                    'v3 user {0} auth encrypted-key'.format(user))

            if conf.exists('v3 user {0} auth plaintext-key'.format(user)):
                user_cfg['authPassword'] = conf.return_value(
                    'v3 user {0} auth plaintext-key'.format(user))

            # load default value
            type = user_cfg['authProtocol']
            if conf.exists('v3 user {0} auth type'.format(user)):
                type = conf.return_value('v3 user {0} auth type'.format(user))

            # (re-)update with either default value or value from CLI
            user_cfg['authProtocol'] = type
            user_cfg['authOID'] = OIDs[type]

            # v3 user {0} group
            if conf.exists('v3 user {0} group'.format(user)):
                user_cfg['group'] = conf.return_value(
                    'v3 user {0} group'.format(user))

            # v3 user {0} mode
            if conf.exists('v3 user {0} mode'.format(user)):
                user_cfg['mode'] = conf.return_value(
                    'v3 user {0} mode'.format(user))

            # v3 user {0} privacy
            if conf.exists('v3 user {0} privacy encrypted-key'.format(user)):
                user_cfg['privMasterKey'] = conf.return_value(
                    'v3 user {0} privacy encrypted-key'.format(user))

            if conf.exists('v3 user {0} privacy plaintext-key'.format(user)):
                user_cfg['privPassword'] = conf.return_value(
                    'v3 user {0} privacy plaintext-key'.format(user))

            # load default value
            type = user_cfg['privProtocol']
            if conf.exists('v3 user {0} privacy type'.format(user)):
                type = conf.return_value(
                    'v3 user {0} privacy type'.format(user))

            # (re-)update with either default value or value from CLI
            user_cfg['privProtocol'] = type
            user_cfg['privOID'] = OIDs[type]

            snmp['v3_users'].append(user_cfg)

    # 'set service snmp v3 view'
    if conf.exists('v3 view'):
        for view in conf.list_nodes('v3 view'):
            view_cfg = {'name': view, 'oids': []}

            if conf.exists('v3 view {0} oid'.format(view)):
                for oid in conf.list_nodes('v3 view {0} oid'.format(view)):
                    oid_cfg = {'oid': oid}
                    view_cfg['oids'].append(oid_cfg)
            snmp['v3_views'].append(view_cfg)

    return snmp
Exemple #10
0
def verify(snmp):
    if snmp is None:
        # we can not delete SNMP when LLDP is configured with SNMP
        conf = Config()
        if conf.exists('service lldp snmp enable'):
            raise ConfigError(
                'Can not delete SNMP service, as LLDP still uses SNMP!')

        return None

    ### check if the configured script actually exist
    if snmp['script_ext']:
        for ext in snmp['script_ext']:
            if not os.path.isfile(ext['script']):
                print("WARNING: script: {} doesn't exist".format(
                    ext['script']))
            else:
                os.chmod(ext['script'],
                         S_IRWXU | S_IXGRP | S_IXOTH | S_IROTH | S_IRGRP)

    for listen in snmp['listen_address']:
        addr = listen[0]
        port = listen[1]

        if is_ipv4(addr):
            # example: udp:127.0.0.1:161
            listen = 'udp:' + addr + ':' + port
        elif snmp['ipv6_enabled']:
            # example: udp6:[::1]:161
            listen = 'udp6:' + '[' + addr + ']' + ':' + port

        # We only wan't to configure addresses that exist on the system.
        # Hint the user if they don't exist
        if is_addr_assigned(addr):
            snmp['listen_on'].append(listen)
        else:
            print('WARNING: SNMP listen address {0} not configured!'.format(
                addr))

    # bail out early if SNMP v3 is not configured
    if not snmp['v3_enabled']:
        return None

    if 'v3_groups' in snmp.keys():
        for group in snmp['v3_groups']:
            #
            # A view must exist prior to mapping it into a group
            #
            if 'view' in group.keys():
                error = True
                if 'v3_views' in snmp.keys():
                    for view in snmp['v3_views']:
                        if view['name'] == group['view']:
                            error = False
                if error:
                    raise ConfigError(
                        'You must create view "{0}" first'.format(
                            group['view']))
            else:
                raise ConfigError('"view" must be specified')

            if not 'mode' in group.keys():
                raise ConfigError('"mode" must be specified')

            if not 'seclevel' in group.keys():
                raise ConfigError('"seclevel" must be specified')

    if 'v3_traps' in snmp.keys():
        for trap in snmp['v3_traps']:
            if trap['authPassword'] and trap['authMasterKey']:
                raise ConfigError(
                    'Must specify only one of encrypted-key/plaintext-key for trap auth'
                )

            if trap['authPassword'] == '' and trap['authMasterKey'] == '':
                raise ConfigError(
                    'Must specify encrypted-key or plaintext-key for trap auth'
                )

            if trap['privPassword'] and trap['privMasterKey']:
                raise ConfigError(
                    'Must specify only one of encrypted-key/plaintext-key for trap privacy'
                )

            if trap['privPassword'] == '' and trap['privMasterKey'] == '':
                raise ConfigError(
                    'Must specify encrypted-key or plaintext-key for trap privacy'
                )

            if not 'type' in trap.keys():
                raise ConfigError('v3 trap: "type" must be specified')

            if not 'authPassword' and 'authMasterKey' in trap.keys():
                raise ConfigError('v3 trap: "auth" must be specified')

            if not 'authProtocol' in trap.keys():
                raise ConfigError('v3 trap: "protocol" must be specified')

            if not 'privPassword' and 'privMasterKey' in trap.keys():
                raise ConfigError('v3 trap: "user" must be specified')

    if 'v3_users' in snmp.keys():
        for user in snmp['v3_users']:
            #
            # Group must exist prior to mapping it into a group
            # seclevel will be extracted from group
            #
            if user['group']:
                error = True
                if 'v3_groups' in snmp.keys():
                    for group in snmp['v3_groups']:
                        if group['name'] == user['group']:
                            seclevel = group['seclevel']
                            error = False

                if error:
                    raise ConfigError(
                        'You must create group "{0}" first'.format(
                            user['group']))

            # Depending on the configured security level
            # the user has to provide additional info
            if user['authPassword'] and user['authMasterKey']:
                raise ConfigError(
                    'Can not mix "encrypted-key" and "plaintext-key" for user auth'
                )

            if (not user['authPassword'] and not user['authMasterKey']):
                raise ConfigError(
                    'Must specify encrypted-key or plaintext-key for user auth'
                )

            if user['privPassword'] and user['privMasterKey']:
                raise ConfigError(
                    'Can not mix "encrypted-key" and "plaintext-key" for user privacy'
                )

            if user['privPassword'] == '' and user['privMasterKey'] == '':
                raise ConfigError(
                    'Must specify encrypted-key or plaintext-key for user privacy'
                )

            if user['mode'] == '':
                raise ConfigError('Must specify user mode ro/rw')

    if 'v3_views' in snmp.keys():
        for view in snmp['v3_views']:
            if not view['oids']:
                raise ConfigError('Must configure an oid')

    return None
Exemple #11
0
def get_config():
    conf = Config()
    base_path = ['vpn', 'l2tp', 'remote-access']
    if not conf.exists(base_path):
        return None

    conf.set_level(base_path)
    l2tp = deepcopy(default_config_data)

    cpu = os.cpu_count()
    if cpu > 1:
        l2tp['thread_cnt'] = int(cpu/2)

    ### general options ###
    if conf.exists(['name-server']):
        for name_server in conf.return_values(['name-server']):
            if is_ipv4(name_server):
                l2tp['dnsv4'].append(name_server)
            else:
                l2tp['dnsv6'].append(name_server)

    if conf.exists(['wins-server']):
        l2tp['wins'] = conf.return_values(['wins-server'])

    if conf.exists('outside-address'):
        l2tp['outside_addr'] = conf.return_value('outside-address')

    if conf.exists(['authentication', 'mode']):
        l2tp['auth_mode'] = conf.return_value(['authentication', 'mode'])

    if conf.exists(['authentication', 'protocols']):
        auth_mods = {
            'pap': 'auth_pap',
            'chap': 'auth_chap_md5',
            'mschap': 'auth_mschap_v1',
            'mschap-v2': 'auth_mschap_v2'
        }

        for proto in conf.return_values(['authentication', 'protocols']):
            l2tp['auth_proto'].append(auth_mods[proto])

    if conf.exists(['authentication', 'mppe']):
        l2tp['auth_ppp_mppe'] = conf.return_value(['authentication', 'mppe'])

    #
    # local auth
    if conf.exists(['authentication', 'local-users']):
        for username in conf.list_nodes(['authentication', 'local-users', 'username']):
            user = {
                'name' : username,
                'password' : '',
                'state' : 'enabled',
                'ip' : '*',
                'upload' : None,
                'download' : None
            }

            conf.set_level(base_path + ['authentication', 'local-users', 'username', username])

            if conf.exists(['password']):
                user['password'] = conf.return_value(['password'])

            if conf.exists(['disable']):
                user['state'] = 'disable'

            if conf.exists(['static-ip']):
                user['ip'] = conf.return_value(['static-ip'])

            if conf.exists(['rate-limit', 'download']):
                user['download'] = conf.return_value(['rate-limit', 'download'])

            if conf.exists(['rate-limit', 'upload']):
                user['upload'] = conf.return_value(['rate-limit', 'upload'])

            l2tp['local_users'].append(user)

    #
    # RADIUS auth and settings
    conf.set_level(base_path + ['authentication', 'radius'])
    if conf.exists(['server']):
        for server in conf.list_nodes(['server']):
            radius = {
                'server' : server,
                'key' : '',
                'fail_time' : 0,
                'port' : '1812'
            }

            conf.set_level(base_path + ['authentication', 'radius', 'server', server])

            if conf.exists(['fail-time']):
                radius['fail-time'] = conf.return_value(['fail-time'])

            if conf.exists(['port']):
                radius['port'] = conf.return_value(['port'])

            if conf.exists(['key']):
                radius['key'] = conf.return_value(['key'])

            if not conf.exists(['disable']):
                l2tp['radius_server'].append(radius)

        #
        # advanced radius-setting
        conf.set_level(base_path + ['authentication', 'radius'])

        if conf.exists(['acct-timeout']):
            l2tp['radius_acct_tmo'] = conf.return_value(['acct-timeout'])

        if conf.exists(['max-try']):
            l2tp['radius_max_try'] = conf.return_value(['max-try'])

        if conf.exists(['timeout']):
            l2tp['radius_timeout'] = conf.return_value(['timeout'])

        if conf.exists(['nas-identifier']):
            l2tp['radius_nas_id'] = conf.return_value(['nas-identifier'])

        if conf.exists(['nas-ip-address']):
            l2tp['radius_nas_ip'] = conf.return_value(['nas-ip-address'])

        if conf.exists(['source-address']):
            l2tp['radius_source_address'] = conf.return_value(['source-address'])

        # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
        if conf.exists(['dynamic-author']):
            dae = {
                'port' : '',
                'server' : '',
                'key' : ''
            }

            if conf.exists(['dynamic-author', 'server']):
                dae['server'] = conf.return_value(['dynamic-author', 'server'])

            if conf.exists(['dynamic-author', 'port']):
                dae['port'] = conf.return_value(['dynamic-author', 'port'])

            if conf.exists(['dynamic-author', 'key']):
                dae['key'] = conf.return_value(['dynamic-author', 'key'])

            l2tp['radius_dynamic_author'] = dae

        if conf.exists(['rate-limit', 'enable']):
            l2tp['radius_shaper_attr'] = 'Filter-Id'
            c_attr = ['rate-limit', 'enable', 'attribute']
            if conf.exists(c_attr):
                l2tp['radius_shaper_attr'] = conf.return_value(c_attr)

            c_vendor = ['rate-limit', 'enable', 'vendor']
            if conf.exists(c_vendor):
                l2tp['radius_shaper_vendor'] = conf.return_value(c_vendor)

    conf.set_level(base_path)
    if conf.exists(['client-ip-pool']):
        if conf.exists(['client-ip-pool', 'start']) and conf.exists(['client-ip-pool', 'stop']):
            start = conf.return_value(['client-ip-pool', 'start'])
            stop  = conf.return_value(['client-ip-pool', 'stop'])
            l2tp['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0)

    if conf.exists(['client-ip-pool', 'subnet']):
        l2tp['client_ip_subnets'] = conf.return_values(['client-ip-pool', 'subnet'])

    if conf.exists(['client-ipv6-pool', 'prefix']):
        l2tp['ip6_column'].append('ip6')
        for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
            tmp = {
                'prefix': prefix,
                'mask': '64'
            }

            if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']):
                tmp['mask'] = conf.return_value(['client-ipv6-pool', 'prefix', prefix, 'mask'])

            l2tp['client_ipv6_pool'].append(tmp)

    if conf.exists(['client-ipv6-pool', 'delegate']):
        l2tp['ip6_column'].append('ip6-db')
        for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']):
            tmp = {
                'prefix': prefix,
                'mask': ''
            }

            if conf.exists(['client-ipv6-pool', 'delegate', prefix, 'mask']):
                tmp['mask'] = conf.return_value(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix'])

            l2tp['client_ipv6_delegate_prefix'].append(tmp)

    if conf.exists(['mtu']):
        l2tp['mtu'] = conf.return_value(['mtu'])

    # gateway address
    if conf.exists(['gateway-address']):
        l2tp['gateway_address'] = conf.return_value(['gateway-address'])
    else:
        # calculate gw-ip-address
        if conf.exists(['client-ip-pool', 'start']):
            # use start ip as gw-ip-address
            l2tp['gateway_address'] = conf.return_value(['client-ip-pool', 'start'])

        elif conf.exists(['client-ip-pool', 'subnet']):
            # use first ip address from first defined pool
            subnet = conf.return_values(['client-ip-pool', 'subnet'])[0]
            subnet = ip_network(subnet)
            l2tp['gateway_address'] = str(list(subnet.hosts())[0])

    # LNS secret
    if conf.exists(['lns', 'shared-secret']):
        l2tp['lns_shared_secret'] = conf.return_value(['lns', 'shared-secret'])

    if conf.exists(['ccp-disable']):
        l2tp[['ccp_disable']] = True

    # PPP options
    if conf.exists(['idle']):
        l2tp['ppp_echo_timeout'] = conf.return_value(['idle'])

    if conf.exists(['ppp-options', 'lcp-echo-failure']):
        l2tp['ppp_echo_failure'] = conf.return_value(['ppp-options', 'lcp-echo-failure'])

    if conf.exists(['ppp-options', 'lcp-echo-interval']):
        l2tp['ppp_echo_interval'] = conf.return_value(['ppp-options', 'lcp-echo-interval'])

    return l2tp
def get_config():
    conf = Config()
    base_path = ['service', 'pppoe-server']
    if not conf.exists(base_path):
        return None

    conf.set_level(base_path)
    pppoe = deepcopy(default_config_data)

    # general options
    if conf.exists(['access-concentrator']):
        pppoe['concentrator'] = conf.return_value(['access-concentrator'])

    if conf.exists(['service-name']):
        pppoe['svc_name'] = conf.return_values(['service-name'])

    if conf.exists(['interface']):
        for interface in conf.list_nodes(['interface']):
            conf.set_level(base_path + ['interface', interface])
            tmp = {'name': interface, 'vlans': []}

            if conf.exists(['vlan-id']):
                tmp['vlans'] += conf.return_values(['vlan-id'])

            if conf.exists(['vlan-range']):
                tmp['vlans'] += conf.return_values(['vlan-range'])

            pppoe['interfaces'].append(tmp)

    conf.set_level(base_path)

    if conf.exists(['local-ip']):
        pppoe['ppp_gw'] = conf.return_value(['local-ip'])

    if conf.exists(['name-server']):
        for name_server in conf.return_values(['name-server']):
            if is_ipv4(name_server):
                pppoe['dnsv4'].append(name_server)
            else:
                pppoe['dnsv6'].append(name_server)

    if conf.exists(['wins-server']):
        pppoe['wins'] = conf.return_values(['wins-server'])

    if conf.exists(['client-ip-pool']):
        if conf.exists(['client-ip-pool', 'start']) and conf.exists(
            ['client-ip-pool', 'stop']):
            start = conf.return_value(['client-ip-pool', 'start'])
            stop = conf.return_value(['client-ip-pool', 'stop'])
            pppoe['client_ip_pool'] = start + '-' + re.search('[0-9]+$',
                                                              stop).group(0)

        if conf.exists(['client-ip-pool', 'subnet']):
            pppoe['client_ip_subnets'] = conf.return_values(
                ['client-ip-pool', 'subnet'])

    if conf.exists(['client-ipv6-pool', 'prefix']):
        for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
            tmp = {'prefix': prefix, 'mask': '64'}

            if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']):
                tmp['mask'] = conf.return_value(
                    ['client-ipv6-pool', 'prefix', prefix, 'mask'])

            pppoe['client_ipv6_pool'].append(tmp)

    if conf.exists(['client-ipv6-pool', 'delegate']):
        for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']):
            tmp = {'prefix': prefix, 'mask': ''}

            if conf.exists(
                ['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']):
                tmp['mask'] = conf.return_value([
                    'client-ipv6-pool', 'delegate', prefix, 'delegation-prefix'
                ])

            pppoe['client_ipv6_delegate_prefix'].append(tmp)

    if conf.exists(['limits']):
        if conf.exists(['limits', 'burst']):
            pppoe['limits_burst'] = conf.return_value(['limits', 'burst'])

        if conf.exists(['limits', 'connection-limit']):
            pppoe['limits_connections'] = conf.return_value(
                ['limits', 'connection-limit'])

        if conf.exists(['limits', 'timeout']):
            pppoe['limits_timeout'] = conf.return_value(['limits', 'timeout'])

    if conf.exists(['snmp']):
        pppoe['snmp'] = True

    if conf.exists(['snmp', 'master-agent']):
        pppoe['snmp'] = 'enable-ma'

    # authentication mode local
    if conf.exists(['authentication', 'mode']):
        pppoe['auth_mode'] = conf.return_value(['authentication', 'mode'])

    if conf.exists(['authentication', 'local-users']):
        for username in conf.list_nodes(
            ['authentication', 'local-users', 'username']):
            user = {
                'name': username,
                'password': '',
                'state': 'enabled',
                'ip': '*',
                'upload': None,
                'download': None
            }
            conf.set_level(
                base_path +
                ['authentication', 'local-users', 'username', username])

            if conf.exists(['password']):
                user['password'] = conf.return_value(['password'])

            if conf.exists(['disable']):
                user['state'] = 'disable'

            if conf.exists(['static-ip']):
                user['ip'] = conf.return_value(['static-ip'])

            if conf.exists(['rate-limit', 'download']):
                user['download'] = conf.return_value(
                    ['rate-limit', 'download'])

            if conf.exists(['rate-limit', 'upload']):
                user['upload'] = conf.return_value(['rate-limit', 'upload'])

            pppoe['local_users'].append(user)

    conf.set_level(base_path)

    if conf.exists(['authentication', 'protocols']):
        auth_mods = {
            'mschap-v2': 'auth_mschap_v2',
            'mschap': 'auth_mschap_v1',
            'chap': 'auth_chap_md5',
            'pap': 'auth_pap'
        }

        pppoe['auth_proto'] = []
        for proto in conf.return_values(['authentication', 'protocols']):
            pppoe['auth_proto'].append(auth_mods[proto])

    #
    # authentication mode radius servers and settings
    if conf.exists(['authentication', 'mode', 'radius']):

        for server in conf.list_nodes(['authentication', 'radius', 'server']):
            radius = {
                'server': server,
                'key': '',
                'fail_time': 0,
                'port': '1812'
            }

            conf.set_level(base_path +
                           ['authentication', 'radius', 'server', server])

            if conf.exists(['fail-time']):
                radius['fail-time'] = conf.return_value(['fail-time'])

            if conf.exists(['port']):
                radius['port'] = conf.return_value(['port'])

            if conf.exists(['key']):
                radius['key'] = conf.return_value(['key'])

            if not conf.exists(['disable']):
                pppoe['radius_server'].append(radius)

        #
        # advanced radius-setting
        conf.set_level(base_path + ['authentication', 'radius'])

        if conf.exists(['acct-timeout']):
            pppoe['radius_acct_tmo'] = conf.return_value(['acct-timeout'])

        if conf.exists(['max-try']):
            pppoe['radius_max_try'] = conf.return_value(['max-try'])

        if conf.exists(['timeout']):
            pppoe['radius_timeout'] = conf.return_value(['timeout'])

        if conf.exists(['nas-identifier']):
            pppoe['radius_nas_id'] = conf.return_value(['nas-identifier'])

        if conf.exists(['nas-ip-address']):
            pppoe['radius_nas_ip'] = conf.return_value(['nas-ip-address'])

        if conf.exists(['source-address']):
            pppoe['radius_source_address'] = conf.return_value(
                ['source-address'])

        # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
        if conf.exists(['dynamic-author']):
            dae = {'port': '', 'server': '', 'key': ''}

            if conf.exists(['dynamic-author', 'server']):
                dae['server'] = conf.return_value(['dynamic-author', 'server'])

            if conf.exists(['dynamic-author', 'port']):
                dae['port'] = conf.return_value(['dynamic-author', 'port'])

            if conf.exists(['dynamic-author', 'key']):
                dae['key'] = conf.return_value(['dynamic-author', 'key'])

            pppoe['radius_dynamic_author'] = dae

        # RADIUS based rate-limiter
        if conf.exists(['rate-limit', 'enable']):
            pppoe['radius_shaper_attr'] = 'Filter-Id'
            c_attr = ['rate-limit', 'enable', 'attribute']
            if conf.exists(c_attr):
                pppoe['radius_shaper_attr'] = conf.return_value(c_attr)

            c_vendor = ['rate-limit', 'enable', 'vendor']
            if conf.exists(c_vendor):
                pppoe['radius_shaper_vendor'] = conf.return_value(c_vendor)

    # re-set config level
    conf.set_level(base_path)

    if conf.exists(['mtu']):
        pppoe['mtu'] = conf.return_value(['mtu'])

    if conf.exists(['session-control']):
        pppoe['sesscrtl'] = conf.return_value(['session-control'])

    # ppp_options
    if conf.exists(['ppp-options']):
        conf.set_level(base_path + ['ppp-options'])

        if conf.exists(['ccp']):
            pppoe['ppp_ccp'] = True

        if conf.exists(['ipv4']):
            pppoe['ppp_ipv4'] = conf.return_value(['ipv4'])

        if conf.exists(['ipv6']):
            pppoe['ppp_ipv6'] = conf.return_value(['ipv6'])

        if conf.exists(['ipv6-accept-peer-intf-id']):
            pppoe['ppp_ipv6_peer_intf_id'] = True

        if conf.exists(['ipv6-intf-id']):
            pppoe['ppp_ipv6_intf_id'] = conf.return_value(['ipv6-intf-id'])

        if conf.exists(['ipv6-peer-intf-id']):
            pppoe['ppp_ipv6_peer_intf_id'] = conf.return_value(
                ['ipv6-peer-intf-id'])

        if conf.exists(['lcp-echo-failure']):
            pppoe['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure'])

        if conf.exists(['lcp-echo-failure']):
            pppoe['ppp_echo_interval'] = conf.return_value(
                ['lcp-echo-failure'])

        if conf.exists(['lcp-echo-timeout']):
            pppoe['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout'])

        if conf.exists(['min-mtu']):
            pppoe['ppp_min_mtu'] = conf.return_value(['min-mtu'])

        if conf.exists(['mppe']):
            pppoe['ppp_mppe'] = conf.return_value(['mppe'])

        if conf.exists(['mru']):
            pppoe['ppp_mru'] = conf.return_value(['mru'])

    if conf.exists(['pado-delay']):
        pppoe['pado_delay'] = '0'
        a = {}
        for id in conf.list_nodes(['pado-delay']):
            if not conf.return_value(['pado-delay', id, 'sessions']):
                a[id] = 0
            else:
                a[id] = conf.return_value(['pado-delay', id, 'sessions'])

        for k in sorted(a.keys()):
            if k != sorted(a.keys())[-1]:
                pppoe['pado_delay'] += ",{0}:{1}".format(k, a[k])
            else:
                pppoe['pado_delay'] += ",{0}:{1}".format('-1', a[k])

    return pppoe
Exemple #13
0
def get_config():
    openvpn = deepcopy(default_config_data)
    conf = Config()

    # determine tagNode instance
    if 'VYOS_TAGNODE_VALUE' not in os.environ:
        raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified')

    openvpn['intf'] = os.environ['VYOS_TAGNODE_VALUE']
    openvpn['auth_user_pass_file'] = f"/run/openvpn/{openvpn['intf']}.pw"

    # check if interface is member of a bridge
    openvpn['is_bridge_member'] = is_member(conf, openvpn['intf'], 'bridge')

    # Check if interface instance has been removed
    if not conf.exists('interfaces openvpn ' + openvpn['intf']):
        openvpn['deleted'] = True
        return openvpn

    # bridged server should not have a pool by default (but can be specified manually)
    if openvpn['is_bridge_member']:
        openvpn['server_pool'] = False
        openvpn['server_ipv6_pool'] = False

    # set configuration level
    conf.set_level('interfaces openvpn ' + openvpn['intf'])

    # retrieve authentication options - username
    if conf.exists('authentication username'):
        openvpn['auth_user'] = conf.return_value('authentication username')
        openvpn['auth'] = True

    # retrieve authentication options - username
    if conf.exists('authentication password'):
        openvpn['auth_pass'] = conf.return_value('authentication password')
        openvpn['auth'] = True

    # retrieve interface description
    if conf.exists('description'):
        openvpn['description'] = conf.return_value('description')

    # interface device-type
    if conf.exists('device-type'):
        openvpn['type'] = conf.return_value('device-type')

    # disable interface
    if conf.exists('disable'):
        openvpn['disable'] = True

    # data encryption algorithm cipher
    if conf.exists('encryption cipher'):
        openvpn['encryption'] = conf.return_value('encryption cipher')

    # disable ncp-ciphers support
    if conf.exists('encryption disable-ncp'):
        openvpn['disable_ncp'] = True

    # data encryption algorithm ncp-list
    if conf.exists('encryption ncp-ciphers'):
        _ncp_ciphers = []
        for enc in conf.return_values('encryption ncp-ciphers'):
            if enc == 'des':
                _ncp_ciphers.append('des-cbc')
                _ncp_ciphers.append('DES-CBC')
            elif enc == '3des':
                _ncp_ciphers.append('des-ede3-cbc')
                _ncp_ciphers.append('DES-EDE3-CBC')
            elif enc == 'aes128':
                _ncp_ciphers.append('aes-128-cbc')
                _ncp_ciphers.append('AES-128-CBC')
            elif enc == 'aes128gcm':
                _ncp_ciphers.append('aes-128-gcm')
                _ncp_ciphers.append('AES-128-GCM')
            elif enc == 'aes192':
                _ncp_ciphers.append('aes-192-cbc')
                _ncp_ciphers.append('AES-192-CBC')
            elif enc == 'aes192gcm':
                _ncp_ciphers.append('aes-192-gcm')
                _ncp_ciphers.append('AES-192-GCM')
            elif enc == 'aes256':
                _ncp_ciphers.append('aes-256-cbc')
                _ncp_ciphers.append('AES-256-CBC')
            elif enc == 'aes256gcm':
                _ncp_ciphers.append('aes-256-gcm')
                _ncp_ciphers.append('AES-256-GCM')
        openvpn['ncp_ciphers'] = ':'.join(_ncp_ciphers)

    # hash algorithm
    if conf.exists('hash'):
        openvpn['hash'] = conf.return_value('hash')

    # Maximum number of keepalive packet failures
    if conf.exists('keep-alive failure-count') and conf.exists(
            'keep-alive interval'):
        fail_count = conf.return_value('keep-alive failure-count')
        interval = conf.return_value('keep-alive interval')
        openvpn['ping_interval'] = interval
        openvpn['ping_restart'] = int(interval) * int(fail_count)

    # Local IP address of tunnel - even as it is a tag node - we can only work
    # on the first address
    if conf.exists('local-address'):
        for tmp in conf.list_nodes('local-address'):
            tmp_ip = ip_address(tmp)
            if tmp_ip.version == 4:
                openvpn['local_address'].append(tmp)
                if conf.exists('local-address {} subnet-mask'.format(tmp)):
                    openvpn['local_address_subnet'] = conf.return_value(
                        'local-address {} subnet-mask'.format(tmp))
            elif tmp_ip.version == 6:
                # input IPv6 address could be expanded so get the compressed version
                openvpn['ipv6_local_address'].append(str(tmp_ip))

    # Local IP address to accept connections
    if conf.exists('local-host'):
        openvpn['local_host'] = conf.return_value('local-host')

    # Local port number to accept connections
    if conf.exists('local-port'):
        openvpn['local_port'] = conf.return_value('local-port')

    # Enable acquisition of IPv6 address using stateless autoconfig (SLAAC)
    if conf.exists('ipv6 address autoconf'):
        openvpn['ipv6_autoconf'] = 1

    # Get prefixes for IPv6 addressing based on MAC address (EUI-64)
    if conf.exists('ipv6 address eui64'):
        openvpn['ipv6_eui64_prefix'] = conf.return_values('ipv6 address eui64')

    # Determine currently effective EUI64 addresses - to determine which
    # address is no longer valid and needs to be removed
    eff_addr = conf.return_effective_values('ipv6 address eui64')
    openvpn['ipv6_eui64_prefix_remove'] = list_diff(
        eff_addr, openvpn['ipv6_eui64_prefix'])

    # Remove the default link-local address if set.
    if conf.exists('ipv6 address no-default-link-local'):
        openvpn['ipv6_eui64_prefix_remove'].append('fe80::/64')
    else:
        # add the link-local by default to make IPv6 work
        openvpn['ipv6_eui64_prefix'].append('fe80::/64')

    # Disable IPv6 forwarding on this interface
    if conf.exists('ipv6 disable-forwarding'):
        openvpn['ipv6_forwarding'] = 0

    # IPv6 Duplicate Address Detection (DAD) tries
    if conf.exists('ipv6 dup-addr-detect-transmits'):
        openvpn['ipv6_dup_addr_detect'] = int(
            conf.return_value('ipv6 dup-addr-detect-transmits'))

    # to make IPv6 SLAAC and DHCPv6 work with forwarding=1,
    # accept_ra must be 2
    if openvpn['ipv6_autoconf'] or 'dhcpv6' in openvpn['address']:
        openvpn['ipv6_accept_ra'] = 2

    # OpenVPN operation mode
    if conf.exists('mode'):
        openvpn['mode'] = conf.return_value('mode')

    # Additional OpenVPN options
    if conf.exists('openvpn-option'):
        openvpn['options'] = conf.return_values('openvpn-option')

    # Do not close and reopen interface
    if conf.exists('persistent-tunnel'):
        openvpn['persistent_tunnel'] = True

    # Communication protocol
    if conf.exists('protocol'):
        openvpn['protocol'] = conf.return_value('protocol')

    # IP address of remote end of tunnel
    if conf.exists('remote-address'):
        for tmp in conf.return_values('remote-address'):
            tmp_ip = ip_address(tmp)
            if tmp_ip.version == 4:
                openvpn['remote_address'].append(tmp)
            elif tmp_ip.version == 6:
                openvpn['ipv6_remote_address'].append(str(tmp_ip))

    # Remote host to connect to (dynamic if not set)
    if conf.exists('remote-host'):
        openvpn['remote_host'] = conf.return_values('remote-host')

    # Remote port number to connect to
    if conf.exists('remote-port'):
        openvpn['remote_port'] = conf.return_value('remote-port')

    # OpenVPN tunnel to be used as the default route
    # see https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/
    # redirect-gateway flags
    if conf.exists('replace-default-route'):
        openvpn['redirect_gateway'] = 'def1'

    if conf.exists('replace-default-route local'):
        openvpn['redirect_gateway'] = 'local def1'

    # Topology for clients
    if conf.exists('server topology'):
        openvpn['server_topology'] = conf.return_value('server topology')

    # Server-mode subnet (from which client IPs are allocated)
    server_network_v4 = None
    server_network_v6 = None
    if conf.exists('server subnet'):
        for tmp in conf.return_values('server subnet'):
            tmp_ip = ip_network(tmp)
            if tmp_ip.version == 4:
                server_network_v4 = tmp_ip
                # convert the network to format: "192.0.2.0 255.255.255.0" for later use in template
                openvpn['server_subnet'].append(
                    tmp_ip.with_netmask.replace(r'/', ' '))
            elif tmp_ip.version == 6:
                server_network_v6 = tmp_ip
                openvpn['server_ipv6_subnet'].append(str(tmp_ip))

    # Client-specific settings
    for client in conf.list_nodes('server client'):
        # set configuration level
        conf.set_level('interfaces openvpn ' + openvpn['intf'] +
                       ' server client ' + client)
        data = {
            'name': client,
            'disable': False,
            'ip': [],
            'ipv6_ip': [],
            'ipv6_remote': '',
            'ipv6_push_route': [],
            'ipv6_subnet': [],
            'push_route': [],
            'subnet': [],
            'remote_netmask': ''
        }

        # Option to disable client connection
        if conf.exists('disable'):
            data['disable'] = True

        # IP address of the client
        for tmp in conf.return_values('ip'):
            tmp_ip = ip_address(tmp)
            if tmp_ip.version == 4:
                data['ip'].append(tmp)
            elif tmp_ip.version == 6:
                data['ipv6_ip'].append(str(tmp_ip))

        # Route to be pushed to the client
        for tmp in conf.return_values('push-route'):
            tmp_ip = ip_network(tmp)
            if tmp_ip.version == 4:
                data['push_route'].append(
                    tmp_ip.with_netmask.replace(r'/', ' '))
            elif tmp_ip.version == 6:
                data['ipv6_push_route'].append(str(tmp_ip))

        # Subnet belonging to the client
        for tmp in conf.return_values('subnet'):
            tmp_ip = ip_network(tmp)
            if tmp_ip.version == 4:
                data['subnet'].append(tmp_ip.with_netmask.replace(r'/', ' '))
            elif tmp_ip.version == 6:
                data['ipv6_subnet'].append(str(tmp_ip))

        # Append to global client list
        openvpn['client'].append(data)

    # re-set configuration level
    conf.set_level('interfaces openvpn ' + openvpn['intf'])

    # Server client IP pool
    if conf.exists('server client-ip-pool'):
        conf.set_level('interfaces openvpn ' + openvpn['intf'] +
                       ' server client-ip-pool')

        # enable or disable server_pool where necessary
        # default is enabled, or disabled in bridge mode
        openvpn['server_pool'] = not conf.exists('disable')

        if conf.exists('start'):
            openvpn['server_pool_start'] = conf.return_value('start')

        if conf.exists('stop'):
            openvpn['server_pool_stop'] = conf.return_value('stop')

        if conf.exists('netmask'):
            openvpn['server_pool_netmask'] = conf.return_value('netmask')

        conf.set_level('interfaces openvpn ' + openvpn['intf'])

    # Server client IPv6 pool
    if conf.exists('server client-ipv6-pool'):
        conf.set_level('interfaces openvpn ' + openvpn['intf'] +
                       ' server client-ipv6-pool')
        openvpn['server_ipv6_pool'] = not conf.exists('disable')
        if conf.exists('base'):
            tmp = conf.return_value('base').split('/')
            openvpn['server_ipv6_pool_base'] = str(IPv6Address(tmp[0]))
            if 1 < len(tmp):
                openvpn['server_ipv6_pool_prefixlen'] = tmp[1]

        conf.set_level('interfaces openvpn ' + openvpn['intf'])

    # DNS suffix to be pushed to all clients
    if conf.exists('server domain-name'):
        openvpn['server_domain'] = conf.return_value('server domain-name')

    # Number of maximum client connections
    if conf.exists('server max-connections'):
        openvpn['server_max_conn'] = conf.return_value(
            'server max-connections')

    # Domain Name Server (DNS)
    if conf.exists('server name-server'):
        for tmp in conf.return_values('server name-server'):
            tmp_ip = ip_address(tmp)
            if tmp_ip.version == 4:
                openvpn['server_dns_nameserver'].append(tmp)
            elif tmp_ip.version == 6:
                openvpn['server_ipv6_dns_nameserver'].append(str(tmp_ip))

    # Route to be pushed to all clients
    if conf.exists('server push-route'):
        for tmp in conf.return_values('server push-route'):
            tmp_ip = ip_network(tmp)
            if tmp_ip.version == 4:
                openvpn['server_push_route'].append(
                    tmp_ip.with_netmask.replace(r'/', ' '))
            elif tmp_ip.version == 6:
                openvpn['server_ipv6_push_route'].append(str(tmp_ip))

    # Reject connections from clients that are not explicitly configured
    if conf.exists('server reject-unconfigured-clients'):
        openvpn['server_reject_unconfigured'] = True

    # File containing TLS auth static key
    if conf.exists('tls auth-file'):
        openvpn['tls_auth'] = conf.return_value('tls auth-file')
        openvpn['tls'] = True

    # File containing certificate for Certificate Authority (CA)
    if conf.exists('tls ca-cert-file'):
        openvpn['tls_ca_cert'] = conf.return_value('tls ca-cert-file')
        openvpn['tls'] = True

    # File containing certificate for this host
    if conf.exists('tls cert-file'):
        openvpn['tls_cert'] = conf.return_value('tls cert-file')
        openvpn['tls'] = True

    # File containing certificate revocation list (CRL) for this host
    if conf.exists('tls crl-file'):
        openvpn['tls_crl'] = conf.return_value('tls crl-file')
        openvpn['tls'] = True

    # File containing Diffie Hellman parameters (server only)
    if conf.exists('tls dh-file'):
        openvpn['tls_dh'] = conf.return_value('tls dh-file')
        openvpn['tls'] = True

    # File containing this host's private key
    if conf.exists('tls key-file'):
        openvpn['tls_key'] = conf.return_value('tls key-file')
        openvpn['tls'] = True

    # File containing key to encrypt control channel packets
    if conf.exists('tls crypt-file'):
        openvpn['tls_crypt'] = conf.return_value('tls crypt-file')
        openvpn['tls'] = True

    # Role in TLS negotiation
    if conf.exists('tls role'):
        openvpn['tls_role'] = conf.return_value('tls role')
        openvpn['tls'] = True

    # Minimum required TLS version
    if conf.exists('tls tls-version-min'):
        openvpn['tls_version_min'] = conf.return_value('tls tls-version-min')
        openvpn['tls'] = True

    if conf.exists('shared-secret-key-file'):
        openvpn['shared_secret_file'] = conf.return_value(
            'shared-secret-key-file')

    if conf.exists('use-lzo-compression'):
        openvpn['compress_lzo'] = True

    # Special case when using EC certificates:
    # if key-file is EC and dh-file is unset, set tls_dh to 'none'
    if not openvpn['tls_dh'] and openvpn['tls_key'] and checkCertHeader(
            '-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']):
        openvpn['tls_dh'] = 'none'

    # set default server topology to net30
    if openvpn['mode'] == 'server' and not openvpn['server_topology']:
        openvpn['server_topology'] = 'net30'

    # Convert protocol to real protocol used by openvpn.
    # To make openvpn listen on both IPv4 and IPv6 we must use *6 protocols
    # (https://community.openvpn.net/openvpn/ticket/360), unless the local-host
    # or each of the remote-host in client mode is IPv4
    # in which case it must use the standard protocols.
    if openvpn['protocol'] == 'tcp-active':
        openvpn['protocol_real'] = 'tcp6-client'
    elif openvpn['protocol'] == 'tcp-passive':
        openvpn['protocol_real'] = 'tcp6-server'
    else:
        openvpn['protocol_real'] = 'udp6'

    if (is_ipv4(openvpn['local_host']) or
            # in client mode test all the remotes instead
        (openvpn['mode'] == 'client'
         and all([is_ipv4(h) for h in openvpn['remote_host']]))):
        # takes out the '6'
        openvpn['protocol_real'] = openvpn['protocol_real'][:3] + openvpn[
            'protocol_real'][4:]

    # Set defaults where necessary.
    # If any of the input parameters are wrong,
    # this will return False and no defaults will be set.
    if server_network_v4 and openvpn['server_topology'] and openvpn['type']:
        default_server = None
        default_server = getDefaultServer(server_network_v4,
                                          openvpn['server_topology'],
                                          openvpn['type'])
        if default_server:
            # server-bridge doesn't require a pool so don't set defaults for it
            if openvpn['server_pool'] and not openvpn['is_bridge_member']:
                if not openvpn['server_pool_start']:
                    openvpn['server_pool_start'] = default_server['pool_start']

                if not openvpn['server_pool_stop']:
                    openvpn['server_pool_stop'] = default_server['pool_stop']

                if not openvpn['server_pool_netmask']:
                    openvpn['server_pool_netmask'] = default_server[
                        'pool_netmask']

            for client in openvpn['client']:
                client['remote_netmask'] = default_server[
                    'client_remote_netmask']

    if server_network_v6:
        if not openvpn['server_ipv6_local']:
            openvpn['server_ipv6_local'] = server_network_v6[1]
        if not openvpn['server_ipv6_prefixlen']:
            openvpn['server_ipv6_prefixlen'] = server_network_v6.prefixlen
        if not openvpn['server_ipv6_remote']:
            openvpn['server_ipv6_remote'] = server_network_v6[2]

        if openvpn['server_ipv6_pool'] and server_network_v6.prefixlen < 112:
            if not openvpn['server_ipv6_pool_base']:
                openvpn['server_ipv6_pool_base'] = server_network_v6[0x1000]
            if not openvpn['server_ipv6_pool_prefixlen']:
                openvpn['server_ipv6_pool_prefixlen'] = openvpn[
                    'server_ipv6_prefixlen']

        for client in openvpn['client']:
            client['ipv6_remote'] = openvpn['server_ipv6_local']

        if openvpn['redirect_gateway']:
            openvpn['redirect_gateway'] += ' ipv6'

    # retrieve VRF instance
    if conf.exists('vrf'):
        openvpn['vrf'] = conf.return_value('vrf')

    return openvpn