From 5cfbc160631beb93b19ebb6abff48230544d1f38 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 17 Oct 2018 20:14:55 +0200 Subject: dns-forwarding: fix XML interface indenting --- interface-definitions/dns-forwarding.xml | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'interface-definitions') diff --git a/interface-definitions/dns-forwarding.xml b/interface-definitions/dns-forwarding.xml index 01e8ad7d3..e3d33e8cc 100644 --- a/interface-definitions/dns-forwarding.xml +++ b/interface-definitions/dns-forwarding.xml @@ -35,26 +35,26 @@ DNSSEC mode - - off - - - - process-no-validate - - - - process - - - - log-fail - - - - validate - - + + off + + + + process-no-validate + + + + process + + + + log-fail + + + + validate + + (off|process-no-validate|process|log-fail|validate) -- cgit v1.2.3 From 8cf83c6ca8cf9cfda0179765effc2696f99dbc94 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 17 Oct 2018 20:16:37 +0200 Subject: T913: DHCP relay service XML/Python rewrite for IPv4 --- interface-definitions/dhcp-relay.xml | 108 ++++++++++++++++++++++++ src/conf_mode/dhcp_relay.py | 158 +++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 interface-definitions/dhcp-relay.xml create mode 100755 src/conf_mode/dhcp_relay.py (limited to 'interface-definitions') diff --git a/interface-definitions/dhcp-relay.xml b/interface-definitions/dhcp-relay.xml new file mode 100644 index 000000000..c918d25a3 --- /dev/null +++ b/interface-definitions/dhcp-relay.xml @@ -0,0 +1,108 @@ + + + + + + + + Host Configuration Protocol (DHCP) relay agent + 910 + + + + + DHCP relay interface [REQUIRED] + + + + + + + + + Relay options + + + + + Policy to discard packets that have reached specified hop-count + + 1-255 + Hop count (default: 10) + + + + + hop-count must be a value between 1 and 255 + + + + + Maximum packet size to send to a DHCPv4/BOOTP server + + 64-1400 + Maximum packet size (default: 576) + + + + + max-size must be a value between 64 and 1400 + + + + + Port number to listen on + + 1-65535 + Port to listen on + + + + + port must be a value between 1 and 65535 + + + + + Policy to handle incoming DHCPv4 packets which already contain relay agent options (default: forward) + + append + append own relay options to packet + + + replace + replace existing agent option field + + + forward + forward packet unchanged + + + discard + discard packet (default action if giaddr not set in packet) + + + (append|replace|forward|discard) + + + + + + + + DHCP server address + + ipv4 + DHCP server IPv4 address + + + + + + + + + + + + diff --git a/src/conf_mode/dhcp_relay.py b/src/conf_mode/dhcp_relay.py new file mode 100755 index 000000000..f757491e0 --- /dev/null +++ b/src/conf_mode/dhcp_relay.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# + +import sys +import os +import jinja2 + +from vyos.config import Config +from vyos import ConfigError + +config_file = r'/etc/default/isc-dhcp-relay' + +# Please be careful if you edit the template. +config_tmpl = """ +### Autogenerated by dhcp_relay.py ### + +# Defaults for isc-dhcp-relay initscript +# sourced by /etc/init.d/isc-dhcp-relay + +# +# This is a POSIX shell fragment +# + +# What servers should the DHCP relay forward requests to? +SERVERS="{{ server | join(' ') }}" + +# On what interfaces should the DHCP relay (dhrelay) serve DHCP requests? +INTERFACES="{{ interface | join(' ') }}" + +# Additional options that are passed to the DHCP relay daemon? +OPTIONS="-4 -p {{ port }} {{ options | join(' ') }}" +""" + +default_config_data = { + 'interface': [], + 'server': [], + 'options': [], + 'port': '67', + 'hop_count': '10', + 'relay_agent_packets': 'forward' +} + +def get_config(): + relay = default_config_data + conf = Config() + if not conf.exists('service dhcp-relay'): + return None + else: + conf.set_level('service dhcp-relay') + + # Network interfaces to listen on + if conf.exists('interface'): + relay['interface'] = conf.return_values('interface') + + # Servers equal to the address of the DHCP server(s) + if conf.exists('server'): + relay['server'] = conf.return_values('server') + + conf.set_level('service dhcp-relay relay-options') + + if conf.exists('hop-count'): + count = '-c ' + conf.return_value('hop-count') + relay['options'].append(count) + + # Specify the maximum packet size to send to a DHCPv4/BOOTP server. + # This might be done to allow sufficient space for addition of relay agent + # options while still fitting into the Ethernet MTU size. + # + # Available in DHCPv4 mode only: + if conf.exists('max-size'): + size = '-A ' + conf.return_value('max-size') + relay['options'].append(size) + + # Listen and transmit on port . This is mostly useful for debugging + # purposes. Default is port 67 for DHCPv4/BOOTP, or port 547 for DHCPv6. + if conf.exists('port'): + relay['port'] = conf.return_value('port') + + # Control the handling of incoming DHCPv4 packets which already contain + # relay agent options. If such a packet does not have giaddr set in its + # header, the DHCP standard requires that the packet be discarded. However, + # if giaddr is set, the relay agent may handle the situation in four ways: + # It may append its own set of relay options to the packet, leaving the + # supplied option field intact; it may replace the existing agent option + # field; it may forward the packet unchanged; or, it may discard it. + # + # Available in DHCPv4 mode only: + if conf.exists('relay-agents-packets'): + pkt = '-m ' + conf.return_value('relay-agents-packets') + relay['options'].append(pkt) + + return relay + +def verify(relay): + # bail out early - looks like removal from running config + if relay is None: + return None + + if len(relay['interface']) < 2: + # We can only issue a warning otherwise old configurations might break + print('WARNING: At least two interfaces are required for DHCP relay\n' \ + 'to work\n') + + if 'lo' in relay['interface']: + raise ConfigError('DHCP relay does not support the loopback interface.') + + if len(relay['server']) == 0: + raise ConfigError('No DHCP relay server(s) configured.\n' \ + 'At least one DHCP relay server required.') + + return None + +def generate(relay): + # bail out early - looks like removal from running config + if relay is None: + return None + + tmpl = jinja2.Template(config_tmpl) + config_text = tmpl.render(relay) + with open(config_file, 'w') as f: + f.write(config_text) + + return None + +def apply(relay): + if relay is not None: + os.system('sudo systemctl restart isc-dhcp-relay.service') + else: + # DHCP relay support is removed in the commit + os.system('sudo systemctl stop isc-dhcp-relay.service') + os.unlink(config_file) + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + sys.exit(1) -- cgit v1.2.3 From ddab02cbd638f0fb5db3003284e360b5b1603007 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 17 Oct 2018 21:09:42 +0200 Subject: T913: DHCP relay service XML/Python rewrite for IPv6 --- interface-definitions/dhcpv6-relay.xml | 92 +++++++++++++++++++++++++ src/conf_mode/dhcpv6_relay.py | 121 +++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 interface-definitions/dhcpv6-relay.xml create mode 100755 src/conf_mode/dhcpv6_relay.py (limited to 'interface-definitions') diff --git a/interface-definitions/dhcpv6-relay.xml b/interface-definitions/dhcpv6-relay.xml new file mode 100644 index 000000000..d6e6daf51 --- /dev/null +++ b/interface-definitions/dhcpv6-relay.xml @@ -0,0 +1,92 @@ + + + + + + + + DHCPv6 Relay Agent parameters + 900 + + + + + Interface for DHCPv6 Relay Agent to listen for requests + + + + + + + + IPv6 address on listen-interface listen for requests on + + ipv6 + IPv6 address on listen interface + + + + + + + + + + + UDP port to listen for requests on + + 1-65535 + Port to listen on + + + + + port must be a value between 1 and 65535 + + + + + Maximum hop count for which requests will be processed + + 1-255 + Hop count (default: 10) + + + + + max-hop-count must be a value between 1 and 255 + + + + + Interface for DHCPv6 Relay Agent forward requests out + + + + + + + + IPv6 address to forward requests to + + ipv6 + IPv6 address of the DHCP server + + + + + + + + + + + Option to set DHCPv6 interface-ID option + + + + + + + + diff --git a/src/conf_mode/dhcpv6_relay.py b/src/conf_mode/dhcpv6_relay.py new file mode 100755 index 000000000..982320d18 --- /dev/null +++ b/src/conf_mode/dhcpv6_relay.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# + +import sys +import os +import jinja2 + +from vyos.config import Config +from vyos import ConfigError + +config_file = r'/etc/default/isc-dhcpv6-relay' + +# Please be careful if you edit the template. +config_tmpl = """ +### Autogenerated by dhcpv6_relay.py ### + +# Defaults for isc-dhcpv6-relay initscript sourced by /etc/init.d/isc-dhcpv6-relay + +OPTIONS="-6 -l {{ listen_addr | join('-l ') }} -p {{ port }} {{ options | join(' ') }} -u {{ upstream_addr | join('-u ') }}" +""" + +default_config_data = { + 'listen_addr': [], + 'upstream_addr': [], + 'port': '547', + 'options': [], +} + +def get_config(): + relay = 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: + 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: + addr = conf.return_value('upstream-interface {0} address'.format(intf)) + server = addr + '%' + intf + relay['upstream_addr'].append(server) + + # Listen and transmit on port . This is mostly useful for debugging + # purposes. Default is port 67 for DHCPv4/BOOTP, or port 547 for DHCPv6. + if conf.exists('listen-port'): + relay['port'] = conf.return_value('listen-port') + + # 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 verify(relay): + # bail out early - looks like removal from running config + if relay is None: + return None + + return None + +def generate(relay): + # bail out early - looks like removal from running config + if relay is None: + return None + + tmpl = jinja2.Template(config_tmpl) + config_text = tmpl.render(relay) + with open(config_file, 'w') as f: + f.write(config_text) + + return None + +def apply(relay): + if relay is not None: + os.system('sudo systemctl restart isc-dhcpv6-relay.service') + else: + # DHCPv6 relay support is removed in the commit + os.system('sudo systemctl stop isc-dhcpv6-relay.service') + os.unlink(config_file) + + return None + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + sys.exit(1) -- cgit v1.2.3 From 19b69daa7c374b7fe34d57c99a8a972e1a6972e0 Mon Sep 17 00:00:00 2001 From: hagbard Date: Wed, 17 Oct 2018 13:53:59 -0700 Subject: Fixing check for local IP, using validator --is-any-host. --- interface-definitions/wireguard.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'interface-definitions') diff --git a/interface-definitions/wireguard.xml b/interface-definitions/wireguard.xml index 51876d6d6..e6bf557cd 100644 --- a/interface-definitions/wireguard.xml +++ b/interface-definitions/wireguard.xml @@ -29,7 +29,7 @@ - + -- cgit v1.2.3 From 06d4635eba6a8d11d92d13c41f09d2ade254f770 Mon Sep 17 00:00:00 2001 From: UnicronNL Date: Fri, 19 Oct 2018 00:33:55 +0200 Subject: Add Client keepalive option for use with cloud-init Add option to specify multiple listening ports Clean up template generation layout --- debian/control | 4 ++- interface-definitions/ssh.xml | 9 +++++++ src/conf_mode/ssh.py | 57 +++++++++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 14 deletions(-) (limited to 'interface-definitions') diff --git a/debian/control b/debian/control index 4cd852687..c0ce26c86 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,9 @@ Build-Depends: debhelper (>= 9), quilt, python3-lxml, python3-nose, - python3-coverage + python3-coverage, + whois, + libvyosconfig0 Standards-Version: 3.9.6 Package: vyos-1x diff --git a/interface-definitions/ssh.xml b/interface-definitions/ssh.xml index 35fe79214..422e6d64d 100644 --- a/interface-definitions/ssh.xml +++ b/interface-definitions/ssh.xml @@ -167,11 +167,20 @@ 1-65535 Numeric IP port + + + + how often send keep alives in seconds + + + + + diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py index beca7bb9a..b681acea3 100755 --- a/src/conf_mode/ssh.py +++ b/src/conf_mode/ssh.py @@ -67,7 +67,13 @@ UseDNS {{ host_validation }} # Specifies the port number that sshd listens on. The default is 22. # Multiple options of this type are permitted. +{% if mport|length != 0 %} +{% for p in mport %} +Port {{ p }} +{% endfor %} +{% else %} Port {{ port }} +{% endif %} # Gives the verbosity level that is used when logging messages from sshd LogLevel {{ log_level }} @@ -78,64 +84,80 @@ PermitRootLogin {{ allow_root }} # Specifies whether password authentication is allowed PasswordAuthentication {{ password_authentication }} -{% if listen_on -%} +{% if listen_on %} # Specifies the local addresses sshd should listen on -{% for a in listen_on -%} +{% for a in listen_on %} ListenAddress {{ a }} -{% endfor -%} +{% endfor %} +{{ "\n" }} {% endif %} -{% if ciphers -%} +{%- if ciphers %} # Specifies the ciphers allowed. Multiple ciphers must be comma-separated. # # NOTE: As of now, there is no 'multi' node for 'ciphers', thus we have only one :/ Ciphers {{ ciphers | join(",") }} +{{ "\n" }} {% endif %} -{% if mac -%} +{%- if mac %} # Specifies the available MAC (message authentication code) algorithms. The MAC # algorithm is used for data integrity protection. Multiple algorithms must be # comma-separated. # # NOTE: As of now, there is no 'multi' node for 'mac', thus we have only one :/ MACs {{ mac | join(",") }} +{{ "\n" }} {% endif %} -{% if key_exchange -%} +{%- if key_exchange %} # Specifies the available KEX (Key Exchange) algorithms. Multiple algorithms must # be comma-separated. # # NOTE: As of now, there is no 'multi' node for 'key-exchange', thus we have only one :/ KexAlgorithms {{ key_exchange | join(",") }} +{{ "\n" }} {% endif %} -{% if allow_users -%} +{%- if allow_users %} # This keyword can be followed by a list of user name patterns, separated by spaces. # If specified, login is allowed only for user names that match one of the patterns. # Only user names are valid, a numerical user ID is not recognized. AllowUsers {{ allow_users | join(" ") }} +{{ "\n" }} {% endif %} -{% if allow_groups -%} +{%- if allow_groups %} # This keyword can be followed by a list of group name patterns, separated by spaces. # If specified, login is allowed only for users whose primary group or supplementary # group list matches one of the patterns. Only group names are valid, a numerical group # ID is not recognized. AllowGroups {{ allow_groups | join(" ") }} +{{ "\n" }} {% endif %} -{% if deny_users -%} +{%- if deny_users %} # This keyword can be followed by a list of user name patterns, separated by spaces. # Login is disallowed for user names that match one of the patterns. Only user names # are valid, a numerical user ID is not recognized. DenyUsers {{ deny_users | join(" ") }} +{{ "\n" }} {% endif %} -{% if deny_groups -%} +{%- if deny_groups %} # This keyword can be followed by a list of group name patterns, separated by spaces. # Login is disallowed for users whose primary group or supplementary group list matches # one of the patterns. Only group names are valid, a numerical group ID is not recognized. DenyGroups {{ deny_groups | join(" ") }} +{{ "\n" }} +{% endif %} + +{%- if client_keepalive %} +# Sets a timeout interval in seconds after which if no data has been received from the client, +# sshd will send a message through the encrypted channel to request a response from the client. +# The default is 0, indicating that these messages will not be sent to the client. +# This option applies to protocol version 2 only. +ClientAliveInterval {{ client_keepalive }} {% endif %} """ @@ -208,8 +230,17 @@ def get_config(): ssh['mac'] = mac if conf.exists('port'): - port = conf.return_value('port') - ssh['port'] = port + ports = conf.return_values('port') + mport = [] + + for prt in ports: + mport.append(prt) + + ssh['mport'] = mport + + if conf.exists('client-keepalive-interval'): + client_keepalive = conf.return_value('client-keepalive-interval') + ssh['client_keepalive'] = client_keepalive return ssh @@ -228,7 +259,7 @@ def generate(ssh): if ssh is None: return None - tmpl = jinja2.Template(config_tmpl) + tmpl = jinja2.Template(config_tmpl, trim_blocks=True) config_text = tmpl.render(ssh) with open(config_file, 'w') as f: f.write(config_text) -- cgit v1.2.3 From 9cf0514668b1461d3b74076b99c9edabafa10418 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 21 Oct 2018 20:03:13 +0200 Subject: T634: remove 'service ssh allow-root' --- interface-definitions/ssh.xml | 6 ------ src/conf_mode/ssh.py | 6 +----- src/migration-scripts/ssh/0-to-1 | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) create mode 100755 src/migration-scripts/ssh/0-to-1 (limited to 'interface-definitions') diff --git a/interface-definitions/ssh.xml b/interface-definitions/ssh.xml index 422e6d64d..c0ce976d6 100644 --- a/interface-definitions/ssh.xml +++ b/interface-definitions/ssh.xml @@ -72,12 +72,6 @@ - - - Allow the root user to login - - - Allowed ciphers diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py index b681acea3..2a5cba99a 100755 --- a/src/conf_mode/ssh.py +++ b/src/conf_mode/ssh.py @@ -79,7 +79,7 @@ Port {{ port }} LogLevel {{ log_level }} # Specifies whether root can log in using ssh -PermitRootLogin {{ allow_root }} +PermitRootLogin no # Specifies whether password authentication is allowed PasswordAuthentication {{ password_authentication }} @@ -164,7 +164,6 @@ ClientAliveInterval {{ client_keepalive }} default_config_data = { 'port' : '22', 'log_level': 'INFO', - 'allow_root': 'no', 'password_authentication': 'yes', 'host_validation': 'yes' } @@ -193,9 +192,6 @@ def get_config(): deny_groups = conf.return_values('access-control deny group') ssh['deny_groups'] = deny_groups - if conf.exists('allow-root'): - ssh['allow-root'] = 'yes' - if conf.exists('ciphers'): ciphers = conf.return_values('ciphers') ssh['ciphers'] = ciphers diff --git a/src/migration-scripts/ssh/0-to-1 b/src/migration-scripts/ssh/0-to-1 new file mode 100755 index 000000000..91b832276 --- /dev/null +++ b/src/migration-scripts/ssh/0-to-1 @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +# Delete "service ssh allow-root" option + +import sys + +from vyos.configtree import ConfigTree + +if (len(sys.argv) < 1): + print("Must specify file name!") + sys.exit(1) + +file_name = sys.argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) + +if not config.exists(['service', 'ssh', 'allow-root']): + # Nothing to do + sys.exit(0) +else: + # Delete node with abandoned command + config.delete(['service', 'ssh', 'allow-root']) + + try: + with open(file_name, 'w') as f: + f.write(config.to_string()) + except OSError as e: + print("Failed to save the modified config: {}".format(e)) + sys.exit(1) -- cgit v1.2.3 From ca551e0bd657afce7f366d245cbbeeb5449bc906 Mon Sep 17 00:00:00 2001 From: hagbard Date: Fri, 26 Oct 2018 15:33:54 -0700 Subject: T886: validation logic in `interfaces wireguard wgX address x.x.x.x broken - removed ip-host from tree, iproute2 will detect faulty addresses and return exit 1 --- interface-definitions/wireguard.xml | 3 --- 1 file changed, 3 deletions(-) (limited to 'interface-definitions') diff --git a/interface-definitions/wireguard.xml b/interface-definitions/wireguard.xml index e6bf557cd..575637ac9 100644 --- a/interface-definitions/wireguard.xml +++ b/interface-definitions/wireguard.xml @@ -28,9 +28,6 @@ IPv6 address and prefix length - - - -- cgit v1.2.3