From 77c1b3457439889846380c5fd5da30cd11e253d9 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 16 Aug 2018 21:04:28 +0200 Subject: T778: T782: dhcp-server: XML and Python rewrite This commit changes in addtion the DHCP server config syntax as defined in "T782: Cleanup dhcp-server configuration". Replace boolean parameter from the folowing nodes and make it valueless. This requires a migration script which is tracked with this task * set service dhcp-server shared-network-name subnet 172.31.0.0/24 ip-forwarding enable (true|false) * set service dhcp-server shared-network-name authoritative (true|false) * set service dhcp-server disabled (true|false) * set service dhcp-server dynamic-dns-update enable (true|fals) * set service dhcp-server hostfile-update (enable|disable) Replace the nested start/stop ip address from "subnet 172.31.0.0/24 start 172.31.0.101 stop 172.31.0.149" to "subnet 172.31.0.0/24 range start" and "subnet 172.31.0.0/24 range stop" where foo can be any character or number. In addition the vyatta-cfg-dhcp-server package used it's own init/config file for service startup. This has been migrated to the vanilla Debian files. Copy 'on-dhcp-event.sh' from vyatta-cfg-shcp-server package commit 4749e648bca6. --- interface-definitions/dhcp-server.xml | 456 ++++++++++++++++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 interface-definitions/dhcp-server.xml (limited to 'interface-definitions') diff --git a/interface-definitions/dhcp-server.xml b/interface-definitions/dhcp-server.xml new file mode 100644 index 000000000..0fcb79454 --- /dev/null +++ b/interface-definitions/dhcp-server.xml @@ -0,0 +1,456 @@ + + + + + + + + Dynamic Host Configuration Protocol (DHCP) for DHCP server + 911 + + + + + Option to disable DHCP server + + + + + + DHCP server to dynamically update the Domain Name System (DNS) + + + + + + Additional global parameters for DHCP server. You must + use the syntax of dhcpd.conf in this text-field. Using this + without proper knowledge may result in a crashed DHCP server. + Check system log to look for errors. + + + + + + Enable DHCP server updating /etc/hosts (per client lease) + + + + + + DHCP shared network name [REQUIRED] + + ^[-_a-zA-Z0-9.]+$ + + Invalid DHCP pool name + + + + + Option to make DHCP server authoritative for this physical network + + + + + + Shared-network-name description + + + + + Option to disable DHCP configuration for shared-network + + + + + + Additional shared-network parameters for DHCP server. + You must use the syntax of dhcpd.conf in this text-field. + Using this without proper knowledge may result in a crashed + DHCP server. Check system log to look for errors. + + + + + + DHCP subnet for shared network + + ipv4net + IPv4 address and prefix length + + + + + + + + + Bootstrap file name + + + + + Server (IP address or domain name) from which the initial + boot file is to be loaded + + + + + Specifies the clients subnet mask as per RFC 950. If unset, subnet declaration is used. + + 0-32 + DHCP client prefix length must be 0 to 32 + + + + + DHCP client prefix length must be 0 to 32 + + + + + IP address of default router + + ipv4 + Default router IPv4 address + + + + + + + + + DNS server IPv4 address + + ipv4 + DNS server IPv4 address + + + + + + + + + + Client domain name + + + + + Client domain search + + + + + + IP address that needs to be excluded from DHCP lease range + + ipv4 + IPv4 address to exclude from lease range + + + + + + + + + + DHCP failover parameters + + + + + IP address for failover peer to connect [REQUIRED] + + ipv4 + IPv4 address to exclude from lease range + + + + + + + + + DHCP failover peer name [REQUIRED] + + ^[-_a-zA-Z0-9.]+$ + + Invalid failover peer name + + + + + IP address of failover peer [REQUIRED] + + ipv4 + IPv4 address to exclude from lease range + + + + + + + + + DHCP failover peer status (primary|secondary) [REQUIRED] + + primary secondary + + + (primary|secondary) + + Invalid DHCP failover peer status + + + + + + + Enable IP forwarding on client + + + + + + Lease timeout in seconds (default: 86400) + + 0-2592000 + DHCP lease time must be 0 to 2592000 (30 days) + + + + + DHCP lease time must be 0 to 2592000 + + + + + IP address of NTP server + + ipv4 + NTP server IPv4 address + + + + + + + + + + IP address of POP3 server + + ipv4 + POP3 server IPv4 address + + + + + + + + + + Address for DHCP server identifier + + ipv4 + DHCP server identifier IPv4 address + + + + + + + + + IP address of SMTP server + + ipv4 + SMTP server IPv4 address + + + + + + + + + + DHCP lease range + + ^[-_a-zA-Z0-9.]+$ + + Invalid DHCP lease range name + + + + + First IP address for DHCP lease range + + ipv4 + IPv4 start address of pool + + + + + + + + + Last IP address for DHCP lease range + + ipv4 + IPv4 end address of pool + + + + + + + + + + + Static mapping for specified address type + + ^[-_a-zA-Z0-9.]+$ + + Invalid static-mapping name + + + + + Option to disable static-mapping + + + + + + Static mapping for specified IP address [REQUIRED] + + ipv4 + IPv4 address used in static mapping + + + + + + + + + Static mapping for specified MAC address [REQUIRED] + + h:h:h:h:h:h + MAC address used in static mapping [REQUIRED] + + + + + + Additional static-mapping parameters for DHCP server. + You must use the syntax of dhcpd.conf in this text-field. + Using this without proper knowledge may result in a crashed + DHCP server. Check system log to look for errors. + + + + + + + + Classless static route + + + + + Destination subnet [REQUIRED] + + ipv4net + IPv4 address and prefix length + + + + + + + + + IP address of router to be used to reach the destination subnet [REQUIRED] + + ipv4 + IPv4 address of router + + + + + + + + + + + Additional subnet parameters for DHCP server. You must + use the syntax of dhcpd.conf in this text-field. Using this + without proper knowledge may result in a crashed DHCP server. + Check system log to look for errors. + + + + + + TFTP server name + + + + + Offset of the client's subnet in seconds from Coordinated Universal Time (UTC) + + ^-?[0-9]+$ + + Invalid time offset valuee + + + + + IP address of time server + + ipv4 + Time server IPv4 address + + + + + + + + + + IP address for Windows Internet Name Service (WINS) server + + ipv4 + WINS server IPv4 address + + + + + + + + + + Web Proxy Autodiscovery (WPAD) URL + + + + + + + + + + + -- cgit v1.2.3 From fd1eabe72862ec364643a61cb94b21c330a385f5 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 28 Aug 2018 21:58:46 +0200 Subject: T810: bugfix broadcast-relay address validator, add 'disable' functionality Whole broadcast relay service can be temporary disabled via set service broadcast-relay disable Individual instances of the broadcast relay service can be disabled set service broadcast-relay id disable --- interface-definitions/bcast-relay.xml | 20 +++- src/conf_mode/bcast_relay.py | 166 +++++++++++++++++++++++----------- 2 files changed, 129 insertions(+), 57 deletions(-) (limited to 'interface-definitions') diff --git a/interface-definitions/bcast-relay.xml b/interface-definitions/bcast-relay.xml index 0437192fa..fdba554db 100644 --- a/interface-definitions/bcast-relay.xml +++ b/interface-definitions/bcast-relay.xml @@ -3,12 +3,18 @@ - + - UDP Broadcast Relay parameters + UDP broadcast relay service - + + + Globally disable broadcast relay service + + + + Unique ID for each UDP port to forward @@ -21,6 +27,12 @@ + + + Disable broadcast relay service instance + + + Set source IP of forwarded packets, otherwise original senders address is used @@ -29,7 +41,7 @@ Optional source address for forwarded packets - + diff --git a/src/conf_mode/bcast_relay.py b/src/conf_mode/bcast_relay.py index 95f6215b5..8cc948610 100755 --- a/src/conf_mode/bcast_relay.py +++ b/src/conf_mode/bcast_relay.py @@ -20,55 +20,104 @@ import sys import os import fnmatch import subprocess +import jinja2 from vyos.config import Config from vyos import ConfigError config_file = r'/etc/default/udp-broadcast-relay' +config_tmpl = """ +### Autogenerated by bcast_relay.py ### + +# UDP broadcast relay configuration for instance {{ id }} +{%- if description %} +# Comment: {{ description }} +{% endif -%} +DAEMON_ARGS="{% if address %}-s {{ address }} {% endif %}{{ id }} {{ port }} {{ interfaces | join(' ') }}" +""" + +default_config_data = { + 'disabled': False, + 'instances': [] +} + def get_config(): + relay = default_config_data 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 = [] - intfs_names = conf.return_values("{0} interface".format(id)) - - for name in intfs_names: - interface_list.append(name) - - relay = { - "id": id, - "address": address, - "description": description, - "interfaces" : interface_list, - "port": port + if not conf.exists('service broadcast-relay'): + return None + else: + conf.set_level('service broadcast-relay') + + # 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('service broadcast-relay id {0}'.format(id)) + config = { + 'id': id, + 'disabled': False, + 'address': '', + 'description': '', + 'interfaces': [], + 'port': '' } - relays.append(relay) - return relays + # 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) -def verify(relays): - for relay in relays: - if not relay["port"]: - raise ConfigError("UDP broadcast relay 'id {0}' requires a port number".format(relay["id"])) + return relay - if len(relay["interfaces"]) < 2: - raise ConfigError("UDP broadcast relay 'id {0}' requires at least 2 interfaces".format(relay["id"])) +def verify(relay): + if relay is None: + return None + + if relay['disabled']: + return None + + for r in relay['instances']: + # we don't have to check this instance when it's disabled + if r['disabled']: + continue + + # we certainly require a UDP port to listen to + if not r['port']: + raise ConfigError('UDP broadcast relay "{0}" requires a port number'.format(r['id'])) + + # Relaying data without two interface is kinda senseless ... + if len(r['interfaces']) < 2: + raise ConfigError('UDP broadcast relay "id {0}" requires at least 2 interfaces'.format(r['id'])) return None -def generate(relays): - config_header = '### Autogenerated by bcast_relay.py ###\n' + +def generate(relay): + if relay is None: + return None config_dir = os.path.dirname(config_file) config_filename = os.path.basename(config_file) @@ -82,32 +131,43 @@ def generate(relays): # sort our list active_configs.sort() + # delete old configuration files for id in active_configs[:]: - os.unlink(config_file + id) - - for relay in relays: - file = config_file + str(relay["id"]) - interfaces = ' '.join(str(intf) for intf in relay["interfaces"]) - config_args = 'DAEMON_ARGS="{0} {1}"\n'.format(relay["port"], interfaces) - - f = open(file, 'w') - f.write(config_header) - if relay["description"]: - f.write('# ' + relay["description"] + '\n') - f.write(config_args) - f.close() + if os.path.exists(config_file + id): + os.unlink(config_file + id) + + # If the service is disabled, we can bail out here + if relay['disabled']: + print('Warning: UDP broadcast relay service will be deactivated because it is disabled') + return None + + for r in relay['instances']: + # Skip writing instance config when it's disabled + if r['disabled']: + continue + + # configuration filename contains instance id + file = config_file + str(r['id']) + tmpl = jinja2.Template(config_tmpl) + config_text = tmpl.render(r) + with open(file, 'w') as f: + f.write(config_text) return None -def apply(relays): +def apply(relay): # first stop all running services - cmd = "sudo systemctl stop udp-broadcast-relay@{1..99}" - os.system(cmd) + os.system('sudo systemctl stop udp-broadcast-relay@{1..99}') + + if (relay is None) or relay['disabled']: + return None # start only required service instances - for relay in relays: - cmd = "sudo systemctl start udp-broadcast-relay@{0}".format(relay["id"]) - os.system(cmd) + for r in relay['instances']: + # Don't start individual instance when it's disabled + if r['disabled']: + continue + os.system('sudo systemctl start udp-broadcast-relay@{0}'.format(r['id'])) return None -- cgit v1.2.3 From a0406e87389ad9ff9a045383d50d2bce49179382 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 28 Aug 2018 23:03:10 +0200 Subject: bcast-relay.xml: move priority from tagNode to base node --- interface-definitions/bcast-relay.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'interface-definitions') diff --git a/interface-definitions/bcast-relay.xml b/interface-definitions/bcast-relay.xml index fdba554db..96ce16639 100644 --- a/interface-definitions/bcast-relay.xml +++ b/interface-definitions/bcast-relay.xml @@ -6,6 +6,7 @@ UDP broadcast relay service + 990 @@ -21,7 +22,6 @@ 1-99 Numerical ID # - 990 -- cgit v1.2.3