def add_addr(self, addr): """ Add IP(v6) address to interface. Address is only added if it is not already assigned to that interface. Address format must be validated and compressed/normalized before calling this function. addr: can be an IPv4 address, IPv6 address, dhcp or dhcpv6! IPv4: add IPv4 address to interface IPv6: add IPv6 address to interface dhcp: start dhclient (IPv4) on interface dhcpv6: start WIDE DHCPv6 (IPv6) on interface Returns False if address is already assigned and wasn't re-added. Example: >>> from vyos.ifconfig import Interface >>> j = Interface('eth0') >>> j.add_addr('192.0.2.1/24') >>> j.add_addr('2001:db8::ffff/64') >>> j.get_addr() ['192.0.2.1/24', '2001:db8::ffff/64'] """ # XXX: normalize/compress with ipaddress if calling functions don't? # is subnet mask always passed, and in the same way? # do not add same address twice if addr in self._addr: return False # we can't have both DHCP and static IPv4 addresses assigned for a in self._addr: if ((addr == 'dhcp' and a != 'dhcpv6' and is_ipv4(a)) or (a == 'dhcp' and addr != 'dhcpv6' and is_ipv4(addr))): raise ConfigError( ("Can't configure both static IPv4 and DHCP address " "on the same interface")) # add to interface if addr == 'dhcp': self.dhcp.v4.set() elif addr == 'dhcpv6': self.dhcp.v6.set() elif not is_intf_addr_assigned(self.ifname, addr): self._cmd(f'ip addr add "{addr}" dev "{self.ifname}"') else: return False # add to cache self._addr.append(addr) return True
def generate(tftpd): # cleanup any available configuration file # files will be recreated on demand for i in glob(config_file + '*'): os.unlink(i) # bail out early - looks like removal from running config if tftpd is None: return None # Prepare Jinja2 template loader from files tmpl_path = os.path.join(vyos_data_dir['data'], 'templates', 'tftp-server') fs_loader = FileSystemLoader(tmpl_path) env = Environment(loader=fs_loader) idx = 0 for listen in tftpd['listen']: config = deepcopy(tftpd) if is_ipv4(listen): config['listen'] = [listen + ":" + tftpd['port'] + " -4"] else: config['listen'] = ["[" + listen + "]" + tftpd['port'] + " -6"] tmpl = env.get_template('default.tmpl') config_text = tmpl.render(config) file = config_file + str(idx) with open(file, 'w') as f: f.write(config_text) idx = idx + 1 return None
def add_addr(self, addr): """ Add IP(v6) address to interface. Address is only added if it is not already assigned to that interface. addr: can be an IPv4 address, IPv6 address, dhcp or dhcpv6! IPv4: add IPv4 address to interface IPv6: add IPv6 address to interface dhcp: start dhclient (IPv4) on interface dhcpv6: start dhclient (IPv6) on interface Example: >>> from vyos.ifconfig import Interface >>> j = Interface('eth0') >>> j.add_addr('192.0.2.1/24') >>> j.add_addr('2001:db8::ffff/64') >>> j.get_addr() ['192.0.2.1/24', '2001:db8::ffff/64'] """ # cache new IP address which is assigned to interface self._addr.append(addr) # we can not have both DHCP and static IPv4 addresses assigned to an interface if 'dhcp' in self._addr: for addr in self._addr: # do not change below 'if' ordering esle you will get an exception as: # ValueError: 'dhcp' does not appear to be an IPv4 or IPv6 address if addr != 'dhcp' and is_ipv4(addr): raise ConfigError( "Can't configure both static IPv4 and DHCP address on the same interface" ) if addr == 'dhcp': self.dhcp.v4.set() elif addr == 'dhcpv6': self.dhcp.v6.set() else: if not is_intf_addr_assigned(self.config['ifname'], addr): cmd = 'ip addr add "{}" dev "{}"'.format( addr, self.config['ifname']) return self._cmd(cmd)
def test_snmp(self): """ Check if SNMP can be configured and service runs """ clients = ['192.0.2.1', '2001:db8::1'] networks = ['192.0.2.128/25', '2001:db8:babe::/48'] listen = ['127.0.0.1', '::1'] for auth in ['ro', 'rw']: community = 'VyOS' + auth self.session.set(base_path + ['community', community, 'authorization', auth]) for client in clients: self.session.set(base_path + ['community', community, 'client', client]) for network in networks: self.session.set(base_path + ['community', community, 'network', network]) for addr in listen: self.session.set(base_path + ['listen-address', addr]) self.session.set(base_path + ['contact', '*****@*****.**']) self.session.set(base_path + ['location', 'qemu']) self.session.commit() # verify listen address, it will be returned as # ['unix:/run/snmpd.socket,udp:127.0.0.1:161,udp6:[::1]:161'] # thus we need to transfor this into a proper list config = get_config_value('agentaddress') expected = 'unix:/run/snmpd.socket' for addr in listen: if is_ipv4(addr): expected += ',udp:{}:161'.format(addr) else: expected += ',udp6:[{}]:161'.format(addr) self.assertTrue(expected in config) # Check for running process self.assertTrue("snmpd" in (p.name() for p in process_iter()))
def generate(tftpd): # cleanup any available configuration file # files will be recreated on demand for i in glob(config_file + '*'): os.unlink(i) # bail out early - looks like removal from running config if tftpd is None: return None idx = 0 for listen in tftpd['listen']: config = deepcopy(tftpd) if is_ipv4(listen): config['listen'] = [listen + ":" + tftpd['port'] + " -4"] else: config['listen'] = ["[" + listen + "]" + tftpd['port'] + " -6"] file = config_file + str(idx) render(file, 'tftp-server/default.tmpl', config) idx = idx + 1 return None
def verify(conf): options = conf['options'] changes = conf['changes'] actions = conf['actions'] ifname = options['ifname'] iftype = options['type'] if changes['section'] == 'delete': if ifname in options['nhrp']: raise ConfigError( f'Can not delete interface tunnel {iftype} {ifname}, it is used by nhrp' ) # done, bail out early return None # tunnel encapsulation checks if not iftype: raise ConfigError( f'Must provide an "encapsulation" for tunnel {iftype} {ifname}') if changes['type'] in ('modify', 'delete'): # TODO: we could now deal with encapsulation modification by deleting / recreating raise ConfigError( f'Encapsulation can only be set at tunnel creation for tunnel {iftype} {ifname}' ) if iftype != 'sit' and options['6rd-prefix']: # XXX: should be able to remove this and let the definition catch it print( f'6RD can only be configured for sit interfaces not tunnel {iftype} {ifname}' ) # what are the tunnel options we can set / modified / deleted kls = get_class(options) valid = kls.updates + ['alias', 'addresses-add', 'addresses-del', 'vrf'] if changes['section'] == 'create': valid.extend([ 'type', ]) valid.extend([o for o in kls.options if o not in kls.updates]) for create in actions['create']: if create not in valid: raise ConfigError( f'Can not set "{create}" for tunnel {iftype} {ifname} at tunnel creation' ) for modify in actions['modify']: if modify not in valid: raise ConfigError( f'Can not modify "{modify}" for tunnel {iftype} {ifname}. it must be set at tunnel creation' ) for delete in actions['delete']: if delete in kls.required: raise ConfigError( f'Can not remove "{delete}", it is an mandatory option for tunnel {iftype} {ifname}' ) # tunnel information tun_local = options['local'] afi_local = get_afi(tun_local) tun_remote = options['remote'] or tun_local afi_remote = get_afi(tun_remote) tun_ismgre = iftype == 'gre' and not options['remote'] tun_is6rd = iftype == 'sit' and options['6rd-prefix'] # incompatible options if not tun_local and not options['dhcp-interface'] and not tun_is6rd: raise ConfigError( f'Must configure either local-ip or dhcp-interface for tunnel {iftype} {ifname}' ) if tun_local and options['dhcp-interface']: raise ConfigError( f'Must configure only one of local-ip or dhcp-interface for tunnel {iftype} {ifname}' ) # tunnel endpoint if afi_local != afi_remote: raise ConfigError( f'IPv4/IPv6 mismatch between local-ip and remote-ip for tunnel {iftype} {ifname}' ) if afi_local != kls.tunnel: version = 4 if tun_local == IP4 else 6 raise ConfigError( f'Invalid IPv{version} local-ip for tunnel {iftype} {ifname}') ipv4_count = len([ip for ip in options['addresses-add'] if is_ipv4(ip)]) ipv6_count = len([ip for ip in options['addresses-add'] if is_ipv6(ip)]) if tun_ismgre and afi_local == IP6: raise ConfigError( f'Using an IPv6 address is forbidden for mGRE tunnels such as tunnel {iftype} {ifname}' ) # check address family use # checks are not enforced (but ip command failing) for backward compatibility if ipv4_count and not IP4 in kls.ip: print(f'Should not use IPv4 addresses on tunnel {iftype} {ifname}') if ipv6_count and not IP6 in kls.ip: print(f'Should not use IPv6 addresses on tunnel {iftype} {ifname}') # tunnel encapsulation check convert = { (6, 4, 'gre'): 'ip6gre', (6, 6, 'gre'): 'ip6gre', (4, 6, 'ipip'): 'ipip6', (6, 6, 'ipip'): 'ip6ip6', } iprotos = [] if ipv4_count: iprotos.append(4) if ipv6_count: iprotos.append(6) for iproto in iprotos: replace = convert.get((kls.tunnel, iproto, iftype), '') if replace: raise ConfigError( f'Using IPv6 address in local-ip or remote-ip is not possible with "encapsulation {iftype}". ' + f'Use "encapsulation {replace}" for tunnel {iftype} {ifname} instead.' ) # tunnel options incompatible = [] if afi_local == IP6: incompatible.extend([ 'ttl', 'tos', 'key', ]) if afi_local == IP4: incompatible.extend(['encaplimit', 'flowlabel', 'hoplimit', 'tclass']) for option in incompatible: if option in options: # TODO: raise converted to print as not enforced by vyatta # raise ConfigError(f'{option} is not valid for tunnel {iftype} {ifname}') print(f'Using "{option}" is invalid for tunnel {iftype} {ifname}') # duplicate tunnel pairs pair = '{}-{}'.format(options['local'], options['remote']) if options['tunnel'].get(iftype, {}).get(pair, 0) > 1: raise ConfigError( f'More than one tunnel configured for with the same encapulation and IPs for tunnel {iftype} {ifname}' ) return None
def get_config(): sstp = deepcopy(default_config_data) base_path = ['vpn', 'sstp'] conf = Config() if not conf.exists(base_path): return None conf.set_level(base_path) if conf.exists(['authentication', 'mode']): sstp['auth_mode'] = conf.return_value(['authentication', 'mode']) # # local auth if conf.exists(['authentication', 'local-users']): for username in conf.list_nodes( ['authentication', 'local-users', 'username']): user = { 'name': username, 'password': '', 'state': 'enabled', 'ip': '*', 'upload': None, 'download': None } conf.set_level( base_path + ['authentication', 'local-users', 'username', username]) if conf.exists(['password']): user['password'] = conf.return_value(['password']) if conf.exists(['disable']): user['state'] = 'disable' if conf.exists(['static-ip']): user['ip'] = conf.return_value(['static-ip']) if conf.exists(['rate-limit', 'download']): user['download'] = conf.return_value( ['rate-limit', 'download']) if conf.exists(['rate-limit', 'upload']): user['upload'] = conf.return_value(['rate-limit', 'upload']) sstp['local_users'].append(user) # # RADIUS auth and settings conf.set_level(base_path + ['authentication', 'radius']) if conf.exists(['server']): for server in conf.list_nodes(['server']): radius = { 'server': server, 'key': '', 'fail_time': 0, 'port': '1812' } conf.set_level(base_path + ['authentication', 'radius', 'server', server]) if conf.exists(['fail-time']): radius['fail-time'] = conf.return_value(['fail-time']) if conf.exists(['port']): radius['port'] = conf.return_value(['port']) if conf.exists(['key']): radius['key'] = conf.return_value(['key']) if not conf.exists(['disable']): sstp['radius_server'].append(radius) # # advanced radius-setting conf.set_level(base_path + ['authentication', 'radius']) if conf.exists(['acct-timeout']): sstp['radius_acct_tmo'] = conf.return_value(['acct-timeout']) if conf.exists(['max-try']): sstp['radius_max_try'] = conf.return_value(['max-try']) if conf.exists(['timeout']): sstp['radius_timeout'] = conf.return_value(['timeout']) if conf.exists(['nas-identifier']): sstp['radius_nas_id'] = conf.return_value(['nas-identifier']) if conf.exists(['nas-ip-address']): sstp['radius_nas_ip'] = conf.return_value(['nas-ip-address']) if conf.exists(['source-address']): sstp['radius_source_address'] = conf.return_value( ['source-address']) # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA) if conf.exists(['dynamic-author']): dae = {'port': '', 'server': '', 'key': ''} if conf.exists(['dynamic-author', 'server']): dae['server'] = conf.return_value(['dynamic-author', 'server']) if conf.exists(['dynamic-author', 'port']): dae['port'] = conf.return_value(['dynamic-author', 'port']) if conf.exists(['dynamic-author', 'key']): dae['key'] = conf.return_value(['dynamic-author', 'key']) sstp['radius_dynamic_author'] = dae if conf.exists(['rate-limit', 'enable']): sstp['radius_shaper_attr'] = 'Filter-Id' c_attr = ['rate-limit', 'enable', 'attribute'] if conf.exists(c_attr): sstp['radius_shaper_attr'] = conf.return_value(c_attr) c_vendor = ['rate-limit', 'enable', 'vendor'] if conf.exists(c_vendor): sstp['radius_shaper_vendor'] = conf.return_value(c_vendor) # # authentication protocols conf.set_level(base_path + ['authentication']) if conf.exists(['protocols']): # clear default list content, now populate with actual CLI values sstp['auth_proto'] = [] auth_mods = { 'pap': 'auth_pap', 'chap': 'auth_chap_md5', 'mschap': 'auth_mschap_v1', 'mschap-v2': 'auth_mschap_v2' } for proto in conf.return_values(['protocols']): sstp['auth_proto'].append(auth_mods[proto]) # # read in SSL certs conf.set_level(base_path + ['ssl']) if conf.exists(['ca-cert-file']): sstp['ssl_ca'] = conf.return_value(['ca-cert-file']) if conf.exists(['cert-file']): sstp['ssl_cert'] = conf.return_value(['cert-file']) if conf.exists(['key-file']): sstp['ssl_key'] = conf.return_value(['key-file']) # # read in client IPv4 pool conf.set_level(base_path + ['network-settings', 'client-ip-settings']) if conf.exists(['subnet']): sstp['client_ip_pool'] = conf.return_values(['subnet']) if conf.exists(['gateway-address']): sstp['client_gateway'] = conf.return_value(['gateway-address']) # # read in client IPv6 pool conf.set_level(base_path + ['network-settings', 'client-ipv6-pool']) if conf.exists(['prefix']): for prefix in conf.list_nodes(['prefix']): tmp = {'prefix': prefix, 'mask': '64'} if conf.exists(['prefix', prefix, 'mask']): tmp['mask'] = conf.return_value(['prefix', prefix, 'mask']) sstp['client_ipv6_pool'].append(tmp) if conf.exists(['delegate']): for prefix in conf.list_nodes(['delegate']): tmp = {'prefix': prefix, 'mask': ''} if conf.exists(['delegate', prefix, 'delegation-prefix']): tmp['mask'] = conf.return_value( ['delegate', prefix, 'delegation-prefix']) sstp['client_ipv6_delegate_prefix'].append(tmp) # # read in network settings conf.set_level(base_path + ['network-settings']) if conf.exists(['name-server']): for name_server in conf.return_values(['name-server']): if is_ipv4(name_server): sstp['dnsv4'].append(name_server) else: sstp['dnsv6'].append(name_server) if conf.exists(['mtu']): sstp['mtu'] = conf.return_value(['mtu']) # # read in PPP stuff conf.set_level(base_path + ['ppp-settings']) if conf.exists('mppe'): sstp['ppp_mppe'] = conf.return_value(['ppp-settings', 'mppe']) if conf.exists(['lcp-echo-failure']): sstp['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure']) if conf.exists(['lcp-echo-interval']): sstp['ppp_echo_interval'] = conf.return_value(['lcp-echo-interval']) if conf.exists(['lcp-echo-timeout']): sstp['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout']) return sstp
def get_config(): conf = Config() base_path = ['service', 'ipoe-server'] if not conf.exists(base_path): return None conf.set_level(base_path) ipoe = deepcopy(default_config_data) for interface in conf.list_nodes(['interface']): tmp = { 'mode': 'L2', 'name': interface, 'shared': '1', # may need a config option, can be dhcpv4 or up for unclassified pkts 'sess_start': 'dhcpv4', 'range': None, 'ifcfg': '1', 'vlan_mon': [] } conf.set_level(base_path + ['interface', interface]) if conf.exists(['network-mode']): tmp['mode'] = conf.return_value(['network-mode']) if conf.exists(['network']): mode = conf.return_value(['network']) if mode == 'vlan': tmp['shared'] = '0' if conf.exists(['vlan-id']): tmp['vlan_mon'] += conf.return_values(['vlan-id']) if conf.exists(['vlan-range']): tmp['vlan_mon'] += conf.return_values(['vlan-range']) if conf.exists(['client-subnet']): tmp['range'] = conf.return_value(['client-subnet']) ipoe['interfaces'].append(tmp) conf.set_level(base_path) if conf.exists(['name-server']): for name_server in conf.return_values(['name-server']): if is_ipv4(name_server): ipoe['dnsv4'].append(name_server) else: ipoe['dnsv6'].append(name_server) if conf.exists(['authentication', 'mode']): ipoe['auth_mode'] = conf.return_value(['authentication', 'mode']) if conf.exists(['authentication', 'interface']): for interface in conf.list_nodes(['authentication', 'interface']): tmp = {'name': interface, 'mac': []} for mac in conf.list_nodes( ['authentication', 'interface', interface, 'mac-address']): client = { 'address': mac, 'rate_download': '', 'rate_upload': '', 'vlan_id': '' } conf.set_level(base_path + [ 'authentication', 'interface', interface, 'mac-address', mac ]) if conf.exists(['rate-limit', 'download']): client['rate_download'] = conf.return_value( ['rate-limit', 'download']) if conf.exists(['rate-limit', 'upload']): client['rate_upload'] = conf.return_value( ['rate-limit', 'upload']) if conf.exists(['vlan-id']): client['vlan'] = conf.return_value(['vlan-id']) tmp['mac'].append(client) ipoe['auth_interfaces'].append(tmp) conf.set_level(base_path) # # authentication mode radius servers and settings if conf.exists(['authentication', 'mode', 'radius']): for server in conf.list_nodes(['authentication', 'radius', 'server']): radius = { 'server': server, 'key': '', 'fail_time': 0, 'port': '1812' } conf.set_level(base_path + ['authentication', 'radius', 'server', server]) if conf.exists(['fail-time']): radius['fail-time'] = conf.return_value(['fail-time']) if conf.exists(['port']): radius['port'] = conf.return_value(['port']) if conf.exists(['key']): radius['key'] = conf.return_value(['key']) if not conf.exists(['disable']): ipoe['radius_server'].append(radius) # # advanced radius-setting conf.set_level(base_path + ['authentication', 'radius']) if conf.exists(['acct-timeout']): ipoe['radius_acct_tmo'] = conf.return_value(['acct-timeout']) if conf.exists(['max-try']): ipoe['radius_max_try'] = conf.return_value(['max-try']) if conf.exists(['timeout']): ipoe['radius_timeout'] = conf.return_value(['timeout']) if conf.exists(['nas-identifier']): ipoe['radius_nas_id'] = conf.return_value(['nas-identifier']) if conf.exists(['nas-ip-address']): ipoe['radius_nas_ip'] = conf.return_value(['nas-ip-address']) if conf.exists(['source-address']): ipoe['radius_source_address'] = conf.return_value(['source-address']) # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA) if conf.exists(['dynamic-author']): dae = {'port': '', 'server': '', 'key': ''} if conf.exists(['dynamic-author', 'server']): dae['server'] = conf.return_value(['dynamic-author', 'server']) if conf.exists(['dynamic-author', 'port']): dae['port'] = conf.return_value(['dynamic-author', 'port']) if conf.exists(['dynamic-author', 'key']): dae['key'] = conf.return_value(['dynamic-author', 'key']) ipoe['radius_dynamic_author'] = dae conf.set_level(base_path) if conf.exists(['client-ipv6-pool', 'prefix']): for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']): tmp = {'prefix': prefix, 'mask': '64'} if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']): tmp['mask'] = conf.return_value( ['client-ipv6-pool', 'prefix', prefix, 'mask']) ipoe['client_ipv6_pool'].append(tmp) if conf.exists(['client-ipv6-pool', 'delegate']): for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']): tmp = {'prefix': prefix, 'mask': ''} if conf.exists( ['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']): tmp['mask'] = conf.return_value([ 'client-ipv6-pool', 'delegate', prefix, 'delegation-prefix' ]) ipoe['client_ipv6_delegate_prefix'].append(tmp) return ipoe
def get_config(): snmp = default_config_data conf = Config() if not conf.exists('service snmp'): return None else: if conf.exists('system ipv6 disable'): snmp['ipv6_enabled'] = False conf.set_level('service snmp') version_data = get_version_data() snmp['version'] = version_data['version'] # create an internal snmpv3 user of the form 'vyosxxxxxxxxxxxxxxxx' # os.urandom(8) returns 8 bytes of random data snmp['vyos_user'] = '******' + hexlify(os.urandom(8)).decode('utf-8') snmp['vyos_user_pass'] = hexlify(os.urandom(16)).decode('utf-8') if conf.exists('community'): for name in conf.list_nodes('community'): community = { 'name': name, 'authorization': 'ro', 'network_v4': [], 'network_v6': [], 'has_source': False } if conf.exists('community {0} authorization'.format(name)): community['authorization'] = conf.return_value( 'community {0} authorization'.format(name)) # Subnet of SNMP client(s) allowed to contact system if conf.exists('community {0} network'.format(name)): for addr in conf.return_values( 'community {0} network'.format(name)): if is_ipv4(addr): community['network_v4'].append(addr) else: community['network_v6'].append(addr) # IP address of SNMP client allowed to contact system if conf.exists('community {0} client'.format(name)): for addr in conf.return_values( 'community {0} client'.format(name)): if is_ipv4(addr): community['network_v4'].append(addr) else: community['network_v6'].append(addr) if (len(community['network_v4']) > 0) or (len( community['network_v6']) > 0): community['has_source'] = True snmp['communities'].append(community) if conf.exists('contact'): snmp['contact'] = conf.return_value('contact') if conf.exists('description'): snmp['description'] = conf.return_value('description') if conf.exists('listen-address'): for addr in conf.list_nodes('listen-address'): port = '161' if conf.exists('listen-address {0} port'.format(addr)): port = conf.return_value( 'listen-address {0} port'.format(addr)) snmp['listen_address'].append((addr, port)) # Always listen on localhost if an explicit address has been configured # This is a safety measure to not end up with invalid listen addresses # that are not configured on this system. See https://phabricator.vyos.net/T850 if not '127.0.0.1' in conf.list_nodes('listen-address'): snmp['listen_address'].append(('127.0.0.1', '161')) if not '::1' in conf.list_nodes('listen-address'): snmp['listen_address'].append(('::1', '161')) if conf.exists('location'): snmp['location'] = conf.return_value('location') if conf.exists('smux-peer'): snmp['smux_peers'] = conf.return_values('smux-peer') if conf.exists('trap-source'): snmp['trap_source'] = conf.return_value('trap-source') if conf.exists('trap-target'): for target in conf.list_nodes('trap-target'): trap_tgt = {'target': target, 'community': '', 'port': ''} if conf.exists('trap-target {0} community'.format(target)): trap_tgt['community'] = conf.return_value( 'trap-target {0} community'.format(target)) if conf.exists('trap-target {0} port'.format(target)): trap_tgt['port'] = conf.return_value( 'trap-target {0} port'.format(target)) snmp['trap_targets'].append(trap_tgt) # # 'set service snmp script-extensions' # if conf.exists('script-extensions'): for extname in conf.list_nodes('script-extensions extension-name'): conf_script = conf.return_value( 'script-extensions extension-name {} script'.format(extname)) # if script has not absolute path, use pre configured path if "/" not in conf_script: conf_script = default_script_dir + conf_script extension = {'name': extname, 'script': conf_script} snmp['script_ext'].append(extension) ######################################################################### # ____ _ _ __ __ ____ _____ # # / ___|| \ | | \/ | _ \ __ _|___ / # # \___ \| \| | |\/| | |_) | \ \ / / |_ \ # # ___) | |\ | | | | __/ \ V / ___) | # # |____/|_| \_|_| |_|_| \_/ |____/ # # # # now take care about the fancy SNMP v3 stuff, or bail out eraly # ######################################################################### if not conf.exists('v3'): return snmp else: snmp['v3_enabled'] = True # 'set service snmp v3 engineid' if conf.exists('v3 engineid'): snmp['v3_engineid'] = conf.return_value('v3 engineid') # 'set service snmp v3 group' if conf.exists('v3 group'): for group in conf.list_nodes('v3 group'): v3_group = { 'name': group, 'mode': 'ro', 'seclevel': 'auth', 'view': '' } if conf.exists('v3 group {0} mode'.format(group)): v3_group['mode'] = conf.return_value( 'v3 group {0} mode'.format(group)) if conf.exists('v3 group {0} seclevel'.format(group)): v3_group['seclevel'] = conf.return_value( 'v3 group {0} seclevel'.format(group)) if conf.exists('v3 group {0} view'.format(group)): v3_group['view'] = conf.return_value( 'v3 group {0} view'.format(group)) snmp['v3_groups'].append(v3_group) # 'set service snmp v3 trap-target' if conf.exists('v3 trap-target'): for trap in conf.list_nodes('v3 trap-target'): trap_cfg = { 'ipAddr': trap, 'secName': '', 'authProtocol': 'md5', 'authPassword': '', 'authMasterKey': '', 'privProtocol': 'des', 'privPassword': '', 'privMasterKey': '', 'ipProto': 'udp', 'ipPort': '162', 'type': '', 'secLevel': 'noAuthNoPriv' } if conf.exists('v3 trap-target {0} user'.format(trap)): # Set the securityName used for authenticated SNMPv3 messages. trap_cfg['secName'] = conf.return_value( 'v3 trap-target {0} user'.format(trap)) if conf.exists('v3 trap-target {0} auth type'.format(trap)): # Set the authentication protocol (MD5 or SHA) used for authenticated SNMPv3 messages # cmdline option '-a' trap_cfg['authProtocol'] = conf.return_value( 'v3 trap-target {0} auth type'.format(trap)) if conf.exists( 'v3 trap-target {0} auth plaintext-key'.format(trap)): # Set the authentication pass phrase used for authenticated SNMPv3 messages. # cmdline option '-A' trap_cfg['authPassword'] = conf.return_value( 'v3 trap-target {0} auth plaintext-key'.format(trap)) if conf.exists( 'v3 trap-target {0} auth encrypted-key'.format(trap)): # Sets the keys to be used for SNMPv3 transactions. These options allow you to set the master authentication keys. # cmdline option '-3m' trap_cfg['authMasterKey'] = conf.return_value( 'v3 trap-target {0} auth encrypted-key'.format(trap)) if conf.exists('v3 trap-target {0} privacy type'.format(trap)): # Set the privacy protocol (DES or AES) used for encrypted SNMPv3 messages. # cmdline option '-x' trap_cfg['privProtocol'] = conf.return_value( 'v3 trap-target {0} privacy type'.format(trap)) if conf.exists( 'v3 trap-target {0} privacy plaintext-key'.format(trap)): # Set the privacy pass phrase used for encrypted SNMPv3 messages. # cmdline option '-X' trap_cfg['privPassword'] = conf.return_value( 'v3 trap-target {0} privacy plaintext-key'.format(trap)) if conf.exists( 'v3 trap-target {0} privacy encrypted-key'.format(trap)): # Sets the keys to be used for SNMPv3 transactions. These options allow you to set the master encryption keys. # cmdline option '-3M' trap_cfg['privMasterKey'] = conf.return_value( 'v3 trap-target {0} privacy encrypted-key'.format(trap)) if conf.exists('v3 trap-target {0} protocol'.format(trap)): trap_cfg['ipProto'] = conf.return_value( 'v3 trap-target {0} protocol'.format(trap)) if conf.exists('v3 trap-target {0} port'.format(trap)): trap_cfg['ipPort'] = conf.return_value( 'v3 trap-target {0} port'.format(trap)) if conf.exists('v3 trap-target {0} type'.format(trap)): trap_cfg['type'] = conf.return_value( 'v3 trap-target {0} type'.format(trap)) # Determine securityLevel used for SNMPv3 messages (noAuthNoPriv|authNoPriv|authPriv). # Appropriate pass phrase(s) must provided when using any level higher than noAuthNoPriv. if trap_cfg['authPassword'] or trap_cfg['authMasterKey']: if trap_cfg['privProtocol'] or trap_cfg['privPassword']: trap_cfg['secLevel'] = 'authPriv' else: trap_cfg['secLevel'] = 'authNoPriv' snmp['v3_traps'].append(trap_cfg) # 'set service snmp v3 user' if conf.exists('v3 user'): for user in conf.list_nodes('v3 user'): user_cfg = { 'name': user, 'authMasterKey': '', 'authPassword': '', 'authProtocol': 'md5', 'authOID': 'none', 'group': '', 'mode': 'ro', 'privMasterKey': '', 'privPassword': '', 'privOID': '', 'privProtocol': 'des' } # v3 user {0} auth if conf.exists('v3 user {0} auth encrypted-key'.format(user)): user_cfg['authMasterKey'] = conf.return_value( 'v3 user {0} auth encrypted-key'.format(user)) if conf.exists('v3 user {0} auth plaintext-key'.format(user)): user_cfg['authPassword'] = conf.return_value( 'v3 user {0} auth plaintext-key'.format(user)) # load default value type = user_cfg['authProtocol'] if conf.exists('v3 user {0} auth type'.format(user)): type = conf.return_value('v3 user {0} auth type'.format(user)) # (re-)update with either default value or value from CLI user_cfg['authProtocol'] = type user_cfg['authOID'] = OIDs[type] # v3 user {0} group if conf.exists('v3 user {0} group'.format(user)): user_cfg['group'] = conf.return_value( 'v3 user {0} group'.format(user)) # v3 user {0} mode if conf.exists('v3 user {0} mode'.format(user)): user_cfg['mode'] = conf.return_value( 'v3 user {0} mode'.format(user)) # v3 user {0} privacy if conf.exists('v3 user {0} privacy encrypted-key'.format(user)): user_cfg['privMasterKey'] = conf.return_value( 'v3 user {0} privacy encrypted-key'.format(user)) if conf.exists('v3 user {0} privacy plaintext-key'.format(user)): user_cfg['privPassword'] = conf.return_value( 'v3 user {0} privacy plaintext-key'.format(user)) # load default value type = user_cfg['privProtocol'] if conf.exists('v3 user {0} privacy type'.format(user)): type = conf.return_value( 'v3 user {0} privacy type'.format(user)) # (re-)update with either default value or value from CLI user_cfg['privProtocol'] = type user_cfg['privOID'] = OIDs[type] snmp['v3_users'].append(user_cfg) # 'set service snmp v3 view' if conf.exists('v3 view'): for view in conf.list_nodes('v3 view'): view_cfg = {'name': view, 'oids': []} if conf.exists('v3 view {0} oid'.format(view)): for oid in conf.list_nodes('v3 view {0} oid'.format(view)): oid_cfg = {'oid': oid} view_cfg['oids'].append(oid_cfg) snmp['v3_views'].append(view_cfg) return snmp
def verify(snmp): if snmp is None: # we can not delete SNMP when LLDP is configured with SNMP conf = Config() if conf.exists('service lldp snmp enable'): raise ConfigError( 'Can not delete SNMP service, as LLDP still uses SNMP!') return None ### check if the configured script actually exist if snmp['script_ext']: for ext in snmp['script_ext']: if not os.path.isfile(ext['script']): print("WARNING: script: {} doesn't exist".format( ext['script'])) else: os.chmod(ext['script'], S_IRWXU | S_IXGRP | S_IXOTH | S_IROTH | S_IRGRP) for listen in snmp['listen_address']: addr = listen[0] port = listen[1] if is_ipv4(addr): # example: udp:127.0.0.1:161 listen = 'udp:' + addr + ':' + port elif snmp['ipv6_enabled']: # example: udp6:[::1]:161 listen = 'udp6:' + '[' + addr + ']' + ':' + port # We only wan't to configure addresses that exist on the system. # Hint the user if they don't exist if is_addr_assigned(addr): snmp['listen_on'].append(listen) else: print('WARNING: SNMP listen address {0} not configured!'.format( addr)) # bail out early if SNMP v3 is not configured if not snmp['v3_enabled']: return None if 'v3_groups' in snmp.keys(): for group in snmp['v3_groups']: # # A view must exist prior to mapping it into a group # if 'view' in group.keys(): error = True if 'v3_views' in snmp.keys(): for view in snmp['v3_views']: if view['name'] == group['view']: error = False if error: raise ConfigError( 'You must create view "{0}" first'.format( group['view'])) else: raise ConfigError('"view" must be specified') if not 'mode' in group.keys(): raise ConfigError('"mode" must be specified') if not 'seclevel' in group.keys(): raise ConfigError('"seclevel" must be specified') if 'v3_traps' in snmp.keys(): for trap in snmp['v3_traps']: if trap['authPassword'] and trap['authMasterKey']: raise ConfigError( 'Must specify only one of encrypted-key/plaintext-key for trap auth' ) if trap['authPassword'] == '' and trap['authMasterKey'] == '': raise ConfigError( 'Must specify encrypted-key or plaintext-key for trap auth' ) if trap['privPassword'] and trap['privMasterKey']: raise ConfigError( 'Must specify only one of encrypted-key/plaintext-key for trap privacy' ) if trap['privPassword'] == '' and trap['privMasterKey'] == '': raise ConfigError( 'Must specify encrypted-key or plaintext-key for trap privacy' ) if not 'type' in trap.keys(): raise ConfigError('v3 trap: "type" must be specified') if not 'authPassword' and 'authMasterKey' in trap.keys(): raise ConfigError('v3 trap: "auth" must be specified') if not 'authProtocol' in trap.keys(): raise ConfigError('v3 trap: "protocol" must be specified') if not 'privPassword' and 'privMasterKey' in trap.keys(): raise ConfigError('v3 trap: "user" must be specified') if 'v3_users' in snmp.keys(): for user in snmp['v3_users']: # # Group must exist prior to mapping it into a group # seclevel will be extracted from group # if user['group']: error = True if 'v3_groups' in snmp.keys(): for group in snmp['v3_groups']: if group['name'] == user['group']: seclevel = group['seclevel'] error = False if error: raise ConfigError( 'You must create group "{0}" first'.format( user['group'])) # Depending on the configured security level # the user has to provide additional info if user['authPassword'] and user['authMasterKey']: raise ConfigError( 'Can not mix "encrypted-key" and "plaintext-key" for user auth' ) if (not user['authPassword'] and not user['authMasterKey']): raise ConfigError( 'Must specify encrypted-key or plaintext-key for user auth' ) if user['privPassword'] and user['privMasterKey']: raise ConfigError( 'Can not mix "encrypted-key" and "plaintext-key" for user privacy' ) if user['privPassword'] == '' and user['privMasterKey'] == '': raise ConfigError( 'Must specify encrypted-key or plaintext-key for user privacy' ) if user['mode'] == '': raise ConfigError('Must specify user mode ro/rw') if 'v3_views' in snmp.keys(): for view in snmp['v3_views']: if not view['oids']: raise ConfigError('Must configure an oid') return None
def get_config(): conf = Config() base_path = ['vpn', 'l2tp', 'remote-access'] if not conf.exists(base_path): return None conf.set_level(base_path) l2tp = deepcopy(default_config_data) cpu = os.cpu_count() if cpu > 1: l2tp['thread_cnt'] = int(cpu/2) ### general options ### if conf.exists(['name-server']): for name_server in conf.return_values(['name-server']): if is_ipv4(name_server): l2tp['dnsv4'].append(name_server) else: l2tp['dnsv6'].append(name_server) if conf.exists(['wins-server']): l2tp['wins'] = conf.return_values(['wins-server']) if conf.exists('outside-address'): l2tp['outside_addr'] = conf.return_value('outside-address') if conf.exists(['authentication', 'mode']): l2tp['auth_mode'] = conf.return_value(['authentication', 'mode']) if conf.exists(['authentication', 'protocols']): auth_mods = { 'pap': 'auth_pap', 'chap': 'auth_chap_md5', 'mschap': 'auth_mschap_v1', 'mschap-v2': 'auth_mschap_v2' } for proto in conf.return_values(['authentication', 'protocols']): l2tp['auth_proto'].append(auth_mods[proto]) if conf.exists(['authentication', 'mppe']): l2tp['auth_ppp_mppe'] = conf.return_value(['authentication', 'mppe']) # # local auth if conf.exists(['authentication', 'local-users']): for username in conf.list_nodes(['authentication', 'local-users', 'username']): user = { 'name' : username, 'password' : '', 'state' : 'enabled', 'ip' : '*', 'upload' : None, 'download' : None } conf.set_level(base_path + ['authentication', 'local-users', 'username', username]) if conf.exists(['password']): user['password'] = conf.return_value(['password']) if conf.exists(['disable']): user['state'] = 'disable' if conf.exists(['static-ip']): user['ip'] = conf.return_value(['static-ip']) if conf.exists(['rate-limit', 'download']): user['download'] = conf.return_value(['rate-limit', 'download']) if conf.exists(['rate-limit', 'upload']): user['upload'] = conf.return_value(['rate-limit', 'upload']) l2tp['local_users'].append(user) # # RADIUS auth and settings conf.set_level(base_path + ['authentication', 'radius']) if conf.exists(['server']): for server in conf.list_nodes(['server']): radius = { 'server' : server, 'key' : '', 'fail_time' : 0, 'port' : '1812' } conf.set_level(base_path + ['authentication', 'radius', 'server', server]) if conf.exists(['fail-time']): radius['fail-time'] = conf.return_value(['fail-time']) if conf.exists(['port']): radius['port'] = conf.return_value(['port']) if conf.exists(['key']): radius['key'] = conf.return_value(['key']) if not conf.exists(['disable']): l2tp['radius_server'].append(radius) # # advanced radius-setting conf.set_level(base_path + ['authentication', 'radius']) if conf.exists(['acct-timeout']): l2tp['radius_acct_tmo'] = conf.return_value(['acct-timeout']) if conf.exists(['max-try']): l2tp['radius_max_try'] = conf.return_value(['max-try']) if conf.exists(['timeout']): l2tp['radius_timeout'] = conf.return_value(['timeout']) if conf.exists(['nas-identifier']): l2tp['radius_nas_id'] = conf.return_value(['nas-identifier']) if conf.exists(['nas-ip-address']): l2tp['radius_nas_ip'] = conf.return_value(['nas-ip-address']) if conf.exists(['source-address']): l2tp['radius_source_address'] = conf.return_value(['source-address']) # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA) if conf.exists(['dynamic-author']): dae = { 'port' : '', 'server' : '', 'key' : '' } if conf.exists(['dynamic-author', 'server']): dae['server'] = conf.return_value(['dynamic-author', 'server']) if conf.exists(['dynamic-author', 'port']): dae['port'] = conf.return_value(['dynamic-author', 'port']) if conf.exists(['dynamic-author', 'key']): dae['key'] = conf.return_value(['dynamic-author', 'key']) l2tp['radius_dynamic_author'] = dae if conf.exists(['rate-limit', 'enable']): l2tp['radius_shaper_attr'] = 'Filter-Id' c_attr = ['rate-limit', 'enable', 'attribute'] if conf.exists(c_attr): l2tp['radius_shaper_attr'] = conf.return_value(c_attr) c_vendor = ['rate-limit', 'enable', 'vendor'] if conf.exists(c_vendor): l2tp['radius_shaper_vendor'] = conf.return_value(c_vendor) conf.set_level(base_path) if conf.exists(['client-ip-pool']): if conf.exists(['client-ip-pool', 'start']) and conf.exists(['client-ip-pool', 'stop']): start = conf.return_value(['client-ip-pool', 'start']) stop = conf.return_value(['client-ip-pool', 'stop']) l2tp['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0) if conf.exists(['client-ip-pool', 'subnet']): l2tp['client_ip_subnets'] = conf.return_values(['client-ip-pool', 'subnet']) if conf.exists(['client-ipv6-pool', 'prefix']): l2tp['ip6_column'].append('ip6') for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']): tmp = { 'prefix': prefix, 'mask': '64' } if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']): tmp['mask'] = conf.return_value(['client-ipv6-pool', 'prefix', prefix, 'mask']) l2tp['client_ipv6_pool'].append(tmp) if conf.exists(['client-ipv6-pool', 'delegate']): l2tp['ip6_column'].append('ip6-db') for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']): tmp = { 'prefix': prefix, 'mask': '' } if conf.exists(['client-ipv6-pool', 'delegate', prefix, 'mask']): tmp['mask'] = conf.return_value(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']) l2tp['client_ipv6_delegate_prefix'].append(tmp) if conf.exists(['mtu']): l2tp['mtu'] = conf.return_value(['mtu']) # gateway address if conf.exists(['gateway-address']): l2tp['gateway_address'] = conf.return_value(['gateway-address']) else: # calculate gw-ip-address if conf.exists(['client-ip-pool', 'start']): # use start ip as gw-ip-address l2tp['gateway_address'] = conf.return_value(['client-ip-pool', 'start']) elif conf.exists(['client-ip-pool', 'subnet']): # use first ip address from first defined pool subnet = conf.return_values(['client-ip-pool', 'subnet'])[0] subnet = ip_network(subnet) l2tp['gateway_address'] = str(list(subnet.hosts())[0]) # LNS secret if conf.exists(['lns', 'shared-secret']): l2tp['lns_shared_secret'] = conf.return_value(['lns', 'shared-secret']) if conf.exists(['ccp-disable']): l2tp[['ccp_disable']] = True # PPP options if conf.exists(['idle']): l2tp['ppp_echo_timeout'] = conf.return_value(['idle']) if conf.exists(['ppp-options', 'lcp-echo-failure']): l2tp['ppp_echo_failure'] = conf.return_value(['ppp-options', 'lcp-echo-failure']) if conf.exists(['ppp-options', 'lcp-echo-interval']): l2tp['ppp_echo_interval'] = conf.return_value(['ppp-options', 'lcp-echo-interval']) return l2tp
def get_config(): conf = Config() base_path = ['service', 'pppoe-server'] if not conf.exists(base_path): return None conf.set_level(base_path) pppoe = deepcopy(default_config_data) # general options if conf.exists(['access-concentrator']): pppoe['concentrator'] = conf.return_value(['access-concentrator']) if conf.exists(['service-name']): pppoe['svc_name'] = conf.return_values(['service-name']) if conf.exists(['interface']): for interface in conf.list_nodes(['interface']): conf.set_level(base_path + ['interface', interface]) tmp = {'name': interface, 'vlans': []} if conf.exists(['vlan-id']): tmp['vlans'] += conf.return_values(['vlan-id']) if conf.exists(['vlan-range']): tmp['vlans'] += conf.return_values(['vlan-range']) pppoe['interfaces'].append(tmp) conf.set_level(base_path) if conf.exists(['local-ip']): pppoe['ppp_gw'] = conf.return_value(['local-ip']) if conf.exists(['name-server']): for name_server in conf.return_values(['name-server']): if is_ipv4(name_server): pppoe['dnsv4'].append(name_server) else: pppoe['dnsv6'].append(name_server) if conf.exists(['wins-server']): pppoe['wins'] = conf.return_values(['wins-server']) if conf.exists(['client-ip-pool']): if conf.exists(['client-ip-pool', 'start']) and conf.exists( ['client-ip-pool', 'stop']): start = conf.return_value(['client-ip-pool', 'start']) stop = conf.return_value(['client-ip-pool', 'stop']) pppoe['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0) if conf.exists(['client-ip-pool', 'subnet']): pppoe['client_ip_subnets'] = conf.return_values( ['client-ip-pool', 'subnet']) if conf.exists(['client-ipv6-pool', 'prefix']): for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']): tmp = {'prefix': prefix, 'mask': '64'} if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']): tmp['mask'] = conf.return_value( ['client-ipv6-pool', 'prefix', prefix, 'mask']) pppoe['client_ipv6_pool'].append(tmp) if conf.exists(['client-ipv6-pool', 'delegate']): for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']): tmp = {'prefix': prefix, 'mask': ''} if conf.exists( ['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']): tmp['mask'] = conf.return_value([ 'client-ipv6-pool', 'delegate', prefix, 'delegation-prefix' ]) pppoe['client_ipv6_delegate_prefix'].append(tmp) if conf.exists(['limits']): if conf.exists(['limits', 'burst']): pppoe['limits_burst'] = conf.return_value(['limits', 'burst']) if conf.exists(['limits', 'connection-limit']): pppoe['limits_connections'] = conf.return_value( ['limits', 'connection-limit']) if conf.exists(['limits', 'timeout']): pppoe['limits_timeout'] = conf.return_value(['limits', 'timeout']) if conf.exists(['snmp']): pppoe['snmp'] = True if conf.exists(['snmp', 'master-agent']): pppoe['snmp'] = 'enable-ma' # authentication mode local if conf.exists(['authentication', 'mode']): pppoe['auth_mode'] = conf.return_value(['authentication', 'mode']) if conf.exists(['authentication', 'local-users']): for username in conf.list_nodes( ['authentication', 'local-users', 'username']): user = { 'name': username, 'password': '', 'state': 'enabled', 'ip': '*', 'upload': None, 'download': None } conf.set_level( base_path + ['authentication', 'local-users', 'username', username]) if conf.exists(['password']): user['password'] = conf.return_value(['password']) if conf.exists(['disable']): user['state'] = 'disable' if conf.exists(['static-ip']): user['ip'] = conf.return_value(['static-ip']) if conf.exists(['rate-limit', 'download']): user['download'] = conf.return_value( ['rate-limit', 'download']) if conf.exists(['rate-limit', 'upload']): user['upload'] = conf.return_value(['rate-limit', 'upload']) pppoe['local_users'].append(user) conf.set_level(base_path) if conf.exists(['authentication', 'protocols']): auth_mods = { 'mschap-v2': 'auth_mschap_v2', 'mschap': 'auth_mschap_v1', 'chap': 'auth_chap_md5', 'pap': 'auth_pap' } pppoe['auth_proto'] = [] for proto in conf.return_values(['authentication', 'protocols']): pppoe['auth_proto'].append(auth_mods[proto]) # # authentication mode radius servers and settings if conf.exists(['authentication', 'mode', 'radius']): for server in conf.list_nodes(['authentication', 'radius', 'server']): radius = { 'server': server, 'key': '', 'fail_time': 0, 'port': '1812' } conf.set_level(base_path + ['authentication', 'radius', 'server', server]) if conf.exists(['fail-time']): radius['fail-time'] = conf.return_value(['fail-time']) if conf.exists(['port']): radius['port'] = conf.return_value(['port']) if conf.exists(['key']): radius['key'] = conf.return_value(['key']) if not conf.exists(['disable']): pppoe['radius_server'].append(radius) # # advanced radius-setting conf.set_level(base_path + ['authentication', 'radius']) if conf.exists(['acct-timeout']): pppoe['radius_acct_tmo'] = conf.return_value(['acct-timeout']) if conf.exists(['max-try']): pppoe['radius_max_try'] = conf.return_value(['max-try']) if conf.exists(['timeout']): pppoe['radius_timeout'] = conf.return_value(['timeout']) if conf.exists(['nas-identifier']): pppoe['radius_nas_id'] = conf.return_value(['nas-identifier']) if conf.exists(['nas-ip-address']): pppoe['radius_nas_ip'] = conf.return_value(['nas-ip-address']) if conf.exists(['source-address']): pppoe['radius_source_address'] = conf.return_value( ['source-address']) # Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA) if conf.exists(['dynamic-author']): dae = {'port': '', 'server': '', 'key': ''} if conf.exists(['dynamic-author', 'server']): dae['server'] = conf.return_value(['dynamic-author', 'server']) if conf.exists(['dynamic-author', 'port']): dae['port'] = conf.return_value(['dynamic-author', 'port']) if conf.exists(['dynamic-author', 'key']): dae['key'] = conf.return_value(['dynamic-author', 'key']) pppoe['radius_dynamic_author'] = dae # RADIUS based rate-limiter if conf.exists(['rate-limit', 'enable']): pppoe['radius_shaper_attr'] = 'Filter-Id' c_attr = ['rate-limit', 'enable', 'attribute'] if conf.exists(c_attr): pppoe['radius_shaper_attr'] = conf.return_value(c_attr) c_vendor = ['rate-limit', 'enable', 'vendor'] if conf.exists(c_vendor): pppoe['radius_shaper_vendor'] = conf.return_value(c_vendor) # re-set config level conf.set_level(base_path) if conf.exists(['mtu']): pppoe['mtu'] = conf.return_value(['mtu']) if conf.exists(['session-control']): pppoe['sesscrtl'] = conf.return_value(['session-control']) # ppp_options if conf.exists(['ppp-options']): conf.set_level(base_path + ['ppp-options']) if conf.exists(['ccp']): pppoe['ppp_ccp'] = True if conf.exists(['ipv4']): pppoe['ppp_ipv4'] = conf.return_value(['ipv4']) if conf.exists(['ipv6']): pppoe['ppp_ipv6'] = conf.return_value(['ipv6']) if conf.exists(['ipv6-accept-peer-intf-id']): pppoe['ppp_ipv6_peer_intf_id'] = True if conf.exists(['ipv6-intf-id']): pppoe['ppp_ipv6_intf_id'] = conf.return_value(['ipv6-intf-id']) if conf.exists(['ipv6-peer-intf-id']): pppoe['ppp_ipv6_peer_intf_id'] = conf.return_value( ['ipv6-peer-intf-id']) if conf.exists(['lcp-echo-failure']): pppoe['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure']) if conf.exists(['lcp-echo-failure']): pppoe['ppp_echo_interval'] = conf.return_value( ['lcp-echo-failure']) if conf.exists(['lcp-echo-timeout']): pppoe['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout']) if conf.exists(['min-mtu']): pppoe['ppp_min_mtu'] = conf.return_value(['min-mtu']) if conf.exists(['mppe']): pppoe['ppp_mppe'] = conf.return_value(['mppe']) if conf.exists(['mru']): pppoe['ppp_mru'] = conf.return_value(['mru']) if conf.exists(['pado-delay']): pppoe['pado_delay'] = '0' a = {} for id in conf.list_nodes(['pado-delay']): if not conf.return_value(['pado-delay', id, 'sessions']): a[id] = 0 else: a[id] = conf.return_value(['pado-delay', id, 'sessions']) for k in sorted(a.keys()): if k != sorted(a.keys())[-1]: pppoe['pado_delay'] += ",{0}:{1}".format(k, a[k]) else: pppoe['pado_delay'] += ",{0}:{1}".format('-1', a[k]) return pppoe
def get_config(): openvpn = deepcopy(default_config_data) conf = Config() # determine tagNode instance if 'VYOS_TAGNODE_VALUE' not in os.environ: raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified') openvpn['intf'] = os.environ['VYOS_TAGNODE_VALUE'] openvpn['auth_user_pass_file'] = f"/run/openvpn/{openvpn['intf']}.pw" # check if interface is member of a bridge openvpn['is_bridge_member'] = is_member(conf, openvpn['intf'], 'bridge') # Check if interface instance has been removed if not conf.exists('interfaces openvpn ' + openvpn['intf']): openvpn['deleted'] = True return openvpn # bridged server should not have a pool by default (but can be specified manually) if openvpn['is_bridge_member']: openvpn['server_pool'] = False openvpn['server_ipv6_pool'] = False # set configuration level conf.set_level('interfaces openvpn ' + openvpn['intf']) # retrieve authentication options - username if conf.exists('authentication username'): openvpn['auth_user'] = conf.return_value('authentication username') openvpn['auth'] = True # retrieve authentication options - username if conf.exists('authentication password'): openvpn['auth_pass'] = conf.return_value('authentication password') openvpn['auth'] = True # retrieve interface description if conf.exists('description'): openvpn['description'] = conf.return_value('description') # interface device-type if conf.exists('device-type'): openvpn['type'] = conf.return_value('device-type') # disable interface if conf.exists('disable'): openvpn['disable'] = True # data encryption algorithm cipher if conf.exists('encryption cipher'): openvpn['encryption'] = conf.return_value('encryption cipher') # disable ncp-ciphers support if conf.exists('encryption disable-ncp'): openvpn['disable_ncp'] = True # data encryption algorithm ncp-list if conf.exists('encryption ncp-ciphers'): _ncp_ciphers = [] for enc in conf.return_values('encryption ncp-ciphers'): if enc == 'des': _ncp_ciphers.append('des-cbc') _ncp_ciphers.append('DES-CBC') elif enc == '3des': _ncp_ciphers.append('des-ede3-cbc') _ncp_ciphers.append('DES-EDE3-CBC') elif enc == 'aes128': _ncp_ciphers.append('aes-128-cbc') _ncp_ciphers.append('AES-128-CBC') elif enc == 'aes128gcm': _ncp_ciphers.append('aes-128-gcm') _ncp_ciphers.append('AES-128-GCM') elif enc == 'aes192': _ncp_ciphers.append('aes-192-cbc') _ncp_ciphers.append('AES-192-CBC') elif enc == 'aes192gcm': _ncp_ciphers.append('aes-192-gcm') _ncp_ciphers.append('AES-192-GCM') elif enc == 'aes256': _ncp_ciphers.append('aes-256-cbc') _ncp_ciphers.append('AES-256-CBC') elif enc == 'aes256gcm': _ncp_ciphers.append('aes-256-gcm') _ncp_ciphers.append('AES-256-GCM') openvpn['ncp_ciphers'] = ':'.join(_ncp_ciphers) # hash algorithm if conf.exists('hash'): openvpn['hash'] = conf.return_value('hash') # Maximum number of keepalive packet failures if conf.exists('keep-alive failure-count') and conf.exists( 'keep-alive interval'): fail_count = conf.return_value('keep-alive failure-count') interval = conf.return_value('keep-alive interval') openvpn['ping_interval'] = interval openvpn['ping_restart'] = int(interval) * int(fail_count) # Local IP address of tunnel - even as it is a tag node - we can only work # on the first address if conf.exists('local-address'): for tmp in conf.list_nodes('local-address'): tmp_ip = ip_address(tmp) if tmp_ip.version == 4: openvpn['local_address'].append(tmp) if conf.exists('local-address {} subnet-mask'.format(tmp)): openvpn['local_address_subnet'] = conf.return_value( 'local-address {} subnet-mask'.format(tmp)) elif tmp_ip.version == 6: # input IPv6 address could be expanded so get the compressed version openvpn['ipv6_local_address'].append(str(tmp_ip)) # Local IP address to accept connections if conf.exists('local-host'): openvpn['local_host'] = conf.return_value('local-host') # Local port number to accept connections if conf.exists('local-port'): openvpn['local_port'] = conf.return_value('local-port') # Enable acquisition of IPv6 address using stateless autoconfig (SLAAC) if conf.exists('ipv6 address autoconf'): openvpn['ipv6_autoconf'] = 1 # Get prefixes for IPv6 addressing based on MAC address (EUI-64) if conf.exists('ipv6 address eui64'): openvpn['ipv6_eui64_prefix'] = conf.return_values('ipv6 address eui64') # Determine currently effective EUI64 addresses - to determine which # address is no longer valid and needs to be removed eff_addr = conf.return_effective_values('ipv6 address eui64') openvpn['ipv6_eui64_prefix_remove'] = list_diff( eff_addr, openvpn['ipv6_eui64_prefix']) # Remove the default link-local address if set. if conf.exists('ipv6 address no-default-link-local'): openvpn['ipv6_eui64_prefix_remove'].append('fe80::/64') else: # add the link-local by default to make IPv6 work openvpn['ipv6_eui64_prefix'].append('fe80::/64') # Disable IPv6 forwarding on this interface if conf.exists('ipv6 disable-forwarding'): openvpn['ipv6_forwarding'] = 0 # IPv6 Duplicate Address Detection (DAD) tries if conf.exists('ipv6 dup-addr-detect-transmits'): openvpn['ipv6_dup_addr_detect'] = int( conf.return_value('ipv6 dup-addr-detect-transmits')) # to make IPv6 SLAAC and DHCPv6 work with forwarding=1, # accept_ra must be 2 if openvpn['ipv6_autoconf'] or 'dhcpv6' in openvpn['address']: openvpn['ipv6_accept_ra'] = 2 # OpenVPN operation mode if conf.exists('mode'): openvpn['mode'] = conf.return_value('mode') # Additional OpenVPN options if conf.exists('openvpn-option'): openvpn['options'] = conf.return_values('openvpn-option') # Do not close and reopen interface if conf.exists('persistent-tunnel'): openvpn['persistent_tunnel'] = True # Communication protocol if conf.exists('protocol'): openvpn['protocol'] = conf.return_value('protocol') # IP address of remote end of tunnel if conf.exists('remote-address'): for tmp in conf.return_values('remote-address'): tmp_ip = ip_address(tmp) if tmp_ip.version == 4: openvpn['remote_address'].append(tmp) elif tmp_ip.version == 6: openvpn['ipv6_remote_address'].append(str(tmp_ip)) # Remote host to connect to (dynamic if not set) if conf.exists('remote-host'): openvpn['remote_host'] = conf.return_values('remote-host') # Remote port number to connect to if conf.exists('remote-port'): openvpn['remote_port'] = conf.return_value('remote-port') # OpenVPN tunnel to be used as the default route # see https://openvpn.net/community-resources/reference-manual-for-openvpn-2-4/ # redirect-gateway flags if conf.exists('replace-default-route'): openvpn['redirect_gateway'] = 'def1' if conf.exists('replace-default-route local'): openvpn['redirect_gateway'] = 'local def1' # Topology for clients if conf.exists('server topology'): openvpn['server_topology'] = conf.return_value('server topology') # Server-mode subnet (from which client IPs are allocated) server_network_v4 = None server_network_v6 = None if conf.exists('server subnet'): for tmp in conf.return_values('server subnet'): tmp_ip = ip_network(tmp) if tmp_ip.version == 4: server_network_v4 = tmp_ip # convert the network to format: "192.0.2.0 255.255.255.0" for later use in template openvpn['server_subnet'].append( tmp_ip.with_netmask.replace(r'/', ' ')) elif tmp_ip.version == 6: server_network_v6 = tmp_ip openvpn['server_ipv6_subnet'].append(str(tmp_ip)) # Client-specific settings for client in conf.list_nodes('server client'): # set configuration level conf.set_level('interfaces openvpn ' + openvpn['intf'] + ' server client ' + client) data = { 'name': client, 'disable': False, 'ip': [], 'ipv6_ip': [], 'ipv6_remote': '', 'ipv6_push_route': [], 'ipv6_subnet': [], 'push_route': [], 'subnet': [], 'remote_netmask': '' } # Option to disable client connection if conf.exists('disable'): data['disable'] = True # IP address of the client for tmp in conf.return_values('ip'): tmp_ip = ip_address(tmp) if tmp_ip.version == 4: data['ip'].append(tmp) elif tmp_ip.version == 6: data['ipv6_ip'].append(str(tmp_ip)) # Route to be pushed to the client for tmp in conf.return_values('push-route'): tmp_ip = ip_network(tmp) if tmp_ip.version == 4: data['push_route'].append( tmp_ip.with_netmask.replace(r'/', ' ')) elif tmp_ip.version == 6: data['ipv6_push_route'].append(str(tmp_ip)) # Subnet belonging to the client for tmp in conf.return_values('subnet'): tmp_ip = ip_network(tmp) if tmp_ip.version == 4: data['subnet'].append(tmp_ip.with_netmask.replace(r'/', ' ')) elif tmp_ip.version == 6: data['ipv6_subnet'].append(str(tmp_ip)) # Append to global client list openvpn['client'].append(data) # re-set configuration level conf.set_level('interfaces openvpn ' + openvpn['intf']) # Server client IP pool if conf.exists('server client-ip-pool'): conf.set_level('interfaces openvpn ' + openvpn['intf'] + ' server client-ip-pool') # enable or disable server_pool where necessary # default is enabled, or disabled in bridge mode openvpn['server_pool'] = not conf.exists('disable') if conf.exists('start'): openvpn['server_pool_start'] = conf.return_value('start') if conf.exists('stop'): openvpn['server_pool_stop'] = conf.return_value('stop') if conf.exists('netmask'): openvpn['server_pool_netmask'] = conf.return_value('netmask') conf.set_level('interfaces openvpn ' + openvpn['intf']) # Server client IPv6 pool if conf.exists('server client-ipv6-pool'): conf.set_level('interfaces openvpn ' + openvpn['intf'] + ' server client-ipv6-pool') openvpn['server_ipv6_pool'] = not conf.exists('disable') if conf.exists('base'): tmp = conf.return_value('base').split('/') openvpn['server_ipv6_pool_base'] = str(IPv6Address(tmp[0])) if 1 < len(tmp): openvpn['server_ipv6_pool_prefixlen'] = tmp[1] conf.set_level('interfaces openvpn ' + openvpn['intf']) # DNS suffix to be pushed to all clients if conf.exists('server domain-name'): openvpn['server_domain'] = conf.return_value('server domain-name') # Number of maximum client connections if conf.exists('server max-connections'): openvpn['server_max_conn'] = conf.return_value( 'server max-connections') # Domain Name Server (DNS) if conf.exists('server name-server'): for tmp in conf.return_values('server name-server'): tmp_ip = ip_address(tmp) if tmp_ip.version == 4: openvpn['server_dns_nameserver'].append(tmp) elif tmp_ip.version == 6: openvpn['server_ipv6_dns_nameserver'].append(str(tmp_ip)) # Route to be pushed to all clients if conf.exists('server push-route'): for tmp in conf.return_values('server push-route'): tmp_ip = ip_network(tmp) if tmp_ip.version == 4: openvpn['server_push_route'].append( tmp_ip.with_netmask.replace(r'/', ' ')) elif tmp_ip.version == 6: openvpn['server_ipv6_push_route'].append(str(tmp_ip)) # Reject connections from clients that are not explicitly configured if conf.exists('server reject-unconfigured-clients'): openvpn['server_reject_unconfigured'] = True # File containing TLS auth static key if conf.exists('tls auth-file'): openvpn['tls_auth'] = conf.return_value('tls auth-file') openvpn['tls'] = True # File containing certificate for Certificate Authority (CA) if conf.exists('tls ca-cert-file'): openvpn['tls_ca_cert'] = conf.return_value('tls ca-cert-file') openvpn['tls'] = True # File containing certificate for this host if conf.exists('tls cert-file'): openvpn['tls_cert'] = conf.return_value('tls cert-file') openvpn['tls'] = True # File containing certificate revocation list (CRL) for this host if conf.exists('tls crl-file'): openvpn['tls_crl'] = conf.return_value('tls crl-file') openvpn['tls'] = True # File containing Diffie Hellman parameters (server only) if conf.exists('tls dh-file'): openvpn['tls_dh'] = conf.return_value('tls dh-file') openvpn['tls'] = True # File containing this host's private key if conf.exists('tls key-file'): openvpn['tls_key'] = conf.return_value('tls key-file') openvpn['tls'] = True # File containing key to encrypt control channel packets if conf.exists('tls crypt-file'): openvpn['tls_crypt'] = conf.return_value('tls crypt-file') openvpn['tls'] = True # Role in TLS negotiation if conf.exists('tls role'): openvpn['tls_role'] = conf.return_value('tls role') openvpn['tls'] = True # Minimum required TLS version if conf.exists('tls tls-version-min'): openvpn['tls_version_min'] = conf.return_value('tls tls-version-min') openvpn['tls'] = True if conf.exists('shared-secret-key-file'): openvpn['shared_secret_file'] = conf.return_value( 'shared-secret-key-file') if conf.exists('use-lzo-compression'): openvpn['compress_lzo'] = True # Special case when using EC certificates: # if key-file is EC and dh-file is unset, set tls_dh to 'none' if not openvpn['tls_dh'] and openvpn['tls_key'] and checkCertHeader( '-----BEGIN EC PRIVATE KEY-----', openvpn['tls_key']): openvpn['tls_dh'] = 'none' # set default server topology to net30 if openvpn['mode'] == 'server' and not openvpn['server_topology']: openvpn['server_topology'] = 'net30' # Convert protocol to real protocol used by openvpn. # To make openvpn listen on both IPv4 and IPv6 we must use *6 protocols # (https://community.openvpn.net/openvpn/ticket/360), unless the local-host # or each of the remote-host in client mode is IPv4 # in which case it must use the standard protocols. if openvpn['protocol'] == 'tcp-active': openvpn['protocol_real'] = 'tcp6-client' elif openvpn['protocol'] == 'tcp-passive': openvpn['protocol_real'] = 'tcp6-server' else: openvpn['protocol_real'] = 'udp6' if (is_ipv4(openvpn['local_host']) or # in client mode test all the remotes instead (openvpn['mode'] == 'client' and all([is_ipv4(h) for h in openvpn['remote_host']]))): # takes out the '6' openvpn['protocol_real'] = openvpn['protocol_real'][:3] + openvpn[ 'protocol_real'][4:] # Set defaults where necessary. # If any of the input parameters are wrong, # this will return False and no defaults will be set. if server_network_v4 and openvpn['server_topology'] and openvpn['type']: default_server = None default_server = getDefaultServer(server_network_v4, openvpn['server_topology'], openvpn['type']) if default_server: # server-bridge doesn't require a pool so don't set defaults for it if openvpn['server_pool'] and not openvpn['is_bridge_member']: if not openvpn['server_pool_start']: openvpn['server_pool_start'] = default_server['pool_start'] if not openvpn['server_pool_stop']: openvpn['server_pool_stop'] = default_server['pool_stop'] if not openvpn['server_pool_netmask']: openvpn['server_pool_netmask'] = default_server[ 'pool_netmask'] for client in openvpn['client']: client['remote_netmask'] = default_server[ 'client_remote_netmask'] if server_network_v6: if not openvpn['server_ipv6_local']: openvpn['server_ipv6_local'] = server_network_v6[1] if not openvpn['server_ipv6_prefixlen']: openvpn['server_ipv6_prefixlen'] = server_network_v6.prefixlen if not openvpn['server_ipv6_remote']: openvpn['server_ipv6_remote'] = server_network_v6[2] if openvpn['server_ipv6_pool'] and server_network_v6.prefixlen < 112: if not openvpn['server_ipv6_pool_base']: openvpn['server_ipv6_pool_base'] = server_network_v6[0x1000] if not openvpn['server_ipv6_pool_prefixlen']: openvpn['server_ipv6_pool_prefixlen'] = openvpn[ 'server_ipv6_prefixlen'] for client in openvpn['client']: client['ipv6_remote'] = openvpn['server_ipv6_local'] if openvpn['redirect_gateway']: openvpn['redirect_gateway'] += ' ipv6' # retrieve VRF instance if conf.exists('vrf'): openvpn['vrf'] = conf.return_value('vrf') return openvpn