def get_config():
    conf = Config()
    mroute = {'old_mroute': {}, 'mroute': {}}

    base_path = "protocols static multicast"

    if not (conf.exists(base_path) or conf.exists_effective(base_path)):
        return None

    conf.set_level(base_path)

    # Get multicast effective routes
    for route in conf.list_effective_nodes('route'):
        mroute['old_mroute'][route] = {}
        for next_hop in conf.list_effective_nodes(
                'route {0} next-hop'.format(route)):
            mroute['old_mroute'][route].update({
                next_hop:
                conf.return_value('route {0} next-hop {1} distance'.format(
                    route, next_hop))
            })

    # Get multicast effective interface-routes
    for route in conf.list_effective_nodes('interface-route'):
        if not route in mroute['old_mroute']:
            mroute['old_mroute'][route] = {}
        for next_hop in conf.list_effective_nodes(
                'interface-route {0} next-hop-interface'.format(route)):
            mroute['old_mroute'][route].update({
                next_hop:
                conf.return_value(
                    'interface-route {0} next-hop-interface {1} distance'.
                    format(route, next_hop))
            })

    # Get multicast routes
    for route in conf.list_nodes('route'):
        mroute['mroute'][route] = {}
        for next_hop in conf.list_nodes('route {0} next-hop'.format(route)):
            mroute['mroute'][route].update({
                next_hop:
                conf.return_value('route {0} next-hop {1} distance'.format(
                    route, next_hop))
            })

    # Get multicast interface-routes
    for route in conf.list_nodes('interface-route'):
        if not route in mroute['mroute']:
            mroute['mroute'][route] = {}
        for next_hop in conf.list_nodes(
                'interface-route {0} next-hop-interface'.format(route)):
            mroute['mroute'][route].update({
                next_hop:
                conf.return_value(
                    'interface-route {0} next-hop-interface {1} distance'.
                    format(route, next_hop))
            })

    return mroute
def get_config():
    conf = Config()
    igmp_conf = {'igmp_conf': False, 'old_ifaces': {}, 'ifaces': {}}
    if not (conf.exists('protocols igmp')
            or conf.exists_effective('protocols igmp')):
        return None

    if conf.exists('protocols igmp'):
        igmp_conf['igmp_conf'] = True

    conf.set_level('protocols igmp')

    # # Get interfaces
    for iface in conf.list_effective_nodes('interface'):
        igmp_conf['old_ifaces'].update({
            iface: {
                'version':
                conf.return_effective_value(
                    'interface {0} version'.format(iface)),
                'query_interval':
                conf.return_effective_value(
                    'interface {0} query-interval'.format(iface)),
                'query_max_resp_time':
                conf.return_effective_value(
                    'interface {0} query-max-response-time'.format(iface)),
                'gr_join': {}
            }
        })
        for gr_join in conf.list_effective_nodes(
                'interface {0} join'.format(iface)):
            igmp_conf['old_ifaces'][iface]['gr_join'][
                gr_join] = conf.return_effective_values(
                    'interface {0} join {1} source'.format(iface, gr_join))

    for iface in conf.list_nodes('interface'):
        igmp_conf['ifaces'].update({
            iface: {
                'version':
                conf.return_value('interface {0} version'.format(iface)),
                'query_interval':
                conf.return_value(
                    'interface {0} query-interval'.format(iface)),
                'query_max_resp_time':
                conf.return_value(
                    'interface {0} query-max-response-time'.format(iface)),
                'gr_join': {}
            }
        })
        for gr_join in conf.list_nodes('interface {0} join'.format(iface)):
            igmp_conf['ifaces'][iface]['gr_join'][
                gr_join] = conf.return_values(
                    'interface {0} join {1} source'.format(iface, gr_join))

    return igmp_conf
def verify(bridge):
    if bridge['dhcpv6_prm_only'] and bridge['dhcpv6_temporary']:
        raise ConfigError(
            'DHCPv6 temporary and parameters-only options are mutually exclusive!'
        )

    vrf_name = bridge['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    conf = Config()
    for intf in bridge['member']:
        # the interface must exist prior adding it to a bridge
        if intf['name'] not in interfaces():
            raise ConfigError(
                (f'Cannot add nonexistent interface "{intf["name"]}" '
                 f'to bridge "{bridge["intf"]}"'))

        if intf['name'] == 'lo':
            raise ConfigError(
                'Loopback interface "lo" can not be added to a bridge')

        # bridge members aren't allowed to be members of another bridge
        for br in conf.list_nodes('interfaces bridge'):
            # it makes no sense to verify ourself in this case
            if br == bridge['intf']:
                continue

            tmp = conf.list_nodes(f'interfaces bridge {br} member interface')
            if intf['name'] in tmp:
                raise ConfigError((
                    f'Cannot add interface "{intf["name"]}" to bridge '
                    f'"{bridge["intf"]}", it is already a member of bridge "{br}"!'
                ))

        # bridge members are not allowed to be bond members
        tmp = is_member(conf, intf['name'], 'bonding')
        if tmp:
            raise ConfigError(
                (f'Cannot add interface "{intf["name"]}" to bridge '
                 f'"{bridge["intf"]}", it is already a member of bond "{tmp}"!'
                 ))

        # bridge members must not have an assigned address
        if has_address_configured(conf, intf['name']):
            raise ConfigError(
                (f'Cannot add interface "{intf["name"]}" to bridge '
                 f'"{bridge["intf"]}", it has an address assigned!'))

    return None
def get_config():
    conf = Config()
    conf.set_level("service broadcast-relay id")
    relay_id = conf.list_nodes("")
    relays = []

    for id in relay_id:
        interface_list = []
        address = conf.return_value("{0} address".format(id))
        description = conf.return_value("{0} description".format(id))
        port = conf.return_value("{0} port".format(id))

        # split the interface name listing and form a list
        if conf.exists("{0} interface".format(id)):
            intfs_names = conf.return_values("{0} interface".format(id))
            intfs_names = intfs_names.replace("'", "")
            intfs_names = intfs_names.split()
            for name in intfs_names:
                interface_list.append(name)

        relay = {
            "id": id,
            "address": address,
            "description": description,
            "interfaces": interface_list,
            "port": port
        }
        relays.append(relay)

    return relays
def verify(bridge):
    if bridge['dhcpv6_prm_only'] and bridge['dhcpv6_temporary']:
        raise ConfigError(
            'DHCPv6 temporary and parameters-only options are mutually exclusive!'
        )

    vrf_name = bridge['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    conf = Config()
    for br in conf.list_nodes('interfaces bridge'):
        # it makes no sense to verify ourself in this case
        if br == bridge['intf']:
            continue

        for intf in bridge['member']:
            tmp = conf.list_nodes(
                'interfaces bridge {} member interface'.format(br))
            if intf['name'] in tmp:
                raise ConfigError(
                    'Interface "{}" belongs to bridge "{}" and can not be enslaved.'
                    .format(intf['name'], bridge['intf']))

    # the interface must exist prior adding it to a bridge
    for intf in bridge['member']:
        if intf['name'] not in interfaces():
            raise ConfigError(
                'Can not add non existing interface "{}" to bridge "{}"'.
                format(intf['name'], bridge['intf']))

        if intf['name'] == 'lo':
            raise ConfigError(
                'Loopback interface "lo" can not be added to a bridge')

    # bridge members are not allowed to be bond members, too
    for intf in bridge['member']:
        for bond in conf.list_nodes('interfaces bonding'):
            if conf.exists('interfaces bonding ' + bond + ' member interface'):
                if intf['name'] in conf.return_values('interfaces bonding ' +
                                                      bond +
                                                      ' member interface'):
                    raise ConfigError(
                        'Interface {} belongs to bond {}, can not add it to {}'
                        .format(intf['name'], bond, bridge['intf']))

    return None
Beispiel #6
0
def get_config():
    c = Config()
    if not c.exists('protocols static arp'):
        return None

    c.set_level('protocols static')
    config_data = {}

    for ip_addr in c.list_nodes('arp'):
        config_data.update(
            {ip_addr: c.return_value('arp ' + ip_addr + ' hwaddr')})

    return config_data
Beispiel #7
0
def get_config():
    relay = deepcopy(default_config_data)
    conf = Config()
    base = ['service', 'broadcast-relay']

    if not conf.exists(base):
        return None
    else:
        conf.set_level(base)

    # Service can be disabled by user
    if conf.exists('disable'):
        relay['disabled'] = True
        return relay

    # Parse configuration of each individual instance
    if conf.exists('id'):
        for id in conf.list_nodes('id'):
            conf.set_level(base + ['id', id])
            config = {
                'id': id,
                'disabled': False,
                'address': '',
                'description': '',
                'interfaces': [],
                'port': ''
            }

            # Check if individual broadcast relay service is disabled
            if conf.exists(['disable']):
                config['disabled'] = True

            # Source IP of forwarded packets, if empty original senders address is used
            if conf.exists(['address']):
                config['address'] = conf.return_value(['address'])

            # A description for each individual broadcast relay service
            if conf.exists(['description']):
                config['description'] = conf.return_value(['description'])

            # UDP port to listen on for broadcast frames
            if conf.exists(['port']):
                config['port'] = conf.return_value(['port'])

            # Network interfaces to listen on for broadcast frames to be relayed
            if conf.exists(['interface']):
                config['interfaces'] = conf.return_values(['interface'])

            relay['instances'].append(config)

    return relay
Beispiel #8
0
def get_config():
    relay = deepcopy(default_config_data)
    conf = Config()
    if not conf.exists('service dhcpv6-relay'):
        return None
    else:
        conf.set_level('service dhcpv6-relay')

    # Network interfaces/address to listen on for DHCPv6 query(s)
    if conf.exists('listen-interface'):
        interfaces = conf.list_nodes('listen-interface')
        for intf in interfaces:
            if conf.exists('listen-interface {0} address'.format(intf)):
                addr = conf.return_value(
                    'listen-interface {0} address'.format(intf))
                listen = addr + '%' + intf
                relay['listen_addr'].append(listen)

    # Upstream interface/address for remote DHCPv6 server
    if conf.exists('upstream-interface'):
        interfaces = conf.list_nodes('upstream-interface')
        for intf in interfaces:
            addresses = conf.return_values(
                'upstream-interface {0} address'.format(intf))
            for addr in addresses:
                server = addr + '%' + intf
                relay['upstream_addr'].append(server)

    # Maximum hop count. When forwarding packets, dhcrelay discards packets
    # which have reached a hop count of COUNT. Default is 10. Maximum is 255.
    if conf.exists('max-hop-count'):
        count = '-c ' + conf.return_value('max-hop-count')
        relay['options'].append(count)

    if conf.exists('use-interface-id-option'):
        relay['options'].append('-I')

    return relay
def get_config():
    bfd = deepcopy(default_config_data)
    conf = Config()
    if not (conf.exists('protocols bfd')
            or conf.exists_effective('protocols bfd')):
        return None
    else:
        conf.set_level('protocols bfd')

    # as we have to use vtysh to talk to FRR we also need to know
    # which peers are gone due to a config removal - thus we read in
    # all peers (active or to delete)
    for peer in conf.list_effective_nodes('peer'):
        bfd['old_peers'].append(get_bfd_peer_config(peer, "effective"))

    for peer in conf.list_nodes('peer'):
        bfd['new_peers'].append(get_bfd_peer_config(peer))

    # find deleted peers
    set_new_peers = set(conf.list_nodes('peer'))
    set_old_peers = set(conf.list_effective_nodes('peer'))
    bfd['deleted_peers'] = set_old_peers - set_new_peers

    return bfd
def get_config():
    opts = copy.deepcopy(default_config_data)
    conf = Config()
    if not conf.exists('firewall options'):
        # bail out early
        return opts
    else:
        conf.set_level('firewall options')

        # Parse configuration of each individual instance
        if conf.exists('interface'):
            for intf in conf.list_nodes('interface'):
                conf.set_level('firewall options interface {0}'.format(intf))
                config = {
                    'intf': intf,
                    'disabled': False,
                    'mss4': '',
                    'mss6': ''
                }

                # Check if individual option is disabled
                if conf.exists('disable'):
                    config['disabled'] = True

                #
                # Get MSS value IPv4
                #
                if conf.exists('adjust-mss'):
                    config['mss4'] = conf.return_value('adjust-mss')

                    # We need a marker that a new iptables chain needs to be generated
                    if not opts['new_chain4']:
                        opts['new_chain4'] = True

                #
                # Get MSS value IPv6
                #
                if conf.exists('adjust-mss6'):
                    config['mss6'] = conf.return_value('adjust-mss6')

                    # We need a marker that a new ip6tables chain needs to be generated
                    if not opts['new_chain6']:
                        opts['new_chain6'] = True

                # Append interface options to global list
                opts['intf_opts'].append(config)

    return opts
Beispiel #11
0
def get_config():
    igmp_proxy = deepcopy(default_config_data)
    conf = Config()
    base = ['protocols', 'igmp-proxy']
    if not conf.exists(base):
        return None
    else:
        conf.set_level(base)

    # Network interfaces to listen on
    if conf.exists(['disable']):
        igmp_proxy['disable'] = True

    # Option to disable "quickleave"
    if conf.exists(['disable-quickleave']):
        igmp_proxy['disable_quickleave'] = True

    for intf in conf.list_nodes(['interface']):
        conf.set_level(base + ['interface', intf])
        interface = {
            'name': intf,
            'alt_subnet': [],
            'role': 'downstream',
            'threshold': '1',
            'whitelist': []
        }

        if conf.exists(['alt-subnet']):
            interface['alt_subnet'] = conf.return_values(['alt-subnet'])

        if conf.exists(['role']):
            interface['role'] = conf.return_value(['role'])

        if conf.exists(['threshold']):
            interface['threshold'] = conf.return_value(['threshold'])

        if conf.exists(['whitelist']):
            interface['whitelist'] = conf.return_values(['whitelist'])

        # Append interface configuration to global configuration list
        igmp_proxy['interfaces'].append(interface)

    return igmp_proxy
Beispiel #12
0
def get_config():
    ntp = deepcopy(default_config_data)
    conf = Config()
    if not conf.exists('system ntp'):
        return None
    else:
        conf.set_level('system ntp')

    if conf.exists('allow-clients address'):
        networks = conf.return_values('allow-clients address')
        for n in networks:
            addr = ip_network(n)
            net = {
                "network" : n,
                "address" : addr.network_address,
                "netmask" : addr.netmask
            }

            ntp['allowed_networks'].append(net)

    if conf.exists('listen-address'):
        ntp['listen_address'] = conf.return_values('listen-address')

    if conf.exists('server'):
        for node in conf.list_nodes('server'):
            options = []
            server = {
                "name": node,
                "options": []
            }
            if conf.exists('server {0} noselect'.format(node)):
                options.append('noselect')
            if conf.exists('server {0} preempt'.format(node)):
                options.append('preempt')
            if conf.exists('server {0} prefer'.format(node)):
                options.append('prefer')

            server['options'] = options
            ntp['servers'].append(server)

    return ntp
def verify(eth):
    if eth['deleted']:
        return None

    if eth['intf'] not in interfaces():
        raise ConfigError(f"Interface ethernet {eth['intf']} does not exist")

    if eth['speed'] == 'auto':
        if eth['duplex'] != 'auto':
            raise ConfigError(
                'If speed is hardcoded, duplex must be hardcoded, too')

    if eth['duplex'] == 'auto':
        if eth['speed'] != 'auto':
            raise ConfigError(
                'If duplex is hardcoded, speed must be hardcoded, too')

    if eth['dhcpv6_prm_only'] and eth['dhcpv6_temporary']:
        raise ConfigError(
            'DHCPv6 temporary and parameters-only options are mutually exclusive!'
        )

    vrf_name = eth['vrf']
    if vrf_name and vrf_name not in interfaces():
        raise ConfigError(f'VRF "{vrf_name}" does not exist')

    conf = Config()
    # some options can not be changed when interface is enslaved to a bond
    for bond in conf.list_nodes('interfaces bonding'):
        if conf.exists('interfaces bonding ' + bond + ' member interface'):
            bond_member = conf.return_values('interfaces bonding ' + bond +
                                             ' member interface')
            if eth['intf'] in bond_member:
                if eth['address']:
                    raise ConfigError(
                        f"Can not assign address to interface {eth['intf']} which is a member of {bond}"
                    )

    # use common function to verify VLAN configuration
    verify_vlan_config(eth)
    return None
Beispiel #14
0
def get_config():
    conf = Config()
    conf.set_level("system task-scheduler task")
    task_names = conf.list_nodes("")
    tasks = []

    for name in task_names:
        interval = conf.return_value("{0} interval".format(name))
        spec = conf.return_value("{0} crontab-spec".format(name))
        executable = conf.return_value("{0} executable path".format(name))
        args = conf.return_value("{0} executable arguments".format(name))
        task = {
            "name": name,
            "interval": interval,
            "spec": spec,
            "executable": executable,
            "args": args
        }
        tasks.append(task)

    return tasks
Beispiel #15
0
def get_config():
    http_api = deepcopy(vyos.defaults.api_data)
    x = http_api.get('api_keys')
    if x is None:
        default_key = None
    else:
        default_key = x[0]
    keys_added = False

    conf = Config()
    if not conf.exists('service https api'):
        return None
    else:
        conf.set_level('service https api')

    if conf.exists('strict'):
        http_api['strict'] = 'true'

    if conf.exists('debug'):
        http_api['debug'] = 'true'

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

    if conf.exists('keys'):
        for name in conf.list_nodes('keys id'):
            if conf.exists('keys id {0} key'.format(name)):
                key = conf.return_value('keys id {0} key'.format(name))
                new_key = {'id': name, 'key': key}
                http_api['api_keys'].append(new_key)
                keys_added = True

    if keys_added and default_key:
        if default_key in http_api['api_keys']:
            http_api['api_keys'].remove(default_key)

    return http_api
Beispiel #16
0
def get_config():
    conf = Config()
    hosts = copy.deepcopy(default_config_data)

    if conf.exists("system host-name"):
        hosts['hostname'] = conf.return_value("system host-name")
        # This may happen if the config is not loaded yet,
        # e.g. if run by cloud-init
        if not hosts['hostname']:
            hosts['hostname'] = default_config_data['hostname']

    if conf.exists("system domain-name"):
        hosts['domain_name'] = conf.return_value("system domain-name")
        hosts['domain_search'].append(hosts['domain_name'])

    for search in conf.return_values("system domain-search domain"):
        hosts['domain_search'].append(search)

    if conf.exists("system name-server"):
        hosts['nameserver'] = conf.return_values("system name-server")

    if conf.exists("system disable-dhcp-nameservers"):
        hosts['no_dhcp_ns'] = True

    # system static-host-mapping
    hosts['static_host_mapping'] = []

    if conf.exists('system static-host-mapping host-name'):
        for hn in conf.list_nodes('system static-host-mapping host-name'):
            mapping = {}
            mapping['host'] = hn
            mapping['address'] = conf.return_value(
                'system static-host-mapping host-name {0} inet'.format(hn))
            mapping['aliases'] = conf.return_values(
                'system static-host-mapping host-name {0} alias'.format(hn))
            hosts['static_host_mapping'].append(mapping)

    return hosts
def get_config():
    vc = Config()
    vc.set_level('')
    # Convert the VyOS config to an abstract internal representation
    flow_config = {
        'flow-accounting-configured':
        vc.exists('system flow-accounting'),
        'buffer-size':
        vc.return_value('system flow-accounting buffer-size'),
        'disable-imt':
        _node_exists('system flow-accounting disable-imt'),
        'syslog-facility':
        vc.return_value('system flow-accounting syslog-facility'),
        'interfaces':
        None,
        'sflow': {
            'configured':
            vc.exists('system flow-accounting sflow'),
            'agent-address':
            vc.return_value('system flow-accounting sflow agent-address'),
            'sampling-rate':
            vc.return_value('system flow-accounting sflow sampling-rate'),
            'servers':
            None
        },
        'netflow': {
            'configured':
            vc.exists('system flow-accounting netflow'),
            'engine-id':
            vc.return_value('system flow-accounting netflow engine-id'),
            'max-flows':
            vc.return_value('system flow-accounting netflow max-flows'),
            'sampling-rate':
            vc.return_value('system flow-accounting netflow sampling-rate'),
            'source-ip':
            vc.return_value('system flow-accounting netflow source-ip'),
            'version':
            vc.return_value('system flow-accounting netflow version'),
            'timeout': {
                'expint':
                vc.return_value(
                    'system flow-accounting netflow timeout expiry-interval'),
                'general':
                vc.return_value(
                    'system flow-accounting netflow timeout flow-generic'),
                'icmp':
                vc.return_value('system flow-accounting netflow timeout icmp'),
                'maxlife':
                vc.return_value(
                    'system flow-accounting netflow timeout max-active-life'),
                'tcp.fin':
                vc.return_value(
                    'system flow-accounting netflow timeout tcp-fin'),
                'tcp':
                vc.return_value(
                    'system flow-accounting netflow timeout tcp-generic'),
                'tcp.rst':
                vc.return_value(
                    'system flow-accounting netflow timeout tcp-rst'),
                'udp':
                vc.return_value('system flow-accounting netflow timeout udp')
            },
            'servers':
            None
        }
    }

    # get interfaces list
    if vc.exists('system flow-accounting interface'):
        flow_config['interfaces'] = vc.return_values(
            'system flow-accounting interface')

    # get sFlow collectors list
    if vc.exists('system flow-accounting sflow server'):
        flow_config['sflow']['servers'] = []
        sflow_collectors = vc.list_nodes('system flow-accounting sflow server')
        for collector in sflow_collectors:
            port = default_sflow_server_port
            if vc.return_value(
                    "system flow-accounting sflow server {} port".format(
                        collector)):
                port = vc.return_value(
                    "system flow-accounting sflow server {} port".format(
                        collector))
            flow_config['sflow']['servers'].append({
                'address': collector,
                'port': port
            })

    # get NetFlow collectors list
    if vc.exists('system flow-accounting netflow server'):
        flow_config['netflow']['servers'] = []
        netflow_collectors = vc.list_nodes(
            'system flow-accounting netflow server')
        for collector in netflow_collectors:
            port = default_netflow_server_port
            if vc.return_value(
                    "system flow-accounting netflow server {} port".format(
                        collector)):
                port = vc.return_value(
                    "system flow-accounting netflow server {} port".format(
                        collector))
            flow_config['netflow']['servers'].append({
                'address': collector,
                'port': port
            })

    # get sflow agent-id
    if flow_config['sflow']['agent-address'] == None or flow_config['sflow'][
            'agent-address'] == 'auto':
        flow_config['sflow']['agent-address'] = _sflow_default_agentip(vc)

    # get NetFlow version
    if not flow_config['netflow']['version']:
        flow_config['netflow']['version'] = default_netflow_version

    # convert NetFlow engine-id format, if this is necessary
    if flow_config['netflow']['engine-id'] and flow_config['netflow'][
            'version'] == '5':
        regex_filter = re.compile('^\d+$')
        if regex_filter.search(flow_config['netflow']['engine-id']):
            flow_config['netflow']['engine-id'] = "{}:0".format(
                flow_config['netflow']['engine-id'])

    # return dict with flow-accounting configuration
    return flow_config
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']

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

    # Check if we belong to any bridge interface
    for bridge in conf.list_nodes('interfaces bridge'):
        for intf in conf.list_nodes(
                'interfaces bridge {} member interface'.format(bridge)):
            if intf == openvpn['intf']:
                openvpn['bridge_member'].append(intf)

    # 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'):
        openvpn['local_address'] = conf.list_nodes('local-address')[0]
        if conf.exists('local-address {} subnet-mask'.format(
                openvpn['local_address'])):
            openvpn['local_address_subnet'] = conf.return_value(
                'local-address {} subnet-mask'.format(
                    openvpn['local_address']))

    # 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 prefix for IPv6 addressing based on MAC address (EUI-64)
    if conf.exists('ipv6 address eui64'):
        openvpn['ipv6_eui64_prefix'] = conf.return_value('ipv6 address eui64')

    # 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'))

    # 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'):
        openvpn['remote_address'] = conf.return_value('remote-address')

    # 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)
    if conf.exists('server subnet'):
        network = conf.return_value('server subnet')
        tmp = IPv4Interface(network).with_netmask
        # convert the network in format: "192.0.2.0 255.255.255.0" for later use in template
        openvpn['server_subnet'] = tmp.replace(r'/', ' ')

    # 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': '',
            'push_route': [],
            'subnet': [],
            'remote_netmask': ''
        }

        # note: with "topology subnet", this is "<ip> <netmask>".
        #       with "topology p2p", this is "<ip> <our_ip>".
        if openvpn['server_topology'] == 'subnet':
            # we are only interested in the netmask portion of server_subnet
            data['remote_netmask'] = openvpn['server_subnet'].split(' ')[1]
        else:
            # we need the server subnet in format 192.0.2.0/255.255.255.0
            subnet = openvpn['server_subnet'].replace(' ', r'/')
            # get iterator over the usable hosts in the network
            tmp = ip_network(subnet).hosts()
            # OpenVPN always uses the subnets first available IP address
            data['remote_netmask'] = list(tmp)[0]

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

        # IP address of the client
        if conf.exists('ip'):
            data['ip'] = conf.return_value('ip')

        # Route to be pushed to the client
        for network in conf.return_values('push-route'):
            tmp = IPv4Interface(network).with_netmask
            data['push_route'].append(tmp.replace(r'/', ' '))

        # Subnet belonging to the client
        for network in conf.return_values('subnet'):
            tmp = IPv4Interface(network).with_netmask
            data['subnet'].append(tmp.replace(r'/', ' '))

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

    # re-set configuration level
    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'):
        openvpn['server_dns_nameserver'] = conf.return_values(
            'server name-server')

    # Route to be pushed to all clients
    if conf.exists('server push-route'):
        for network in conf.return_values('server push-route'):
            tmp = IPv4Interface(network).with_netmask
            openvpn['server_push_route'].append(tmp.replace(r'/', ' '))

    # 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'

    return openvpn
Beispiel #19
0
def get_config():
    conf = Config()
    vrf_config = deepcopy(default_config_data)

    cfg_base = ['vrf']
    if not conf.exists(cfg_base):
        # get all currently effetive VRFs and mark them for deletion
        vrf_config['vrf_remove'] = conf.list_effective_nodes(cfg_base +
                                                             ['name'])
    else:
        # set configuration level base
        conf.set_level(cfg_base)

        # Should services be allowed to bind to all VRFs?
        if conf.exists(['bind-to-all']):
            vrf_config['bind_to_all'] = '1'

        # Determine vrf interfaces (currently effective) - to determine which
        # vrf interface is no longer present and needs to be removed
        eff_vrf = conf.list_effective_nodes(['name'])
        act_vrf = conf.list_nodes(['name'])
        vrf_config['vrf_remove'] = list_diff(eff_vrf, act_vrf)

        # read in individual VRF definition and build up
        # configuration
        for name in conf.list_nodes(['name']):
            vrf_inst = {
                'description': '',
                'members': [],
                'name': name,
                'table': '',
                'table_mod': False
            }
            conf.set_level(cfg_base + ['name', name])

            if conf.exists(['table']):
                # VRF table can't be changed on demand, thus we need to read in the
                # current and the effective routing table number
                act_table = conf.return_value(['table'])
                eff_table = conf.return_effective_value(['table'])
                vrf_inst['table'] = act_table
                if eff_table and eff_table != act_table:
                    vrf_inst['table_mod'] = True

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

            # append individual VRF configuration to global configuration list
            vrf_config['vrf_add'].append(vrf_inst)

    # set configuration level base
    conf.set_level(cfg_base)

    # check VRFs which need to be removed as they are not allowed to have
    # interfaces attached
    tmp = []
    for name in vrf_config['vrf_remove']:
        vrf_inst = {'interfaces': [], 'name': name, 'routes': []}

        # find member interfaces of this particulat VRF
        vrf_inst['interfaces'] = vrf_interfaces(conf, name)

        # find routing protocols used by this VRF
        vrf_inst['routes'] = vrf_routing(conf, name)

        # append individual VRF configuration to temporary configuration list
        tmp.append(vrf_inst)

    # replace values in vrf_remove with list of dictionaries
    # as we need it in verify() - we can't delete a VRF with members attached
    vrf_config['vrf_remove'] = tmp
    return vrf_config
Beispiel #20
0
def get_config():
    conf = Config()
    pim_conf = {
        'pim_conf': False,
        'old_pim': {
            'ifaces': {},
            'rp': {}
        },
        'pim': {
            'ifaces': {},
            'rp': {}
        }
    }
    if not (conf.exists('protocols pim')
            or conf.exists_effective('protocols pim')):
        return None

    if conf.exists('protocols pim'):
        pim_conf['pim_conf'] = True

    conf.set_level('protocols pim')

    # Get interfaces
    for iface in conf.list_effective_nodes('interface'):
        pim_conf['old_pim']['ifaces'].update({
            iface: {
                'hello':
                conf.return_effective_value(
                    'interface {0} hello'.format(iface)),
                'dr_prio':
                conf.return_effective_value(
                    'interface {0} dr-priority'.format(iface))
            }
        })

    for iface in conf.list_nodes('interface'):
        pim_conf['pim']['ifaces'].update({
            iface: {
                'hello':
                conf.return_value('interface {0} hello'.format(iface)),
                'dr_prio':
                conf.return_value('interface {0} dr-priority'.format(iface)),
            }
        })

    conf.set_level('protocols pim rp')

    # Get RPs addresses
    for rp_addr in conf.list_effective_nodes('address'):
        pim_conf['old_pim']['rp'][rp_addr] = conf.return_effective_values(
            'address {0} group'.format(rp_addr))

    for rp_addr in conf.list_nodes('address'):
        pim_conf['pim']['rp'][rp_addr] = conf.return_values(
            'address {0} group'.format(rp_addr))

    # Get RP keep-alive-timer
    if conf.exists_effective('rp keep-alive-timer'):
        pim_conf['old_pim']['rp_keep_alive'] = conf.return_effective_value(
            'rp keep-alive-timer')
    if conf.exists('rp keep-alive-timer'):
        pim_conf['pim']['rp_keep_alive'] = conf.return_value(
            'rp keep-alive-timer')

    return pim_conf
Beispiel #21
0
def get_config():
    server_block_list = []
    conf = Config()
    if not conf.exists('service https'):
        return None
    else:
        conf.set_level('service https')

    if not conf.exists('virtual-host'):
        server_block_list.append(default_server_block)
    else:
        for vhost in conf.list_nodes('virtual-host'):
            server_block = deepcopy(default_server_block)
            server_block['id'] = vhost
            if conf.exists(f'virtual-host {vhost} listen-address'):
                addr = conf.return_value(
                    f'virtual-host {vhost} listen-address')
                server_block['address'] = addr
            if conf.exists(f'virtual-host {vhost} listen-port'):
                port = conf.return_value(f'virtual-host {vhost} listen-port')
                server_block['port'] = port
            if conf.exists(f'virtual-host {vhost} server-name'):
                names = conf.return_values(f'virtual-host {vhost} server-name')
                server_block['name'] = names[:]
            server_block_list.append(server_block)

    vyos_cert_data = {}
    if conf.exists('certificates system-generated-certificate'):
        vyos_cert_data = vyos.defaults.vyos_cert_data
    if vyos_cert_data:
        for block in server_block_list:
            block['vyos_cert'] = vyos_cert_data

    certbot = False
    certbot_domains = []
    if conf.exists('certificates certbot domain-name'):
        certbot_domains = conf.return_values(
            'certificates certbot domain-name')
    if certbot_domains:
        certbot = True
        for domain in certbot_domains:
            sub_list = vyos.certbot_util.choose_server_block(
                server_block_list, domain)
            if sub_list:
                for sb in sub_list:
                    sb['certbot'] = True
                    # certbot organizes certificates by first domain
                    sb['certbot_dir'] = certbot_domains[0]

    api_somewhere = False
    api_data = {}
    if conf.exists('api'):
        api_somewhere = True
        api_data = vyos.defaults.api_data
        if conf.exists('api port'):
            port = conf.return_value('api port')
            api_data['port'] = port
        if conf.exists('api-restrict virtual-host'):
            vhosts = conf.return_values('api-restrict virtual-host')
            api_data['vhost'] = vhosts[:]

    if api_data:
        # we do not want to include 'vhost' key as part of
        # vyos.defaults.api_data, so check for key existence
        vhost_list = api_data.get('vhost')
        if vhost_list is None:
            for block in server_block_list:
                block['api'] = api_data
        else:
            for block in server_block_list:
                if block['id'] in vhost_list:
                    block['api'] = api_data

    https = {
        'server_block_list': server_block_list,
        'api_somewhere': api_somewhere,
        'certbot': certbot
    }
    return https
Beispiel #22
0
def get_config():
    dyndns = deepcopy(default_config_data)
    conf = Config()
    base_level = ['service', 'dns', 'dynamic']

    if not conf.exists(base_level):
        dyndns['deleted'] = True
        return dyndns

    for interface in conf.list_nodes(base_level + ['interface']):
        node = {
            'interface': interface,
            'rfc2136': [],
            'service': [],
            'web_skip': '',
            'web_url': ''
        }

        # set config level to e.g. "service dns dynamic interface eth0"
        conf.set_level(base_level + ['interface', interface])
        # Handle RFC2136 - Dynamic Updates in the Domain Name System
        for rfc2136 in conf.list_nodes(['rfc2136']):
            rfc = {
                'name': rfc2136,
                'keyfile': '',
                'record': [],
                'server': '',
                'ttl': '600',
                'zone': ''
            }

            # set config level
            conf.set_level(base_level + ['interface', interface, 'rfc2136', rfc2136])

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

            if conf.exists(['record']):
                rfc['record'] = conf.return_values(['record'])

            if conf.exists(['server']):
                rfc['server'] = conf.return_value(['server'])

            if conf.exists(['ttl']):
                rfc['ttl'] = conf.return_value(['ttl'])

            if conf.exists(['zone']):
                rfc['zone'] = conf.return_value(['zone'])

            node['rfc2136'].append(rfc)

        # set config level to e.g. "service dns dynamic interface eth0"
        conf.set_level(base_level + ['interface', interface])
        # Handle DynDNS service providers
        for service in conf.list_nodes(['service']):
            srv = {
                'provider': service,
                'host': [],
                'login': '',
                'password': '',
                'protocol': '',
                'server': '',
                'custom' : False,
                'zone' : ''
            }

            # set config level
            conf.set_level(base_level + ['interface', interface, 'service', service])

            # preload protocol from default service mapping
            if service in default_service_protocol.keys():
                srv['protocol'] = default_service_protocol[service]
            else:
                srv['custom'] = True

            if conf.exists(['login']):
                srv['login'] = conf.return_value(['login'])

            if conf.exists(['host-name']):
                srv['host'] = conf.return_values(['host-name'])

            if conf.exists(['protocol']):
                srv['protocol'] = conf.return_value(['protocol'])

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

            if conf.exists(['server']):
                srv['server'] = conf.return_value(['server'])

            if conf.exists(['zone']):
                srv['zone'] = conf.return_value(['zone'])
            elif srv['provider'] == 'cloudflare':
                # default populate zone entry with bar.tld if
                # host-name is foo.bar.tld
                srv['zone'] = srv['host'][0].split('.',1)[1]

            node['service'].append(srv)

        # Set config back to appropriate level for these options
        conf.set_level(base_level + ['interface', interface])

        # Additional settings in CLI
        if conf.exists(['use-web', 'skip']):
            node['web_skip'] = conf.return_value(['use-web', 'skip'])

        if conf.exists(['use-web', 'url']):
            node['web_url'] = conf.return_value(['use-web', 'url'])

        # set config level back to top level
        conf.set_level(base_level)

        dyndns['interfaces'].append(node)

    return dyndns
Beispiel #23
0
def get_config():
    c = Config()
    if not c.exists(['vpn', 'pptp', 'remote-access']):
        return None

    c.set_level(['vpn', 'pptp', 'remote-access'])
    config_data = {
        'authentication': {
            'mode': 'local',
            'local-users': {},
            'radiussrv': {},
            'auth_proto': 'auth_mschap_v2',
            'mppe': 'require'
        },
        'outside_addr': '',
        'dns': [],
        'wins': [],
        'client_ip_pool': '',
        'mtu': '1436',
    }

    ### general options ###

    if c.exists(['dns-servers', 'server-1']):
        config_data['dns'].append(c.return_value(['dns-servers', 'server-1']))
    if c.exists(['dns-servers', 'server-2']):
        config_data['dns'].append(c.return_value(['dns-servers', 'server-2']))
    if c.exists(['wins-servers', 'server-1']):
        config_data['wins'].append(c.return_value(['wins-servers',
                                                   'server-1']))
    if c.exists(['wins-servers', 'server-2']):
        config_data['wins'].append(c.return_value(['wins-servers',
                                                   'server-2']))
    if c.exists(['outside-address']):
        config_data['outside_addr'] = c.return_value(['outside-address'])

    # auth local
    if c.exists(['authentication', 'mode', 'local']):
        if c.exists(['authentication', 'local-users', 'username']):
            for usr in c.list_nodes(
                ['authentication', 'local-users', 'username']):
                config_data['authentication']['local-users'].update(
                    {usr: {
                        'passwd': '',
                        'state': 'enabled',
                        'ip': ''
                    }})

                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'password'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'passwd'] = c.return_value([
                            'authentication', 'local-users', 'username', usr,
                            'password'
                        ])
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'disable'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'state'] = 'disable'
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'static-ip'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'ip'] = c.return_value([
                            'authentication', 'local-users', 'username', usr,
                            'static-ip'
                        ])

    # authentication mode radius servers and settings

    if c.exists(['authentication', 'mode', 'radius']):
        config_data['authentication']['mode'] = 'radius'
        rsrvs = c.list_nodes(['authentication', 'radius', 'server'])
        for rsrv in rsrvs:
            if not c.return_value(
                ['authentication', 'radius', 'server', rsrv, 'fail-time']):
                ftime = '0'
            else:
                ftime = c.return_value(
                    ['authentication', 'radius', 'server', rsrv, 'fail-time'])
            if not c.return_value(
                ['authentication', 'radius-server', rsrv, 'req-limit']):
                reql = '0'
            else:
                reql = c.return_value(
                    ['authentication', 'radius', 'server', rsrv, 'req-limit'])

            config_data['authentication']['radiussrv'].update({
                rsrv: {
                    'secret':
                    c.return_value(
                        ['authentication', 'radius', 'server', rsrv, 'key']),
                    'fail-time':
                    ftime,
                    'req-limit':
                    reql
                }
            })

    if c.exists(['client-ip-pool']):
        if c.exists(['client-ip-pool', 'start']):
            config_data['client_ip_pool'] = c.return_value(
                ['client-ip-pool', 'start'])
        if c.exists(['client-ip-pool', 'stop']):
            config_data['client_ip_pool'] += '-' + \
                re.search(
                    '[0-9]+$', c.return_value(['client-ip-pool', 'stop'])).group(0)
    if c.exists(['mtu']):
        config_data['mtu'] = c.return_value(['mtu'])

    # gateway address
    if c.exists(['gateway-address']):
        config_data['gw_ip'] = c.return_value(['gateway-address'])
    else:
        config_data['gw_ip'] = re.sub('[0-9]+$', '1',
                                      config_data['client_ip_pool'])

    if c.exists(['authentication', 'require']):
        if c.return_value(['authentication', 'require']) == 'pap':
            config_data['authentication']['auth_proto'] = 'auth_pap'
        if c.return_value(['authentication', 'require']) == 'chap':
            config_data['authentication']['auth_proto'] = 'auth_chap_md5'
        if c.return_value(['authentication', 'require']) == 'mschap':
            config_data['authentication']['auth_proto'] = 'auth_mschap_v1'
        if c.return_value(['authentication', 'require']) == 'mschap-v2':
            config_data['authentication']['auth_proto'] = 'auth_mschap_v2'

        if c.exists(['authentication', 'mppe']):
            config_data['authentication']['mppe'] = c.return_value(
                ['authentication', 'mppe'])

    return config_data
Beispiel #24
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)

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

    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']):
        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 ip pool settings
    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 network settings
    conf.set_level(base_path + ['network-settings'])
    if conf.exists(['name-server']):
        sstp['dnsv4'] = conf.return_values(['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 verify(bfd):
    if bfd is None:
        return None

    # some variables to use later
    conf = Config()

    for peer in bfd['new_peers']:
        # IPv6 link local peers require an explicit local address/interface
        if is_ipv6_link_local(peer['remote']):
            if not (peer['src_if'] and peer['src_addr']):
                raise ConfigError(
                    'BFD IPv6 link-local peers require explicit local address and interface setting'
                )

        # IPv6 peers require an explicit local address
        if is_ipv6(peer['remote']):
            if not peer['src_addr']:
                raise ConfigError(
                    'BFD IPv6 peers require explicit local address setting')

        # multihop require source address
        if peer['multihop'] and not peer['src_addr']:
            raise ConfigError('Multihop require source address')

        # multihop and echo-mode cannot be used together
        if peer['multihop'] and peer['echo_mode']:
            raise ConfigError('Multihop and echo-mode cannot be used together')

        # multihop doesn't accept interface names
        if peer['multihop'] and peer['src_if']:
            raise ConfigError(
                'Multihop and source interface cannot be used together')

        # echo interval can be configured only with enabled echo-mode
        if peer['echo_interval'] != '' and not peer['echo_mode']:
            raise ConfigError(
                'echo-interval can be configured only with enabled echo-mode')

    # check if we deleted peers are not used in configuration
    if conf.exists('protocols bgp'):
        bgp_as = conf.list_nodes('protocols bgp')[0]

        # check BGP neighbors
        for peer in bfd['deleted_peers']:
            if conf.exists('protocols bgp {0} neighbor {1} bfd'.format(
                    bgp_as, peer)):
                raise ConfigError(
                    'Cannot delete BFD peer {0}: it is used in BGP configuration'
                    .format(peer))
            if conf.exists('protocols bgp {0} neighbor {1} peer-group'.format(
                    bgp_as, peer)):
                peer_group = conf.return_value(
                    'protocols bgp {0} neighbor {1} peer-group'.format(
                        bgp_as, peer))
                if conf.exists('protocols bgp {0} peer-group {1} bfd'.format(
                        bgp_as, peer_group)):
                    raise ConfigError(
                        'Cannot delete BFD peer {0}: it belongs to BGP peer-group {1} with enabled BFD'
                        .format(peer, peer_group))

    return None
Beispiel #26
0
def get_config():
    snmp = default_config_data
    conf = Config()
    if not conf.exists('service snmp'):
        return None
    else:
        conf.set_level('service snmp')

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

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

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

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

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

            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'):
            listen = ''
            port = '161'
            if conf.exists('listen-address {0} port'.format(addr)):
                port = conf.return_value(
                    'listen-address {0} port'.format(addr))

            if ipaddress.ip_address(addr).version == 4:
                # udp:127.0.0.1:161
                listen = 'udp:' + addr + ':' + port
            elif ipaddress.ip_address(addr).version == 6:
                # udp6:[::1]:161
                listen = 'udp6:' + '[' + addr + ']' + ':' + port
            else:
                raise ConfigError('Invalid IP address version')

            snmp['listen_on'].append(listen)

    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)

    #########################################################################
    #                ____  _   _ __  __ ____          _____                 #
    #               / ___|| \ | |  \/  |  _ \  __   _|___ /                 #
    #               \___ \|  \| | |\/| | |_) | \ \ / / |_ \                 #
    #                ___) | |\  | |  | |  __/   \ 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,
                'engineID': '',
                'secName': '',
                'authProtocol': 'md5',
                'authPassword': '',
                'authMasterKey': '',
                'privProtocol': 'des',
                'privPassword': '',
                'privMasterKey': '',
                'ipProto': 'udp',
                'ipPort': '162',
                'type': '',
                'secLevel': 'noAuthNoPriv'
            }

            if conf.exists('v3 trap-target {0} engineid'.format(trap)):
                # Set the context engineID used for SNMPv3 REQUEST messages scopedPdu.
                # If not specified, this will default to the authoritative engineID.
                trap_cfg['engineID'] = conf.return_value(
                    'v3 trap-target {0} engineid'.format(trap))

            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 tsm'
    #
    if conf.exists('v3 tsm'):
        if conf.exists('v3 tsm local-key'):
            snmp['v3_tsm_key'] = conf.return_value('v3 tsm local-key')

        if conf.exists('v3 tsm port'):
            snmp['v3_tsm_port'] = conf.return_value('v3 tsm port')

    #
    # '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': '',
                'authOID': '',
                'engineID': '',
                'group': '',
                'mode': 'ro',
                'privMasterKey': '',
                'privPassword': '',
                'privOID': '',
                'privTsmKey': '',
                'privProtocol': ''
            }

            #
            # 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))

            if conf.exists('v3 user {0} auth type'.format(user)):
                type = conf.return_value('v3 user {0} auth type'.format(user))
                user_cfg['authProtocol'] = type
                user_cfg['authOID'] = OIDs[type]

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

            #
            # 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))

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

            if conf.exists('v3 user {0} privacy type'.format(user)):
                type = conf.return_value(
                    'v3 user {0} privacy type'.format(user))
                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
Beispiel #27
0
from vyos.config import Config
from vyos.util import cmd, run

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        '--interface',
        action='store',
        help=
        'Interface name which should be added to bridge it is configured for',
        required=True)
    args, unknownargs = parser.parse_known_args()

    conf = Config()
    if not conf.list_nodes('interfaces bridge'):
        #  no bridge interfaces exist .. bail out early
        exit(0)
    else:
        for bridge in conf.list_nodes('interfaces bridge'):
            for member_if in conf.list_nodes(
                    'interfaces bridge {} member interface'.format(bridge)):
                if args.interface == member_if:
                    command = 'brctl addif "{}" "{}"'.format(
                        bridge, args.interface)
                    # let interfaces etc. settle - especially required for OpenVPN bridged interfaces
                    sleep(4)
                    # XXX: This is ignoring any issue, should be cmd but kept as it
                    # XXX: during the migration to not cause any regression
                    run(command)
def get_config(arguments):
    dns = deepcopy(default_config_data)
    conf = Config()
    base = ['service', 'dns', 'forwarding']

    if arguments.dhclient:
        conf.exists = conf.exists_effective
        conf.return_value = conf.return_effective_value
        conf.return_values = conf.return_effective_values

    if not conf.exists(base):
        return None

    conf.set_level(base)

    if conf.exists(['allow-from']):
        dns['allow_from'] = conf.return_values(['allow-from'])

    if conf.exists(['cache-size']):
        cache_size = conf.return_value(['cache-size'])
        dns['cache_size'] = cache_size

    if conf.exists('negative-ttl'):
        negative_ttl = conf.return_value(['negative-ttl'])
        dns['negative_ttl'] = negative_ttl

    if conf.exists(['domain']):
        for node in conf.list_nodes(['domain']):
            servers = conf.return_values(['domain', node, 'server'])
            domain = {"name": node, "servers": bracketize_ipv6_addrs(servers)}
            dns['domains'].append(domain)

    if conf.exists(['ignore-hosts-file']):
        dns['export_hosts_file'] = "no"

    if conf.exists(['name-server']):
        name_servers = conf.return_values(['name-server'])
        dns['name_servers'] = dns['name_servers'] + name_servers

    if conf.exists(['system']):
        conf.set_level(['system'])
        system_name_servers = []
        system_name_servers = conf.return_values(['name-server'])
        if not system_name_servers:
            print(
                "DNS forwarding warning: No name-servers set under 'system name-server'\n"
            )
        else:
            dns['name_servers'] = dns['name_servers'] + system_name_servers
        conf.set_level(base)

    dns['name_servers'] = bracketize_ipv6_addrs(dns['name_servers'])

    if conf.exists(['listen-address']):
        dns['listen_on'] = conf.return_values(['listen-address'])

    if conf.exists(['dnssec']):
        dns['dnssec'] = conf.return_value(['dnssec'])

    # Add name servers received from DHCP
    if conf.exists(['dhcp']):
        interfaces = []
        interfaces = conf.return_values(['dhcp'])
        hc = hostsd_client()

        for interface in interfaces:
            dhcp_resolvers = hc.get_name_servers(f'dhcp-{interface}')
            dhcpv6_resolvers = hc.get_name_servers(f'dhcpv6-{interface}')

            if dhcp_resolvers:
                dns['name_servers'] = dns['name_servers'] + dhcp_resolvers
            if dhcpv6_resolvers:
                dns['name_servers'] = dns['name_servers'] + dhcpv6_resolvers

    return dns
Beispiel #29
0
def get_config():
    c = Config()
    if not c.exists('service pppoe-server'):
        return None

    config_data = {
        'concentrator': 'vyos-ac',
        'authentication': {
            'local-users': {},
            'mode': 'local',
            'radiussrv': {},
            'radiusopt': {}
        },
        'client_ip_pool': '',
        'client_ip_subnets': [],
        'client_ipv6_pool': {},
        'interface': {},
        'ppp_gw': '',
        'svc_name': [],
        'dns': [],
        'dnsv6': [],
        'wins': [],
        'mtu': '1492',
        'ppp_options': {},
        'limits': {},
        'snmp': 'disable',
        'sesscrtl': 'replace',
        'pado_delay': ''
    }

    c.set_level(['service', 'pppoe-server'])
    # general options
    if c.exists(['access-concentrator']):
        config_data['concentrator'] = c.return_value(['access-concentrator'])
    if c.exists(['service-name']):
        config_data['svc_name'] = c.return_values(['service-name'])
    if c.exists(['interface']):
        for intfc in c.list_nodes(['interface']):
            config_data['interface'][intfc] = {'vlans': []}
            if c.exists(['interface', intfc, 'vlan-id']):
                config_data['interface'][intfc]['vlans'] += c.return_values(
                    ['interface', intfc, 'vlan-id'])
            if c.exists(['interface', intfc, 'vlan-range']):
                config_data['interface'][intfc]['vlans'] += c.return_values(
                    ['interface', intfc, 'vlan-range'])
    if c.exists(['local-ip']):
        config_data['ppp_gw'] = c.return_value(['local-ip'])
    if c.exists(['dns-servers']):
        if c.return_value(['dns-servers', 'server-1']):
            config_data['dns'].append(
                c.return_value(['dns-servers', 'server-1']))
        if c.return_value(['dns-servers', 'server-2']):
            config_data['dns'].append(
                c.return_value(['dns-servers', 'server-2']))
    if c.exists(['dnsv6-servers']):
        if c.return_value(['dnsv6-servers', 'server-1']):
            config_data['dnsv6'].append(
                c.return_value(['dnsv6-servers', 'server-1']))
        if c.return_value(['dnsv6-servers', 'server-2']):
            config_data['dnsv6'].append(
                c.return_value(['dnsv6-servers', 'server-2']))
        if c.return_value(['dnsv6-servers', 'server-3']):
            config_data['dnsv6'].append(
                c.return_value(['dnsv6-servers', 'server-3']))
    if c.exists(['wins-servers']):
        if c.return_value(['wins-servers', 'server-1']):
            config_data['wins'].append(
                c.return_value(['wins-servers', 'server-1']))
        if c.return_value(['wins-servers', 'server-2']):
            config_data['wins'].append(
                c.return_value(['wins-servers', 'server-2']))
    if c.exists(['client-ip-pool']):
        if c.exists(['client-ip-pool', 'start']):
            config_data['client_ip_pool'] = c.return_value(
                ['client-ip-pool start'])
            if c.exists(['client-ip-pool stop']):
                config_data['client_ip_pool'] += '-' + re.search(
                    '[0-9]+$', c.return_value(['client-ip-pool', 'stop'
                                               ])).group(0)
            else:
                raise ConfigError('client ip pool stop required')
        if c.exists(['client-ip-pool', 'subnet']):
            config_data['client_ip_subnets'] = c.return_values(
                ['client-ip-pool', 'subnet'])
    if c.exists(['client-ipv6-pool', 'prefix']):
        config_data['client_ipv6_pool']['prefix'] = c.return_values(
            ['client-ipv6-pool', 'prefix'])
        if c.exists(['client-ipv6-pool', 'delegate-prefix']):
            config_data['client_ipv6_pool'][
                'delegate-prefix'] = c.return_values(
                    ['client-ipv6-pool', 'delegate-prefix'])
    if c.exists(['limits']):
        if c.exists(['limits', 'burst']):
            config_data['limits']['burst'] = str(
                c.return_value(['limits', 'burst']))
        if c.exists(['limits', 'timeout']):
            config_data['limits']['timeout'] = str(
                c.return_value(['limits', 'timeout']))
        if c.exists(['limits', 'connection-limit']):
            config_data['limits']['conn-limit'] = str(
                c.return_value(['limits', 'connection-limit']))
    if c.exists(['snmp']):
        config_data['snmp'] = 'enable'
    if c.exists(['snmp', 'master-agent']):
        config_data['snmp'] = 'enable-ma'

    # authentication mode local
    if not c.exists(['authentication', 'mode']):
        raise ConfigError('pppoe-server authentication mode required')

    if c.exists(['authentication', 'mode', 'local']):
        if c.exists(['authentication', 'local-users', 'username']):
            for usr in c.list_nodes(
                ['authentication', 'local-users', 'username']):
                config_data['authentication']['local-users'].update({
                    usr: {
                        'passwd': None,
                        'state': 'enabled',
                        'ip': '*',
                        'upload': None,
                        'download': None
                    }
                })
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'password'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'passwd'] = c.return_value([
                            'authentication', 'local-users', 'username', usr,
                            'password'
                        ])
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'disable'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'state'] = 'disable'
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'static-ip'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'ip'] = c.return_value([
                            'authentication', 'local-users', 'username', usr,
                            'static-ip'
                        ])
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'rate-limit', 'download'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'download'] = c.return_value([
                            'authentication', 'local-users', 'username', usr,
                            'rate-limit', 'download'
                        ])
                if c.exists([
                        'authentication', 'local-users', 'username', usr,
                        'rate-limit', 'upload'
                ]):
                    config_data['authentication']['local-users'][usr][
                        'upload'] = c.return_value([
                            'authentication', 'local-users', 'username', usr,
                            'rate-limit', 'upload'
                        ])

        # authentication mode radius servers and settings

    if c.exists(['authentication', 'mode', 'radius']):
        config_data['authentication']['mode'] = 'radius'
        rsrvs = c.list_nodes(['authentication', 'radius-server'])
        for rsrv in rsrvs:
            if c.return_value(
                ['authentication', 'radius-server', rsrv,
                 'fail-time']) == None:
                ftime = '0'
            else:
                ftime = str(
                    c.return_value(
                        ['authentication', 'radius-server', rsrv,
                         'fail-time']))
            if c.return_value(
                ['authentication', 'radius-server', rsrv,
                 'req-limit']) == None:
                reql = '0'
            else:
                reql = str(
                    c.return_value(
                        ['authentication', 'radius-server', rsrv,
                         'req-limit']))
            config_data['authentication']['radiussrv'].update({
                rsrv: {
                    'secret':
                    c.return_value(
                        ['authentication', 'radius-server', rsrv, 'secret']),
                    'fail-time':
                    ftime,
                    'req-limit':
                    reql
                }
            })

        # advanced radius-setting
        if c.exists(['authentication', 'radius-settings']):
            if c.exists(['authentication', 'radius-settings', 'acct-timeout']):
                config_data['authentication']['radiusopt'][
                    'acct-timeout'] = c.return_value(
                        ['authentication', 'radius-settings', 'acct-timeout'])
            if c.exists(['authentication', 'radius-settings', 'max-try']):
                config_data['authentication']['radiusopt'][
                    'max-try'] = c.return_value(
                        ['authentication', 'radius-settings', 'max-try'])
            if c.exists(['authentication', 'radius-settings', 'timeout']):
                config_data['authentication']['radiusopt'][
                    'timeout'] = c.return_value(
                        ['authentication', 'radius-settings', 'timeout'])
            if c.exists(
                ['authentication', 'radius-settings', 'nas-identifier']):
                config_data['authentication']['radiusopt'][
                    'nas-id'] = c.return_value([
                        'authentication', 'radius-settings', 'nas-identifier'
                    ])
            if c.exists(
                ['authentication', 'radius-settings', 'nas-ip-address']):
                config_data['authentication']['radiusopt'][
                    'nas-ip'] = c.return_value([
                        'authentication', 'radius-settings', 'nas-ip-address'
                    ])
            if c.exists(['authentication', 'radius-settings', 'dae-server']):
                config_data['authentication']['radiusopt'].update({
                    'dae-srv': {
                        'ip-addr':
                        c.return_value([
                            'authentication', 'radius-settings', 'dae-server',
                            'ip-address'
                        ]),
                        'port':
                        c.return_value([
                            'authentication', 'radius-settings', 'dae-server',
                            'port'
                        ]),
                        'secret':
                        str(
                            c.return_value([
                                'authentication', 'radius-settings',
                                'dae-server', 'secret'
                            ]))
                    }
                })
            # filter-id is the internal accel default if attribute is empty
            # set here as default for visibility which may change in the future
            if c.exists(
                ['authentication', 'radius-settings', 'rate-limit', 'enable']):
                if not c.exists([
                        'authentication', 'radius-settings', 'rate-limit',
                        'attribute'
                ]):
                    config_data['authentication']['radiusopt']['shaper'] = {
                        'attr': 'Filter-Id'
                    }
                else:
                    config_data['authentication']['radiusopt']['shaper'] = {
                        'attr':
                        c.return_value([
                            'authentication', 'radius-settings', 'rate-limit',
                            'attribute'
                        ])
                    }
                if c.exists([
                        'authentication', 'radius-settings', 'rate-limit',
                        'vendor'
                ]):
                    config_data['authentication']['radiusopt']['shaper'][
                        'vendor'] = c.return_value([
                            'authentication', 'radius-settings', 'rate-limit',
                            'vendor'
                        ])

    if c.exists(['mtu']):
        config_data['mtu'] = c.return_value(['mtu'])

    # ppp_options
    ppp_options = {}
    if c.exists(['ppp-options']):
        if c.exists(['ppp-options', 'ccp']):
            ppp_options['ccp'] = c.return_value(['ppp-options', 'ccp'])
        if c.exists(['ppp-options', 'min-mtu']):
            ppp_options['min-mtu'] = c.return_value(['ppp-options', 'min-mtu'])
        if c.exists(['ppp-options', 'mru']):
            ppp_options['mru'] = c.return_value(['ppp-options', 'mru'])
        if c.exists(['ppp-options', 'mppe deny']):
            ppp_options['mppe'] = 'deny'
        if c.exists(['ppp-options', 'mppe', 'require']):
            ppp_options['mppe'] = 'require'
        if c.exists(['ppp-options', 'mppe', 'prefer']):
            ppp_options['mppe'] = 'prefer'
        if c.exists(['ppp-options', 'lcp-echo-failure']):
            ppp_options['lcp-echo-failure'] = c.return_value(
                ['ppp-options', 'lcp-echo-failure'])
        if c.exists(['ppp-options', 'lcp-echo-interval']):
            ppp_options['lcp-echo-interval'] = c.return_value(
                ['ppp-options', 'lcp-echo-interval'])
        if c.exists(['ppp-options', 'ipv4']):
            ppp_options['ipv4'] = c.return_value(['ppp-options', 'ipv4'])
        if c.exists(['ppp-options', 'ipv6']):
            ppp_options['ipv6'] = c.return_value(['ppp-options', 'ipv6'])
        if c.exists(['ppp-options', 'ipv6-accept-peer-intf-id']):
            ppp_options['ipv6-accept-peer-intf-id'] = 1
        if c.exists(['ppp-options', 'ipv6-intf-id']):
            ppp_options['ipv6-intf-id'] = c.return_value(
                ['ppp-options', 'ipv6-intf-id'])
        if c.exists(['ppp-options', 'ipv6-peer-intf-id']):
            ppp_options['ipv6-peer-intf-id'] = c.return_value(
                ['ppp-options', 'ipv6-peer-intf-id'])
        if c.exists(['ppp-options', 'lcp-echo-timeout']):
            ppp_options['lcp-echo-timeout'] = c.return_value(
                ['ppp-options', 'lcp-echo-timeout'])

    if len(ppp_options) != 0:
        config_data['ppp_options'] = ppp_options

    if c.exists(['session-control']):
        config_data['sesscrtl'] = c.return_value(['session-control'])

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

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

    return config_data
Beispiel #30
0
def get_config():
    dhcpv6 = deepcopy(default_config_data)
    conf = Config()
    if not conf.exists('service dhcpv6-server'):
        return None
    else:
        conf.set_level('service dhcpv6-server')

    # Check for global disable of DHCPv6 service
    if conf.exists('disable'):
        dhcpv6['disabled'] = True
        return dhcpv6

    # Preference of this DHCPv6 server compared with others
    if conf.exists('preference'):
        dhcpv6['preference'] = conf.return_value('preference')

    # check for multiple, shared networks served with DHCPv6 addresses
    if conf.exists('shared-network-name'):
        for network in conf.list_nodes('shared-network-name'):
            conf.set_level(
                'service dhcpv6-server shared-network-name {0}'.format(
                    network))
            config = {'name': network, 'disabled': False, 'subnet': []}

            # If disabled, the shared-network configuration becomes inactive
            if conf.exists('disable'):
                config['disabled'] = True

            # check for multiple subnet configurations in a shared network
            if conf.exists('subnet'):
                for net in conf.list_nodes('subnet'):
                    conf.set_level(
                        'service dhcpv6-server shared-network-name {0} subnet {1}'
                        .format(network, net))
                    subnet = {
                        'network': net,
                        'range6_prefix': [],
                        'range6': [],
                        'default_router': '',
                        'dns_server': [],
                        'domain_name': '',
                        'domain_search': [],
                        'lease_def': '',
                        'lease_min': '',
                        'lease_max': '',
                        'nis_domain': '',
                        'nis_server': [],
                        'nisp_domain': '',
                        'nisp_server': [],
                        'sip_address': [],
                        'sip_hostname': [],
                        'sntp_server': [],
                        'static_mapping': []
                    }

                    # For any subnet on which addresses will be assigned dynamically, there must be at
                    # least one address range statement. The range statement gives the lowest and highest
                    # IP addresses in a range. All IP addresses in the range should be in the subnet in
                    # which the range statement is declared.
                    if conf.exists('address-range prefix'):
                        for prefix in conf.list_nodes('address-range prefix'):
                            range = {'prefix': prefix, 'temporary': False}

                            # Address range will be used for temporary addresses
                            if conf.exists(
                                    'address-range prefix {0} temporary'.
                                    format(range['prefix'])):
                                range['temporary'] = True

                            # Append to subnet temporary range6 list
                            subnet['range6_prefix'].append(range)

                    if conf.exists('address-range start'):
                        for range in conf.list_nodes('address-range start'):
                            range = {
                                'start':
                                range,
                                'stop':
                                conf.return_value(
                                    'address-range start {0} stop'.format(
                                        range))
                            }

                            # Append to subnet range6 list
                            subnet['range6'].append(range)

                    # The domain-search option specifies a 'search list' of Domain Names to be used
                    # by the client to locate not-fully-qualified domain names.
                    if conf.exists('domain-search'):
                        for domain in conf.return_values('domain-search'):
                            subnet['domain_search'].append('"' + domain + '"')

                    # IPv6 address valid lifetime
                    #  (at the end the address is no longer usable by the client)
                    #  (set to 30 days, the usual IPv6 default)
                    if conf.exists('lease-time default'):
                        subnet['lease_def'] = conf.return_value(
                            'lease-time default')

                    # Time should be the maximum length in seconds that will be assigned to a lease.
                    # The only exception to this is that Dynamic BOOTP lease lengths, which are not
                    # specified by the client, are not limited by this maximum.
                    if conf.exists('lease-time maximum'):
                        subnet['lease_max'] = conf.return_value(
                            'lease-time maximum')

                    # Time should be the minimum length in seconds that will be assigned to a lease
                    if conf.exists('lease-time minimum'):
                        subnet['lease_min'] = conf.return_value(
                            'lease-time minimum')

                    # Specifies a list of Domain Name System name servers available to the client.
                    # Servers should be listed in order of preference.
                    if conf.exists('name-server'):
                        subnet['dns_server'] = conf.return_values(
                            'name-server')

                    # Ancient NIS (Network Information Service) domain name
                    if conf.exists('nis-domain'):
                        subnet['nis_domain'] = conf.return_value('nis-domain')

                    # Ancient NIS (Network Information Service) servers
                    if conf.exists('nis-server'):
                        subnet['nis_server'] = conf.return_values('nis-server')

                    # Ancient NIS+ (Network Information Service) domain name
                    if conf.exists('nisplus-domain'):
                        subnet['nisp_domain'] = conf.return_value(
                            'nisplus-domain')

                    # Ancient NIS+ (Network Information Service) servers
                    if conf.exists('nisplus-server'):
                        subnet['nisp_server'] = conf.return_values(
                            'nisplus-server')

                    # Prefix Delegation (RFC 3633)
                    if conf.exists('prefix-delegation'):
                        print(
                            'TODO: This option is actually not implemented right now!'
                        )

                    # Local SIP server that is to be used for all outbound SIP requests - IPv6 address
                    if conf.exists('sip-server-address'):
                        subnet['sip_address'] = conf.return_values(
                            'sip-server-address')

                    # Local SIP server that is to be used for all outbound SIP requests - hostname
                    if conf.exists('sip-server-name'):
                        for hostname in conf.return_values('sip-server-name'):
                            subnet['sip_hostname'].append('"' + hostname + '"')

                    # List of local SNTP servers available for the client to synchronize their clocks
                    if conf.exists('sntp-server'):
                        subnet['sntp_server'] = conf.return_values(
                            'sntp-server')

                    #
                    # Static DHCP v6 leases
                    #
                    if conf.exists('static-mapping'):
                        for mapping in conf.list_nodes('static-mapping'):
                            conf.set_level(
                                'service dhcpv6-server shared-network-name {0} subnet {1} static-mapping {2}'
                                .format(network, net, mapping))
                            mapping = {
                                'name': mapping,
                                'disabled': False,
                                'ipv6_address': '',
                                'client_identifier': '',
                            }

                            # This static lease is disabled
                            if conf.exists('disable'):
                                mapping['disabled'] = True

                            # IPv6 address used for this DHCP client
                            if conf.exists('ipv6-address'):
                                mapping['ipv6_address'] = conf.return_value(
                                    'ipv6-address')

                            # This option specifies the client’s DUID identifier. DUIDs are similar but different from DHCPv4 client identifiers
                            if conf.exists('identifier'):
                                mapping[
                                    'client_identifier'] = conf.return_value(
                                        'identifier')

                            # append static mapping configuration tu subnet list
                            subnet['static_mapping'].append(mapping)

                    # append subnet configuration to shared network subnet list
                    config['subnet'].append(subnet)

            # append shared network configuration to config dictionary
            dhcpv6['shared_network'].append(config)

    return dhcpv6