From f8c01ef3cf31e9d0fe57a51e32a7352079d0d7e7 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Fri, 4 Dec 2020 13:48:43 +0100 Subject: vyos.ifconfig: T1579: migrate "ip source-validation" option from vyatta-cfg-quagga --- Makefile | 47 ++++--------------- .../include/interface-ipv4-options.xml.i | 1 + .../include/interface-source-validation.xml.i | 25 ++++++++++ interface-definitions/interfaces-dummy.xml.in | 8 ++++ interface-definitions/interfaces-loopback.xml.in | 8 ++++ interface-definitions/interfaces-openvpn.xml.in | 8 +--- interface-definitions/interfaces-pppoe.xml.in | 8 ++++ python/vyos/ifconfig/interface.py | 54 ++++++++++++++++++---- 8 files changed, 105 insertions(+), 54 deletions(-) create mode 100644 interface-definitions/include/interface-source-validation.xml.i diff --git a/Makefile b/Makefile index cd66809e3..256a600f6 100644 --- a/Makefile +++ b/Makefile @@ -38,45 +38,6 @@ interface_definitions: $(BUILD_DIR) $(obj) # XXX: delete top level node.def's that now live in other packages rm -f $(TMPL_DIR)/firewall/node.def rm -f $(TMPL_DIR)/interfaces/node.def - rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/vif/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/vif/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/vif-s/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/bonding/node.tag/vif-s/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/bridge/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/bridge/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif-s/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif-s/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif-s/node.tag/vif-c/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/ethernet/node.tag/vif-s/node.tag/vif-c/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/l2tpv3/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/l2tpv3/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/openvpn/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/pppoe/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/pppoe/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/vif/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/vif/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/vif-s/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/vif-s/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/vif-s/node.tag/vif-c/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/pseudo-ethernet/node.tag/vif-s/node.tag/vif-c/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/tunnel/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/tunnel/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/vxlan/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/vxlan/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/wireless/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/wireless/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/wireless/node.tag/vif/node.tag/ip/node.def - rm -f $(TMPL_DIR)/interfaces/wireless/node.tag/vif/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/wirelessmodem/node.tag/ipv6/node.def - rm -f $(TMPL_DIR)/interfaces/wireguard/node.tag/ipv6/node.def rm -f $(TMPL_DIR)/protocols/node.def rm -rf $(TMPL_DIR)/protocols/nbgp rm -f $(TMPL_DIR)/protocols/static/node.def @@ -86,6 +47,14 @@ interface_definitions: $(BUILD_DIR) $(obj) rm -f $(TMPL_DIR)/vpn/ipsec/node.def rm -rf $(TMPL_DIR)/vpn/nipsec + # Requires until OSPF and RIP is migrated from vyatta-cfg-quagga to vyos-1x + mkdir $(TMPL_DIR)/interfaces/loopback/node.tag/ipv6 + mkdir $(TMPL_DIR)/interfaces/dummy/node.tag/ipv6 + mkdir $(TMPL_DIR)/interfaces/openvpn/node.tag/ip + cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ipv6/node.def $(TMPL_DIR)/interfaces/loopback/node.tag/ipv6 + cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ipv6/node.def $(TMPL_DIR)/interfaces/dummy/node.tag/ipv6 + cp $(TMPL_DIR)/interfaces/ethernet/node.tag/ip/node.def $(TMPL_DIR)/interfaces/openvpn/node.tag/ip + .PHONY: op_mode_definitions .ONESHELL: op_mode_definitions: diff --git a/interface-definitions/include/interface-ipv4-options.xml.i b/interface-definitions/include/interface-ipv4-options.xml.i index 416e1adf5..c63f89890 100644 --- a/interface-definitions/include/interface-ipv4-options.xml.i +++ b/interface-definitions/include/interface-ipv4-options.xml.i @@ -12,6 +12,7 @@ #include #include #include + #include diff --git a/interface-definitions/include/interface-source-validation.xml.i b/interface-definitions/include/interface-source-validation.xml.i new file mode 100644 index 000000000..32cec464e --- /dev/null +++ b/interface-definitions/include/interface-source-validation.xml.i @@ -0,0 +1,25 @@ + + + + Source validation by reversed path (RFC3704) + + strict loose disable + + + strict + Enable Strict Reverse Path Forwarding as defined in RFC3704 + + + loose + Enable Loose Reverse Path Forwarding as defined in RFC3704 + + + disable + No source validation + + + ^(strict|loose|disable)$ + + + + diff --git a/interface-definitions/interfaces-dummy.xml.in b/interface-definitions/interfaces-dummy.xml.in index 135adfc10..54de43c7a 100644 --- a/interface-definitions/interfaces-dummy.xml.in +++ b/interface-definitions/interfaces-dummy.xml.in @@ -19,6 +19,14 @@ #include #include #include + + + IPv4 routing parameters + + + #include + + #include diff --git a/interface-definitions/interfaces-loopback.xml.in b/interface-definitions/interfaces-loopback.xml.in index 97d5bab90..0fd74f302 100644 --- a/interface-definitions/interfaces-loopback.xml.in +++ b/interface-definitions/interfaces-loopback.xml.in @@ -18,6 +18,14 @@ #include #include + + + IPv4 routing parameters + + + #include + + diff --git a/interface-definitions/interfaces-openvpn.xml.in b/interface-definitions/interfaces-openvpn.xml.in index 56a35e537..4c572a8b2 100644 --- a/interface-definitions/interfaces-openvpn.xml.in +++ b/interface-definitions/interfaces-openvpn.xml.in @@ -171,13 +171,7 @@ - - - #include - #include - #include - - + #include Hashing Algorithm diff --git a/interface-definitions/interfaces-pppoe.xml.in b/interface-definitions/interfaces-pppoe.xml.in index b6208e0b9..acb26b18b 100644 --- a/interface-definitions/interfaces-pppoe.xml.in +++ b/interface-definitions/interfaces-pppoe.xml.in @@ -81,6 +81,14 @@ + + + IPv4 routing parameters + + + #include + + diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 9f067b75e..6837e2d6a 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -36,6 +36,7 @@ from vyos.template import render from vyos.util import mac2eui64 from vyos.util import dict_search from vyos.util import cmd +from vyos.util import read_file from vyos.template import is_ipv4 from vyos.template import is_ipv6 from vyos.validate import is_intf_addr_assigned @@ -152,6 +153,10 @@ class Interface(Control): 'validate': assert_boolean, 'location': '/proc/sys/net/ipv4/conf/{ifname}/forwarding', }, + 'rp_filter': { + 'validate': lambda flt: assert_range(flt,0,3), + 'location': '/proc/sys/net/ipv4/conf/{ifname}/rp_filter', + }, 'ipv6_accept_ra': { 'validate': lambda ara: assert_range(ara,0,3), 'location': '/proc/sys/net/ipv6/conf/{ifname}/accept_ra', @@ -484,6 +489,34 @@ class Interface(Control): """ return self.set_interface('ipv4_forwarding', forwarding) + def set_ipv4_source_validation(self, value): + """ + Help prevent attacks used by Spoofing IP Addresses. Reverse path + filtering is a Kernel feature that, when enabled, is designed to ensure + packets that are not routable to be dropped. The easiest example of this + would be and IP Address of the range 10.0.0.0/8, a private IP Address, + being received on the Internet facing interface of the router. + + As per RFC3074. + """ + if value == 'strict': + value = 1 + elif value == 'loose': + value = 2 + else: + value = 0 + + all_rp_filter = int(read_file('/proc/sys/net/ipv4/conf/all/rp_filter')) + if all_rp_filter > value: + global_setting = 'disable' + if all_rp_filter == 1: global_setting = 'strict' + elif all_rp_filter == 2: global_setting = 'loose' + + print(f'WARNING: Global source-validation is set to "{global_setting}\n"' \ + 'this overrides per interface setting!') + + return self.set_interface('rp_filter', value) + def set_ipv6_accept_ra(self, accept_ra): """ Accept Router Advertisements; autoconfigure using them. @@ -930,13 +963,13 @@ class Interface(Control): if os.path.isfile(config_file): os.remove(config_file) - + def get_tc_config(self,objectname): # Parse configuration get_tc_cmd = f'tc -j {objectname}' tmp = cmd(get_tc_cmd, shell=True) return json.loads(tmp) - + def del_tc_qdisc(self,dev,kind,handle): tc_qdisc = self.get_tc_config('qdisc') for rule in tc_qdisc: @@ -946,15 +979,15 @@ class Interface(Control): if old_dev == dev and old_handle == handle and old_kind == kind: delete_tc_cmd = f'tc qdisc del dev {dev} handle {handle} {kind}' self._cmd(delete_tc_cmd) - - + + def apply_mirror(self,config): ifname = config['ifname'] - + # Remove existing mirroring rules self.del_tc_qdisc(ifname,'ingress','ffff:') - + # Setting up packet mirroring mirror = dict_search('mirror', config) if mirror: @@ -1068,6 +1101,11 @@ class Interface(Control): value = '0' if (tmp != None) else '1' self.set_ipv4_forwarding(value) + # IPv4 source-validation + tmp = dict_search('ip.source_validation', config) + value = tmp if (tmp != None) else '0' + self.set_ipv4_source_validation(value) + # IPv6 forwarding tmp = dict_search('ipv6.disable_forwarding', config) value = '0' if (tmp != None) else '1' @@ -1169,9 +1207,9 @@ class Interface(Control): vif_config['ifname'] = vif_ifname vlan = VLANIf(vif_ifname, **tmp) vlan.update(vif_config) - + self.apply_mirror(config) - + class VLANIf(Interface): -- cgit v1.2.3