diff options
-rw-r--r-- | data/templates/load-balancing/haproxy.cfg.j2 | 2 | ||||
-rw-r--r-- | interface-definitions/include/firewall/global-options.xml.i | 20 | ||||
-rw-r--r-- | interface-definitions/include/version/firewall-version.xml.i | 2 | ||||
-rw-r--r-- | interface-definitions/load-balancing_reverse-proxy.xml.in | 6 | ||||
-rw-r--r-- | interface-definitions/system_ip.xml.in | 6 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_firewall.py | 1 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_load-balancing_reverse-proxy.py | 18 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_system_ip.py | 11 | ||||
-rwxr-xr-x | src/conf_mode/firewall.py | 1 | ||||
-rwxr-xr-x | src/conf_mode/interfaces_openvpn.py | 6 | ||||
-rwxr-xr-x | src/conf_mode/load-balancing_reverse-proxy.py | 4 | ||||
-rwxr-xr-x | src/conf_mode/pki.py | 38 | ||||
-rwxr-xr-x | src/conf_mode/system_ip.py | 5 | ||||
-rwxr-xr-x | src/migration-scripts/firewall/14-to-15 | 46 |
14 files changed, 126 insertions, 40 deletions
diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 849cef74d..feb10d247 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -150,7 +150,7 @@ backend {{ back }} {% endfor %} {% endif %} {% if back_config.server is vyos_defined %} -{% set ssl_back = 'ssl ca-file /run/haproxy/' ~ back_config.ssl.ca_certificate ~ '.pem' if back_config.ssl.ca_certificate is vyos_defined else '' %} +{% set ssl_back = 'ssl ca-file /run/haproxy/' ~ back_config.ssl.ca_certificate ~ '.pem' if back_config.ssl.ca_certificate is vyos_defined else ('ssl verify none' if back_config.ssl.no_verify is vyos_defined else '') %} {% for server, server_config in back_config.server.items() %} server {{ server }} {{ server_config.address }}:{{ server_config.port }}{{ ' check' if server_config.check is vyos_defined }}{{ ' backup' if server_config.backup is vyos_defined }}{{ ' send-proxy' if server_config.send_proxy is vyos_defined }}{{ ' send-proxy-v2' if server_config.send_proxy_v2 is vyos_defined }} {{ ssl_back }} {% endfor %} diff --git a/interface-definitions/include/firewall/global-options.xml.i b/interface-definitions/include/firewall/global-options.xml.i index 415d85f05..9cd0b3239 100644 --- a/interface-definitions/include/firewall/global-options.xml.i +++ b/interface-definitions/include/firewall/global-options.xml.i @@ -44,6 +44,26 @@ </properties> <defaultValue>disable</defaultValue> </leafNode> + <leafNode name="directed-broadcast"> + <properties> + <help>Policy for handling IPv4 directed broadcast forwarding on all interfaces</help> + <completionHelp> + <list>enable disable</list> + </completionHelp> + <valueHelp> + <format>enable</format> + <description>Enable IPv4 directed broadcast forwarding on all interfaces</description> + </valueHelp> + <valueHelp> + <format>disable</format> + <description>Disable IPv4 directed broadcast forwarding on all interfaces</description> + </valueHelp> + <constraint> + <regex>(enable|disable)</regex> + </constraint> + </properties> + <defaultValue>enable</defaultValue> + </leafNode> <leafNode name="ip-src-route"> <properties> <help>Policy for handling IPv4 packets with source route option</help> diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i index 6702ee041..fa8e26f78 100644 --- a/interface-definitions/include/version/firewall-version.xml.i +++ b/interface-definitions/include/version/firewall-version.xml.i @@ -1,3 +1,3 @@ <!-- include start from include/version/firewall-version.xml.i --> -<syntaxVersion component='firewall' version='14'></syntaxVersion> +<syntaxVersion component='firewall' version='15'></syntaxVersion> <!-- include end --> diff --git a/interface-definitions/load-balancing_reverse-proxy.xml.in b/interface-definitions/load-balancing_reverse-proxy.xml.in index 2c2742dff..49d1d858e 100644 --- a/interface-definitions/load-balancing_reverse-proxy.xml.in +++ b/interface-definitions/load-balancing_reverse-proxy.xml.in @@ -157,6 +157,12 @@ </properties> <children> #include <include/pki/ca-certificate.xml.i> + <leafNode name="no-verify"> + <properties> + <help>Do not attempt to verify SSL certificates for backend servers</help> + <valueless/> + </properties> + </leafNode> </children> </node> #include <include/haproxy/timeout.xml.i> diff --git a/interface-definitions/system_ip.xml.in b/interface-definitions/system_ip.xml.in index 015eb270f..b4b5092fe 100644 --- a/interface-definitions/system_ip.xml.in +++ b/interface-definitions/system_ip.xml.in @@ -23,12 +23,6 @@ <valueless/> </properties> </leafNode> - <leafNode name="disable-directed-broadcast"> - <properties> - <help>Disable IPv4 directed broadcast forwarding on all interfaces</help> - <valueless/> - </properties> - </leafNode> <node name="multipath"> <properties> <help>IPv4 multipath settings</help> diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index fe6977252..c47562714 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -27,6 +27,7 @@ from vyos.utils.process import run sysfs_config = { 'all_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_all', 'default': '0', 'test_value': 'disable'}, 'broadcast_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts', 'default': '1', 'test_value': 'enable'}, + 'directed_broadcast': {'sysfs': '/proc/sys/net/ipv4/conf/all/bc_forwarding', 'default': '1', 'test_value': 'disable'}, 'ip_src_route': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_source_route', 'default': '0', 'test_value': 'enable'}, 'ipv6_receive_redirects': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_redirects', 'default': '0', 'test_value': 'enable'}, 'ipv6_src_route': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_source_route', 'default': '-1', 'test_value': 'enable'}, diff --git a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py index 97304da8b..d21fc762b 100755 --- a/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py +++ b/smoketest/scripts/cli/test_load-balancing_reverse-proxy.py @@ -280,6 +280,24 @@ class TestLoadBalancingReverseProxy(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'smoketest']) self.cli_commit() + def test_04_lb_reverse_proxy_backend_ssl_no_verify(self): + # Setup base + self.configure_pki() + self.base_config() + + # Set no-verify option + self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'no-verify']) + self.cli_commit() + + # Test no-verify option + config = read_file(HAPROXY_CONF) + self.assertIn('server bk-01 192.0.2.11:9090 send-proxy ssl verify none', config) + + # Test setting ca-certificate alongside no-verify option fails, to test config validation + self.cli_set(base_path + ['backend', 'bk-01', 'ssl', 'ca-certificate', 'smoketest']) + with self.assertRaises(ConfigSessionError) as e: + self.cli_commit() + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_system_ip.py b/smoketest/scripts/cli/test_system_ip.py index ac8b74236..5b0090237 100755 --- a/smoketest/scripts/cli/test_system_ip.py +++ b/smoketest/scripts/cli/test_system_ip.py @@ -38,17 +38,6 @@ class TestSystemIP(VyOSUnitTestSHIM.TestCase): self.assertEqual(read_file(all_forwarding), '0') - def test_system_ip_directed_broadcast_forwarding(self): - # Test if IPv4 directed broadcast forwarding can be disabled globally, - # default is '1' which means forwarding enabled - bc_forwarding = '/proc/sys/net/ipv4/conf/all/bc_forwarding' - self.assertEqual(read_file(bc_forwarding), '1') - - self.cli_set(base_path + ['disable-directed-broadcast']) - self.cli_commit() - - self.assertEqual(read_file(bc_forwarding), '0') - def test_system_ip_multipath(self): # Test IPv4 multipathing options, options default to off -> '0' use_neigh = '/proc/sys/net/ipv4/fib_multipath_use_neigh' diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 3cf618363..e96e57154 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -44,6 +44,7 @@ nftables_conf = '/run/nftables.conf' sysfs_config = { 'all_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_all', 'enable': '0', 'disable': '1'}, 'broadcast_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts', 'enable': '0', 'disable': '1'}, + 'directed_broadcast' : {'sysfs': '/proc/sys/net/ipv4/conf/all/bc_forwarding', 'enable': '1', 'disable': '0'}, 'ip_src_route': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_source_route'}, 'ipv6_receive_redirects': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_redirects'}, 'ipv6_src_route': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_source_route', 'enable': '0', 'disable': '-1'}, diff --git a/src/conf_mode/interfaces_openvpn.py b/src/conf_mode/interfaces_openvpn.py index 505ec55c6..0ecffd3be 100755 --- a/src/conf_mode/interfaces_openvpn.py +++ b/src/conf_mode/interfaces_openvpn.py @@ -198,6 +198,12 @@ def verify_pki(openvpn): raise ConfigError(f'Cannot use encrypted private key on openvpn interface {interface}') if 'dh_params' in tls: + if 'dh' not in pki: + raise ConfigError(f'pki dh is not configured') + proposed_dh = tls['dh_params'] + if proposed_dh not in pki['dh'].keys(): + raise ConfigError(f"pki dh '{proposed_dh}' is not configured") + pki_dh = pki['dh'][tls['dh_params']] dh_params = load_dh_parameters(pki_dh['parameters']) dh_numbers = dh_params.parameter_numbers() diff --git a/src/conf_mode/load-balancing_reverse-proxy.py b/src/conf_mode/load-balancing_reverse-proxy.py index 694a4e1ea..9f895c4e2 100755 --- a/src/conf_mode/load-balancing_reverse-proxy.py +++ b/src/conf_mode/load-balancing_reverse-proxy.py @@ -84,6 +84,10 @@ def verify(lb): if {'send_proxy', 'send_proxy_v2'} <= set(bk_server_conf): raise ConfigError(f'Cannot use both "send-proxy" and "send-proxy-v2" for server "{bk_server}"') + if 'ssl' in back_config: + if {'no_verify', 'ca_certificate'} <= set(back_config['ssl']): + raise ConfigError(f'backend {back} cannot have both ssl options no-verify and ca-certificate set!') + for front, front_config in lb['service'].items(): for cert in dict_search('ssl.certificate', front_config) or []: verify_pki_certificate(lb, cert) diff --git a/src/conf_mode/pki.py b/src/conf_mode/pki.py index 3ab6ac5c3..6228ff0d2 100755 --- a/src/conf_mode/pki.py +++ b/src/conf_mode/pki.py @@ -24,6 +24,7 @@ from vyos.config import config_dict_merge from vyos.configdep import set_dependents from vyos.configdep import call_dependents from vyos.configdict import node_changed +from vyos.configdiff import Diff from vyos.defaults import directories from vyos.pki import is_ca_certificate from vyos.pki import load_certificate @@ -136,32 +137,32 @@ def get_config(config=None): if len(argv) > 1 and argv[1] == 'certbot_renew': pki['certbot_renew'] = {} - tmp = node_changed(conf, base + ['ca'], recursive=True) + tmp = node_changed(conf, base + ['ca'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'ca' : tmp}) - tmp = node_changed(conf, base + ['certificate'], recursive=True) + tmp = node_changed(conf, base + ['certificate'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'certificate' : tmp}) - tmp = node_changed(conf, base + ['dh'], recursive=True) + tmp = node_changed(conf, base + ['dh'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'dh' : tmp}) - tmp = node_changed(conf, base + ['key-pair'], recursive=True) + tmp = node_changed(conf, base + ['key-pair'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'key_pair' : tmp}) - tmp = node_changed(conf, base + ['openssh'], recursive=True) + tmp = node_changed(conf, base + ['openssh'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'openssh' : tmp}) - tmp = node_changed(conf, base + ['openvpn', 'shared-secret'], recursive=True) + tmp = node_changed(conf, base + ['openvpn', 'shared-secret'], recursive=True, expand_nodes=Diff.DELETE | Diff.ADD) if tmp: if 'changed' not in pki: pki.update({'changed':{}}) pki['changed'].update({'openvpn' : tmp}) @@ -217,16 +218,21 @@ def get_config(config=None): if not search_dict: continue for found_name, found_path in dict_search_recursive(search_dict, key): - if found_name == item_name: - path = search['path'] - path_str = ' '.join(path + found_path) - print(f'PKI: Updating config: {path_str} {found_name}') - - if path[0] == 'interfaces': - ifname = found_path[0] - set_dependents(path[1], conf, ifname) - else: - set_dependents(path[1], conf) + if isinstance(found_name, list) and item_name not in found_name: + continue + + if isinstance(found_name, str) and found_name != item_name: + continue + + path = search['path'] + path_str = ' '.join(path + found_path) + print(f'PKI: Updating config: {path_str} {item_name}') + + if path[0] == 'interfaces': + ifname = found_path[0] + set_dependents(path[1], conf, ifname) + else: + set_dependents(path[1], conf) return pki diff --git a/src/conf_mode/system_ip.py b/src/conf_mode/system_ip.py index b945b51f2..2a0bda91a 100755 --- a/src/conf_mode/system_ip.py +++ b/src/conf_mode/system_ip.py @@ -81,11 +81,6 @@ def apply(opt): value = '0' if (tmp != None) else '1' write_file('/proc/sys/net/ipv4/conf/all/forwarding', value) - # enable/disable IPv4 directed broadcast forwarding - tmp = dict_search('disable_directed_broadcast', opt) - value = '0' if (tmp != None) else '1' - write_file('/proc/sys/net/ipv4/conf/all/bc_forwarding', value) - # configure multipath tmp = dict_search('multipath.ignore_unreachable_nexthops', opt) value = '1' if (tmp != None) else '0' diff --git a/src/migration-scripts/firewall/14-to-15 b/src/migration-scripts/firewall/14-to-15 new file mode 100755 index 000000000..735839365 --- /dev/null +++ b/src/migration-scripts/firewall/14-to-15 @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022-2024 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 <http://www.gnu.org/licenses/>. + +# T5535: Migrate <set system ip disable-directed-broadcast> to <set firewall global-options directed-broadcas [enable|disable] + +from sys import argv +from sys import exit + +from vyos.configtree import ConfigTree + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) + +base = ['firewall'] + +if config.exists(['system', 'ip', 'disable-directed-broadcast']): + config.set(['firewall', 'global-options', 'directed-broadcast'], value='disable') + config.delete(['system', 'ip', 'disable-directed-broadcast']) + +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)) + exit(1)
\ No newline at end of file |