From 1c2209c1dc84993d0f766f3d14df1fb3adf9dda2 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Tue, 23 May 2023 14:48:15 -0300 Subject: T5160: firewall refactor: new cli structure. Update only all xml --- interface-definitions/firewall.xml.in | 704 +-------------------- .../include/firewall/action-and-notrack.xml.i | 41 ++ .../include/firewall/common-rule-ipv4-raw.xml.i | 331 ++++++++++ .../include/firewall/common-rule-ipv4.xml.i | 416 ++++++++++++ .../include/firewall/common-rule-ipv6.xml.i | 416 ++++++++++++ .../firewall/default-action-base-chains.xml.i | 22 + .../include/firewall/global-options.xml.i | 272 ++++++++ .../include/firewall/inbound-interface.xml.i | 10 + .../include/firewall/ipv4-custom-name.xml.i | 49 ++ .../include/firewall/ipv4-hook-forward.xml.i | 44 ++ .../include/firewall/ipv4-hook-input.xml.i | 43 ++ .../include/firewall/ipv4-hook-output.xml.i | 43 ++ .../include/firewall/ipv4-hook-prerouting.xml.i | 85 +++ .../include/firewall/ipv6-custom-name.xml.i | 49 ++ .../include/firewall/ipv6-hook-forward.xml.i | 44 ++ .../include/firewall/ipv6-hook-input.xml.i | 43 ++ .../include/firewall/ipv6-hook-output.xml.i | 43 ++ .../include/firewall/match-interface.xml.i | 7 + .../include/firewall/outbound-interface.xml.i | 10 + .../include/version/firewall-version.xml.i | 2 +- 20 files changed, 1983 insertions(+), 691 deletions(-) create mode 100644 interface-definitions/include/firewall/action-and-notrack.xml.i create mode 100644 interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i create mode 100644 interface-definitions/include/firewall/common-rule-ipv4.xml.i create mode 100644 interface-definitions/include/firewall/common-rule-ipv6.xml.i create mode 100644 interface-definitions/include/firewall/default-action-base-chains.xml.i create mode 100644 interface-definitions/include/firewall/global-options.xml.i create mode 100644 interface-definitions/include/firewall/inbound-interface.xml.i create mode 100644 interface-definitions/include/firewall/ipv4-custom-name.xml.i create mode 100644 interface-definitions/include/firewall/ipv4-hook-forward.xml.i create mode 100644 interface-definitions/include/firewall/ipv4-hook-input.xml.i create mode 100644 interface-definitions/include/firewall/ipv4-hook-output.xml.i create mode 100644 interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i create mode 100644 interface-definitions/include/firewall/ipv6-custom-name.xml.i create mode 100644 interface-definitions/include/firewall/ipv6-hook-forward.xml.i create mode 100644 interface-definitions/include/firewall/ipv6-hook-input.xml.i create mode 100644 interface-definitions/include/firewall/ipv6-hook-output.xml.i create mode 100644 interface-definitions/include/firewall/outbound-interface.xml.i diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 1cdc7b819..9b36f92e8 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -6,66 +6,7 @@ Firewall - - - Policy for handling of all IPv4 ICMP echo requests - - enable disable - - - enable - Enable processing of all IPv4 ICMP echo requests - - - disable - Disable processing of all IPv4 ICMP echo requests - - - (enable|disable) - - - enable - - - - Policy for handling broadcast IPv4 ICMP echo and timestamp requests - - enable disable - - - enable - Enable processing of broadcast IPv4 ICMP echo/timestamp requests - - - disable - Disable processing of broadcast IPv4 ICMP echo/timestamp requests - - - (enable|disable) - - - disable - - - - SNMP trap generation on firewall configuration changes - - enable disable - - - enable - Enable sending SNMP trap on firewall configuration change - - - disable - Disable sending SNMP trap on firewall configuration change - - - (enable|disable) - - - disable - + #include Firewall group @@ -343,645 +284,28 @@ - + - Interface name to apply firewall configuration - - - - - #include - + IPv4 firewall - - - Forwarded packets on inbound interface - - - #include - - - - - Forwarded packets on outbound interface - - - #include - - - - - Packets destined for this router - - - #include - - - - - - - Policy for handling IPv4 packets with source route option - - enable disable - - - enable - Enable processing of IPv4 packets with source route option - - - disable - Disable processing of IPv4 packets with source route option - - - (enable|disable) - - - disable - - - - IPv6 firewall rule-set name - - [a-zA-Z0-9][\w\-\.]* - - - - #include - #include - #include - - - Set jump target. Action jump must be defined in default-action to use this setting - - firewall ipv6-name - - - - - - Firewall rule number (IPv6) - - u32:1-999999 - Number for this Firewall rule - - - - - Firewall rule number must be between 1 and 999999 - - - #include - #include - - - Destination parameters - - - #include - #include - #include - #include - #include - #include - - - - - Source parameters - - - #include - #include - #include - #include - #include - #include - - - #include - #include - #include - #include - #include - - - ICMPv6 type and code information - - - - - ICMPv6 code - - u32:0-255 - ICMPv6 code (0-255) - - - - - - - - - ICMPv6 type - - u32:0-255 - ICMPv6 type (0-255) - - - - - - - #include - - - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv6-name - - - - #include - - - - - - - Policy for handling received ICMPv6 redirect messages - - enable disable - - - enable - Enable processing of received ICMPv6 redirect messages - - - disable - Disable processing of received ICMPv6 redirect messages - - - (enable|disable) - - - disable - - - - Policy for handling IPv6 packets with routing extension header - - enable disable - - - enable - Enable processing of IPv6 packets with routing header type 2 - - - disable - Disable processing of IPv6 packets with routing header - - - (enable|disable) - - - disable - - - - Policy for logging IPv4 packets with invalid addresses - - enable disable - - - enable - Enable logging of IPv4 packets with invalid addresses - - - disable - Disable logging of Ipv4 packets with invalid addresses - - - (enable|disable) - - - enable - - - - IPv4 firewall rule-set name - - [a-zA-Z0-9][\w\-\.]* - - - - #include - #include - #include - - - Set jump target. Action jump must be defined in default-action to use this setting - - firewall name - - - - - - Firewall rule number (IPv4) - - u32:1-999999 - Number for this Firewall rule - - - - - Firewall rule number must be between 1 and 999999 - - - #include - #include - - - Destination parameters - - - #include - #include - #include - #include - #include - #include - - - - - Source parameters - - - #include - #include - #include - #include - #include - #include - - - #include - #include - #include - #include - - - ICMP type and code information - - - - - ICMP code - - u32:0-255 - ICMP code (0-255) - - - - - - - - - ICMP type - - u32:0-255 - ICMP type (0-255) - - - - - - - #include - - - - - Set jump target. Action jump must be defined to use this setting - - firewall name - - - - #include - #include - - - - - - - Policy for handling received IPv4 ICMP redirect messages - - enable disable - - - enable - Enable processing of received IPv4 ICMP redirect messages - - - disable - Disable processing of received IPv4 ICMP redirect messages - - - (enable|disable) - - - disable - - - - Retains last successful value if domain resolution fails - - - - - - Domain resolver update interval - - u32:10-3600 - Interval (seconds) - - - - - - 300 - - - - Policy for sending IPv4 ICMP redirect messages - - enable disable - - - enable - Enable sending IPv4 ICMP redirect messages - - - disable - Disable sending IPv4 ICMP redirect messages - - - (enable|disable) - - - enable - - - - Policy for source validation by reversed path, as specified in 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) - - - disable - - - - Global firewall state-policy - - - - - Global firewall policy for packets part of an established connection - - - #include - #include - #include - - - - - Global firewall policy for packets part of an invalid connection - - - #include - #include - #include - - - - - Global firewall policy for packets part of a related connection - - - #include - #include - #include - - + #include + #include + #include + #include - - - Policy for using TCP SYN cookies with IPv4 - - enable disable - - - enable - Enable use of TCP SYN cookies with IPv4 - - - disable - Disable use of TCP SYN cookies with IPv4 - - - (enable|disable) - - - enable - - + - RFC1337 TCP TIME-WAIT assasination hazards protection - - enable disable - - - enable - Enable RFC1337 TIME-WAIT hazards protection - - - disable - Disable RFC1337 TIME-WAIT hazards protection - - - (enable|disable) - - - disable - - - - Zone-policy - - txt - Zone name - - - [a-zA-Z0-9][\w\-\.]* - + IPv6 firewall - #include - #include - - - Default-action for traffic coming into this zone - - drop reject - - - drop - Drop silently - - - reject - Drop and notify source - - - (drop|reject) - - - drop - - - - Zone from which to filter traffic - - zone-policy zone - - - - - - Firewall options - - - - - IPv6 firewall ruleset - - firewall ipv6-name - - - - - - IPv4 firewall ruleset - - firewall name - - - - - - - - - - Interface associated with zone - - txt - Interface associated with zone - - - vrf - VRF associated with zone - - - - vrf name - - - - - - - Intra-zone filtering - - - - - Action for intra-zone traffic - - accept drop - - - accept - Accept traffic - - - drop - Drop silently - - - (accept|drop) - - - - - - Use the specified firewall chain - - - - - IPv6 firewall ruleset - - firewall ipv6-name - - - - - - IPv4 firewall ruleset - - firewall name - - - - - - - - - - Zone to be local-zone - - - + #include + #include + #include + #include - + diff --git a/interface-definitions/include/firewall/action-and-notrack.xml.i b/interface-definitions/include/firewall/action-and-notrack.xml.i new file mode 100644 index 000000000..5f81a1451 --- /dev/null +++ b/interface-definitions/include/firewall/action-and-notrack.xml.i @@ -0,0 +1,41 @@ + + + + Rule action + + accept jump notrack reject return drop queue + + + accept + Accept matching entries + + + jump + Jump to another chain + + + reject + Reject matching entries + + + return + Return from the current chain and continue at the next rule of the last chain + + + drop + Drop matching entries + + + queue + Enqueue packet to userspace + + + notrack + Igone connection tracking + + + (accept|jump|notrack|reject|return|drop|queue) + + + + diff --git a/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i new file mode 100644 index 000000000..86af2fb0e --- /dev/null +++ b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i @@ -0,0 +1,331 @@ + +#include +#include +#include +#include +#include + + + Destination parameters + + + #include + #include + #include + #include + #include + #include + #include + + + + + Option to disable firewall rule + + + + + + IP fragment match + + + + + Second and further fragments of fragmented packets + + + + + + Head fragments or unfragmented packets + + + + + + + + ICMP type and code information + + + + + ICMP code + + u32:0-255 + ICMP code (0-255) + + + + + + + + + ICMP type + + u32:0-255 + ICMP type (0-255) + + + + + + + #include + + + + + Inbound IPsec packets + + + + + Inbound IPsec packets + + + + + + Inbound non-IPsec packets + + + + + + + + Rate limit using a token bucket filter + + + + + Maximum number of packets to allow in excess of rate + + u32:0-4294967295 + Maximum number of packets to allow in excess of rate + + + + + + + + + Maximum average matching rate + + txt + integer/unit (Example: 5/minute) + + + \d+/(second|minute|hour|day) + + + + + + + + Option to log packets matching rule + + enable disable + + + enable + Enable log + + + disable + Disable log + + + (enable|disable) + + + +#include + + + Connection status + + + + + NAT connection status + + destination source + + + destination + Match connections that are subject to destination NAT + + + source + Match connections that are subject to source NAT + + + ^(destination|source)$ + + + + + + + + Protocol to match (protocol name, number, or "all") + + + all tcp_udp + + + all + All IP protocols + + + tcp_udp + Both TCP and UDP + + + u32:0-255 + IP protocol number + + + <protocol> + IP protocol name + + + !<protocol> + IP protocol name + + + + + + + + + Parameters for matching recently seen sources + + + + + Source addresses seen more than N times + + u32:1-255 + Source addresses seen more than N times + + + + + + + + + Source addresses seen in the last second/minute/hour + + second minute hour + + + second + Source addresses seen COUNT times in the last second + + + minute + Source addresses seen COUNT times in the last minute + + + hour + Source addresses seen COUNT times in the last hour + + + (second|minute|hour) + + + + + + + + Source parameters + + + #include + #include + #include + #include + #include + #include + #include + + +#include + + + Time to match rule + + + + + Date to start matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to start matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Date to stop matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to stop matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Comma separated weekdays to match rule on + + txt + Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday) + + + u32:0-6 + Day number (0 = Sunday ... 6 = Saturday) + + + + + + diff --git a/interface-definitions/include/firewall/common-rule-ipv4.xml.i b/interface-definitions/include/firewall/common-rule-ipv4.xml.i new file mode 100644 index 000000000..b873d99a3 --- /dev/null +++ b/interface-definitions/include/firewall/common-rule-ipv4.xml.i @@ -0,0 +1,416 @@ + +#include +#include +#include +#include +#include +#include +#include + + + Destination parameters + + + #include + #include + #include + #include + #include + #include + #include + + + + + Option to disable firewall rule + + + + + + IP fragment match + + + + + Second and further fragments of fragmented packets + + + + + + Head fragments or unfragmented packets + + + + + + + + ICMP type and code information + + + + + ICMP code + + u32:0-255 + ICMP code (0-255) + + + + + + + + + ICMP type + + u32:0-255 + ICMP type (0-255) + + + + + + + #include + + + + + Inbound IPsec packets + + + + + Inbound IPsec packets + + + + + + Inbound non-IPsec packets + + + + + + + + Rate limit using a token bucket filter + + + + + Maximum number of packets to allow in excess of rate + + u32:0-4294967295 + Maximum number of packets to allow in excess of rate + + + + + + + + + Maximum average matching rate + + txt + integer/unit (Example: 5/minute) + + + \d+/(second|minute|hour|day) + + + + + + + + Option to log packets matching rule + + enable disable + + + enable + Enable log + + + disable + Disable log + + + (enable|disable) + + + +#include + + + Connection status + + + + + NAT connection status + + destination source + + + destination + Match connections that are subject to destination NAT + + + source + Match connections that are subject to source NAT + + + ^(destination|source)$ + + + + + + + + Protocol to match (protocol name, number, or "all") + + + all tcp_udp + + + all + All IP protocols + + + tcp_udp + Both TCP and UDP + + + u32:0-255 + IP protocol number + + + <protocol> + IP protocol name + + + !<protocol> + IP protocol name + + + + + + + + + Parameters for matching recently seen sources + + + + + Source addresses seen more than N times + + u32:1-255 + Source addresses seen more than N times + + + + + + + + + Source addresses seen in the last second/minute/hour + + second minute hour + + + second + Source addresses seen COUNT times in the last second + + + minute + Source addresses seen COUNT times in the last minute + + + hour + Source addresses seen COUNT times in the last hour + + + (second|minute|hour) + + + + + + + + Source parameters + + + #include + #include + #include + #include + #include + #include + #include + + + + + Session state + + + + + Established state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + Invalid state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + New state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + Related state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + +#include + + + Time to match rule + + + + + Date to start matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to start matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Date to stop matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to stop matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Comma separated weekdays to match rule on + + txt + Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday) + + + u32:0-6 + Day number (0 = Sunday ... 6 = Saturday) + + + + + + diff --git a/interface-definitions/include/firewall/common-rule-ipv6.xml.i b/interface-definitions/include/firewall/common-rule-ipv6.xml.i new file mode 100644 index 000000000..758281335 --- /dev/null +++ b/interface-definitions/include/firewall/common-rule-ipv6.xml.i @@ -0,0 +1,416 @@ + +#include +#include +#include +#include +#include +#include +#include + + + Destination parameters + + + #include + #include + #include + #include + #include + #include + #include + + + + + Option to disable firewall rule + + + + + + IP fragment match + + + + + Second and further fragments of fragmented packets + + + + + + Head fragments or unfragmented packets + + + + + + + + ICMPv6 type and code information + + + + + ICMPv6 code + + u32:0-255 + ICMPv6 code (0-255) + + + + + + + + + ICMPv6 type + + u32:0-255 + ICMPv6 type (0-255) + + + + + + + #include + + + + + Inbound IPsec packets + + + + + Inbound IPsec packets + + + + + + Inbound non-IPsec packets + + + + + + + + Rate limit using a token bucket filter + + + + + Maximum number of packets to allow in excess of rate + + u32:0-4294967295 + Maximum number of packets to allow in excess of rate + + + + + + + + + Maximum average matching rate + + txt + integer/unit (Example: 5/minute) + + + \d+/(second|minute|hour|day) + + + + + + + + Option to log packets matching rule + + enable disable + + + enable + Enable log + + + disable + Disable log + + + (enable|disable) + + + +#include + + + Connection status + + + + + NAT connection status + + destination source + + + destination + Match connections that are subject to destination NAT + + + source + Match connections that are subject to source NAT + + + ^(destination|source)$ + + + + + + + + Protocol to match (protocol name, number, or "all") + + + all tcp_udp + + + all + All IP protocols + + + tcp_udp + Both TCP and UDP + + + u32:0-255 + IP protocol number + + + <protocol> + IP protocol name + + + !<protocol> + IP protocol name + + + + + + + + + Parameters for matching recently seen sources + + + + + Source addresses seen more than N times + + u32:1-255 + Source addresses seen more than N times + + + + + + + + + Source addresses seen in the last second/minute/hour + + second minute hour + + + second + Source addresses seen COUNT times in the last second + + + minute + Source addresses seen COUNT times in the last minute + + + hour + Source addresses seen COUNT times in the last hour + + + (second|minute|hour) + + + + + + + + Source parameters + + + #include + #include + #include + #include + #include + #include + #include + + + + + Session state + + + + + Established state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + Invalid state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + New state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + Related state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + +#include + + + Time to match rule + + + + + Date to start matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to start matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Date to stop matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to stop matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Comma separated weekdays to match rule on + + txt + Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday) + + + u32:0-6 + Day number (0 = Sunday ... 6 = Saturday) + + + + + + diff --git a/interface-definitions/include/firewall/default-action-base-chains.xml.i b/interface-definitions/include/firewall/default-action-base-chains.xml.i new file mode 100644 index 000000000..ba7c63cd6 --- /dev/null +++ b/interface-definitions/include/firewall/default-action-base-chains.xml.i @@ -0,0 +1,22 @@ + + + + Default-action for rule-set + + drop accept + + + drop + Drop if no prior rules are hit + + + accept + Accept if no prior rules are hit + + + (drop|accept) + + + drop + + diff --git a/interface-definitions/include/firewall/global-options.xml.i b/interface-definitions/include/firewall/global-options.xml.i new file mode 100644 index 000000000..3204a239d --- /dev/null +++ b/interface-definitions/include/firewall/global-options.xml.i @@ -0,0 +1,272 @@ + + + + Global Options + + + + + Policy for handling of all IPv4 ICMP echo requests + + enable disable + + + enable + Enable processing of all IPv4 ICMP echo requests + + + disable + Disable processing of all IPv4 ICMP echo requests + + + (enable|disable) + + + enable + + + + Policy for handling broadcast IPv4 ICMP echo and timestamp requests + + enable disable + + + enable + Enable processing of broadcast IPv4 ICMP echo/timestamp requests + + + disable + Disable processing of broadcast IPv4 ICMP echo/timestamp requests + + + (enable|disable) + + + disable + + + + SNMP trap generation on firewall configuration changes + + enable disable + + + enable + Enable sending SNMP trap on firewall configuration change + + + disable + Disable sending SNMP trap on firewall configuration change + + + (enable|disable) + + + disable + + + + Policy for handling IPv4 packets with source route option + + enable disable + + + enable + Enable processing of IPv4 packets with source route option + + + disable + Disable processing of IPv4 packets with source route option + + + (enable|disable) + + + disable + + + + Policy for logging IPv4 packets with invalid addresses + + enable disable + + + enable + Enable logging of IPv4 packets with invalid addresses + + + disable + Disable logging of Ipv4 packets with invalid addresses + + + (enable|disable) + + + enable + + + + Policy for handling received IPv4 ICMP redirect messages + + enable disable + + + enable + Enable processing of received IPv4 ICMP redirect messages + + + disable + Disable processing of received IPv4 ICMP redirect messages + + + (enable|disable) + + + disable + + + + Retains last successful value if domain resolution fails + + + + + + Domain resolver update interval + + u32:10-3600 + Interval (seconds) + + + + + + 300 + + + + Policy for sending IPv4 ICMP redirect messages + + enable disable + + + enable + Enable sending IPv4 ICMP redirect messages + + + disable + Disable sending IPv4 ICMP redirect messages + + + (enable|disable) + + + enable + + + + Policy for source validation by reversed path, as specified in 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) + + + disable + + + + Policy for using TCP SYN cookies with IPv4 + + enable disable + + + enable + Enable use of TCP SYN cookies with IPv4 + + + disable + Disable use of TCP SYN cookies with IPv4 + + + (enable|disable) + + + enable + + + + RFC1337 TCP TIME-WAIT assasination hazards protection + + enable disable + + + enable + Enable RFC1337 TIME-WAIT hazards protection + + + disable + Disable RFC1337 TIME-WAIT hazards protection + + + (enable|disable) + + + disable + + + + Policy for handling received ICMPv6 redirect messages + + enable disable + + + enable + Enable processing of received ICMPv6 redirect messages + + + disable + Disable processing of received ICMPv6 redirect messages + + + (enable|disable) + + + disable + + + + Policy for handling IPv6 packets with routing extension header + + enable disable + + + enable + Enable processing of IPv6 packets with routing header type 2 + + + disable + Disable processing of IPv6 packets with routing header + + + (enable|disable) + + + disable + + + + diff --git a/interface-definitions/include/firewall/inbound-interface.xml.i b/interface-definitions/include/firewall/inbound-interface.xml.i new file mode 100644 index 000000000..13df71de3 --- /dev/null +++ b/interface-definitions/include/firewall/inbound-interface.xml.i @@ -0,0 +1,10 @@ + + + + Match inbound-interface + + + #include + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-custom-name.xml.i b/interface-definitions/include/firewall/ipv4-custom-name.xml.i new file mode 100644 index 000000000..b2f8271f7 --- /dev/null +++ b/interface-definitions/include/firewall/ipv4-custom-name.xml.i @@ -0,0 +1,49 @@ + + + + IPv4 custom firewall + + [a-zA-Z0-9][\w\-\.]* + + + + #include + #include + #include + + + Set jump target. Action jump must be defined in default-action to use this setting + + firewall ip name + + + + + + IP Firewall custom rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ip name + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i new file mode 100644 index 000000000..6179afe31 --- /dev/null +++ b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i @@ -0,0 +1,44 @@ + + + + IPv4 forward firewall + + + + + IPv4 firewall forward filter + + + #include + #include + + + IP Firewall forward filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ip name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-hook-input.xml.i b/interface-definitions/include/firewall/ipv4-hook-input.xml.i new file mode 100644 index 000000000..f9746378b --- /dev/null +++ b/interface-definitions/include/firewall/ipv4-hook-input.xml.i @@ -0,0 +1,43 @@ + + + + IPv4 input firewall + + + + + IPv4 firewall input filter + + + #include + #include + + + IP Firewall input filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ip name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-hook-output.xml.i b/interface-definitions/include/firewall/ipv4-hook-output.xml.i new file mode 100644 index 000000000..a1820f314 --- /dev/null +++ b/interface-definitions/include/firewall/ipv4-hook-output.xml.i @@ -0,0 +1,43 @@ + + + + IPv4 output firewall + + + + + IPv4 firewall output filter + + + #include + #include + + + IP Firewall output filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ip name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i b/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i new file mode 100644 index 000000000..229a25ef4 --- /dev/null +++ b/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i @@ -0,0 +1,85 @@ + + + + IPv4 prerouting firewall + + + + + IPv4 firewall prerouting filter + + + #include + #include + + + IP Firewall prerouting filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ip name + + + + + + + + + + IPv4 firewall prerouting raw + + + #include + #include + + + Set jump target. Action jump must be defined in default-action to use this setting + + firewall ip name + + + + + + IP Firewall prerouting raw rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ip name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv6-custom-name.xml.i b/interface-definitions/include/firewall/ipv6-custom-name.xml.i new file mode 100644 index 000000000..6275036c1 --- /dev/null +++ b/interface-definitions/include/firewall/ipv6-custom-name.xml.i @@ -0,0 +1,49 @@ + + + + IPv6 custom firewall + + [a-zA-Z0-9][\w\-\.]* + + + + #include + #include + #include + + + Set jump target. Action jump must be defined in default-action to use this setting + + firewall ipv6 ipv6-name + + + + + + IPv6 Firewall custom rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ipv6 ipv6-name + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i new file mode 100644 index 000000000..042bd9931 --- /dev/null +++ b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i @@ -0,0 +1,44 @@ + + + + IPv6 forward firewall + + + + + IPv6 firewall forward filter + + + #include + #include + + + IPv6 Firewall forward filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ipv6 ipv6-name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv6-hook-input.xml.i b/interface-definitions/include/firewall/ipv6-hook-input.xml.i new file mode 100644 index 000000000..8c41e0aca --- /dev/null +++ b/interface-definitions/include/firewall/ipv6-hook-input.xml.i @@ -0,0 +1,43 @@ + + + + IPv6 input firewall + + + + + IPv6 firewall input filter + + + #include + #include + + + IPv6 Firewall input filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ipv6 ipv6-name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv6-hook-output.xml.i b/interface-definitions/include/firewall/ipv6-hook-output.xml.i new file mode 100644 index 000000000..9b756d870 --- /dev/null +++ b/interface-definitions/include/firewall/ipv6-hook-output.xml.i @@ -0,0 +1,43 @@ + + + + IPv6 output firewall + + + + + IPv6 firewall output filter + + + #include + #include + + + IPv6 Firewall output filter rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + Set jump target. Action jump must be defined to use this setting + + firewall ipv6 ipv6-name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/match-interface.xml.i b/interface-definitions/include/firewall/match-interface.xml.i index 3e52422cf..a62bf8d89 100644 --- a/interface-definitions/include/firewall/match-interface.xml.i +++ b/interface-definitions/include/firewall/match-interface.xml.i @@ -5,6 +5,13 @@ + + txt + Interface name, wildcard (*) supported + + + #include + diff --git a/interface-definitions/include/firewall/outbound-interface.xml.i b/interface-definitions/include/firewall/outbound-interface.xml.i new file mode 100644 index 000000000..8654dfd80 --- /dev/null +++ b/interface-definitions/include/firewall/outbound-interface.xml.i @@ -0,0 +1,10 @@ + + + + Match outbound-interface + + + #include + + + \ No newline at end of file diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i index c32484542..dd21bfaca 100644 --- a/interface-definitions/include/version/firewall-version.xml.i +++ b/interface-definitions/include/version/firewall-version.xml.i @@ -1,3 +1,3 @@ - + -- cgit v1.2.3 From a8244928af84e65dcc9833e14e2de3324b484977 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Tue, 23 May 2023 14:53:57 -0300 Subject: T5160: firewall refactor: new cli structure. Update jinja templates, python scripts and src firewall --- data/templates/firewall/nftables-policy.j2 | 4 +- data/templates/firewall/nftables.j2 | 361 +++++++++++++++++------------ python/vyos/firewall.py | 67 ++++-- python/vyos/template.py | 8 +- src/conf_mode/firewall.py | 174 +++++--------- 5 files changed, 325 insertions(+), 289 deletions(-) diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 index 1c9bda64f..699349e2b 100644 --- a/data/templates/firewall/nftables-policy.j2 +++ b/data/templates/firewall/nftables-policy.j2 @@ -25,7 +25,7 @@ table ip vyos_mangle { chain VYOS_PBR_UD_{{ route_text }} { {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} - {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }} + {{ rule_conf | nft_rule('route', route_text, rule_id, 'ip') }} {% endfor %} {% endif %} } @@ -54,7 +54,7 @@ table ip6 vyos_mangle { chain VYOS_PBR6_UD_{{ route_text }} { {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} - {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }} + {{ rule_conf | nft_rule('route6', route_text, rule_id, 'ip6') }} {% endfor %} {% endif %} } diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index 2c7115134..dcfe71a58 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -7,86 +7,147 @@ delete table ip vyos_filter {% endif %} table ip vyos_filter { - chain VYOS_FW_FORWARD { - type filter hook forward priority 0; policy accept; -{% if state_policy is vyos_defined %} - jump VYOS_STATE_POLICY -{% endif %} -{% if interface is vyos_defined %} -{% for ifname, ifconf in interface.items() %} -{% if ifconf.in is vyos_defined and ifconf.in.name is vyos_defined %} - iifname {{ ifname }} counter jump NAME_{{ ifconf.in.name }} -{% endif %} -{% if ifconf.out is vyos_defined and ifconf.out.name is vyos_defined %} - oifname {{ ifname }} counter jump NAME_{{ ifconf.out.name }} -{% endif %} -{% endfor %} -{% endif %} - jump VYOS_POST_FW +{% if ip is vyos_defined %} +{% if ip.forward is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ip.forward.items() %} +{% set def_action = conf.default_action %} + chain VYOS_FORWARD_{{ prior }} { + type filter hook forward priority {{ prior }}; policy {{ def_action }}; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('FWD', prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['FWD_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} } - chain VYOS_FW_LOCAL { - type filter hook input priority 0; policy accept; -{% if state_policy is vyos_defined %} - jump VYOS_STATE_POLICY -{% endif %} -{% if interface is vyos_defined %} -{% for ifname, ifconf in interface.items() %} -{% if ifconf.local is vyos_defined and ifconf.local.name is vyos_defined %} - iifname {{ ifname }} counter jump NAME_{{ ifconf.local.name }} -{% endif %} -{% endfor %} -{% endif %} - jump VYOS_POST_FW +{% endfor %} +{% for set_name in ns.sets %} + set RECENT_{{ set_name }} { + type ipv4_addr + size 65535 + flags dynamic } - chain VYOS_FW_OUTPUT { - type filter hook output priority 0; policy accept; -{% if state_policy is vyos_defined %} - jump VYOS_STATE_POLICY -{% endif %} - jump VYOS_POST_FW +{% endfor %} +{% endif %} + +{% if ip.input is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ip.input.items() %} +{% set def_action = conf.default_action %} + chain VYOS_INPUT_{{ prior }} { + type filter hook input priority {{ prior }}; policy {{ def_action }}; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('INP',prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['INP_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + } +{% endfor %} +{% for set_name in ns.sets %} + set RECENT_{{ set_name }} { + type ipv4_addr + size 65535 + flags dynamic } - chain VYOS_POST_FW { - return +{% endfor %} +{% endif %} + +{% if ip.output is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ip.output.items() %} +{% set def_action = conf.default_action %} + chain VYOS_OUTPUT_{{ prior }} { + type filter hook output priority {{ prior }}; policy {{ def_action }}; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('OUT', prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['OUT_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} } +{% endfor %} +{% for set_name in ns.sets %} + set RECENT_{{ set_name }} { + type ipv4_addr + size 65535 + flags dynamic + } +{% endfor %} +{% endif %} + chain VYOS_FRAG_MARK { type filter hook prerouting priority -450; policy accept; ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return } -{% if name is vyos_defined %} -{% set ns = namespace(sets=[]) %} -{% for name_text, conf in name.items() %} - chain NAME_{{ name_text }} { -{% if conf.rule is vyos_defined %} -{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} - {{ rule_conf | nft_rule(name_text, rule_id) }} -{% if rule_conf.recent is vyos_defined %} -{% set ns.sets = ns.sets + [name_text + '_' + rule_id] %} -{% endif %} -{% endfor %} -{% endif %} - {{ conf | nft_default_rule(name_text) }} +{% if ip.prerouting is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ip.prerouting.items() %} + chain VYOS_PREROUTING_{{ prior }} { + type filter hook prerouting priority {{ prior }}; policy accept; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('PRE', prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['PRE_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(prior) }} + # jump VYOS_POST_FW } -{% endfor %} -{% for set_name in ip_fqdn %} - set FQDN_{{ set_name }} { +{% endfor %} +{% for set_name in ns.sets %} + set RECENT_{{ set_name }} { type ipv4_addr - flags interval + size 65535 + flags dynamic } -{% endfor %} -{% for set_name in ns.sets %} +{% endfor %} +{% endif %} +{% if ip.name is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for name_text, conf in ip.name.items() %} + chain NAME_{{ name_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('NAM', name_text, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['NAM_' + name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(name_text) }} + } +{% endfor %} +{% for set_name in ns.sets %} set RECENT_{{ set_name }} { type ipv4_addr size 65535 flags dynamic } -{% endfor %} -{% if geoip_updated.name is vyos_defined %} -{% for setname in geoip_updated.name %} - set {{ setname }} { +{% endfor %} +{% for set_name in ip_fqdn %} + set FQDN_{{ set_name }} { type ipv4_addr flags interval } {% endfor %} +{% if geoip_updated.name is vyos_defined %} +{% for setname in geoip_updated.name %} + set {{ setname }} { + type ipv4_addr + flags interval + } +{% endfor %} +{% endif %} {% endif %} {% endif %} @@ -95,107 +156,128 @@ table ip vyos_filter { {% if zone is vyos_defined %} {{ zone_tmpl.zone_chains(zone, state_policy is vyos_defined, False) }} {% endif %} - -{% if state_policy is vyos_defined %} - chain VYOS_STATE_POLICY { -{% if state_policy.established is vyos_defined %} - {{ state_policy.established | nft_state_policy('established') }} -{% endif %} -{% if state_policy.invalid is vyos_defined %} - {{ state_policy.invalid | nft_state_policy('invalid') }} -{% endif %} -{% if state_policy.related is vyos_defined %} - {{ state_policy.related | nft_state_policy('related') }} -{% endif %} - return - } -{% endif %} } {% if first_install is not vyos_defined %} delete table ip6 vyos_filter {% endif %} table ip6 vyos_filter { - chain VYOS_FW6_FORWARD { - type filter hook forward priority 0; policy accept; -{% if state_policy is vyos_defined %} - jump VYOS_STATE_POLICY6 -{% endif %} -{% if interface is vyos_defined %} -{% for ifname, ifconf in interface.items() %} -{% if ifconf.in is vyos_defined and ifconf.in.ipv6_name is vyos_defined %} - iifname {{ ifname }} counter jump NAME6_{{ ifconf.in.ipv6_name }} -{% endif %} -{% if ifconf.out is vyos_defined and ifconf.out.ipv6_name is vyos_defined %} - oifname {{ ifname }} counter jump NAME6_{{ ifconf.out.ipv6_name }} -{% endif %} -{% endfor %} -{% endif %} - jump VYOS_POST_FW6 +{% if ipv6 is vyos_defined %} +{% if ipv6.forward is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ipv6.forward.items() %} +{% set def_action = conf.default_action %} + chain VYOS_IPV6_FORWARD_{{ prior }} { + type filter hook forward priority {{ prior }}; policy {{ def_action }}; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('FWD', prior, rule_id ,'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['FWD_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} } - chain VYOS_FW6_LOCAL { - type filter hook input priority 0; policy accept; -{% if state_policy is vyos_defined %} - jump VYOS_STATE_POLICY6 -{% endif %} -{% if interface is vyos_defined %} -{% for ifname, ifconf in interface.items() %} -{% if ifconf.local is vyos_defined and ifconf.local.ipv6_name is vyos_defined %} - iifname {{ ifname }} counter jump NAME6_{{ ifconf.local.ipv6_name }} -{% endif %} -{% endfor %} -{% endif %} - jump VYOS_POST_FW6 +{% endfor %} +{% for set_name in ns.sets %} + set RECENT6_{{ set_name }} { + type ipv6_addr + size 65535 + flags dynamic } - chain VYOS_FW6_OUTPUT { - type filter hook output priority 0; policy accept; -{% if state_policy is vyos_defined %} - jump VYOS_STATE_POLICY6 -{% endif %} - jump VYOS_POST_FW6 +{% endfor %} +{% endif %} + +{% if ipv6.input is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ipv6.input.items() %} +{% set def_action = conf.default_action %} + chain VYOS_IPV6_INPUT_{{ prior }} { + type filter hook input priority {{ prior }}; policy {{ def_action }}; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('INP', prior, rule_id ,'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['INP_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} } - chain VYOS_POST_FW6 { - return +{% endfor %} +{% for set_name in ns.sets %} + set RECENT6_{{ set_name }} { + type ipv6_addr + size 65535 + flags dynamic } +{% endfor %} +{% endif %} + +{% if ipv6.output is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for prior, conf in ipv6.output.items() %} +{% set def_action = conf.default_action %} + chain VYOS_IPV6_OUTPUT_{{ prior }} { + type filter hook output priority {{ prior }}; policy {{ def_action }}; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('OUT', prior, rule_id ,'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['OUT_ ' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + } +{% endfor %} +{% for set_name in ns.sets %} + set RECENT6_{{ set_name }} { + type ipv6_addr + size 65535 + flags dynamic + } +{% endfor %} +{% endif %} chain VYOS_FRAG6_MARK { type filter hook prerouting priority -450; policy accept; exthdr frag exists meta mark set 0xffff1 return } -{% if ipv6_name is vyos_defined %} -{% set ns = namespace(sets=[]) %} -{% for name_text, conf in ipv6_name.items() %} + +{% if ipv6.ipv6_name is vyos_defined %} +{% set ns = namespace(sets=[]) %} +{% for name_text, conf in ipv6.ipv6_name.items() %} chain NAME6_{{ name_text }} { -{% if conf.rule is vyos_defined %} -{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} - {{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }} -{% if rule_conf.recent is vyos_defined %} -{% set ns.sets = ns.sets + [name_text + '_' + rule_id] %} -{% endif %} -{% endfor %} -{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('NAM', name_text, rule_id, 'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['NAM_' + name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} {{ conf | nft_default_rule(name_text, ipv6=True) }} } -{% endfor %} -{% for set_name in ip6_fqdn %} +{% endfor %} +{% for set_name in ip6_fqdn %} set FQDN_{{ set_name }} { type ipv6_addr flags interval } -{% endfor %} -{% for set_name in ns.sets %} +{% endfor %} +{% for set_name in ns.sets %} set RECENT6_{{ set_name }} { type ipv6_addr size 65535 flags dynamic } -{% endfor %} -{% if geoip_updated.ipv6_name is vyos_defined %} -{% for setname in geoip_updated.ipv6_name %} +{% endfor %} +{% if geoip_updated.ipv6_name is vyos_defined %} +{% for setname in geoip_updated.ipv6_name %} set {{ setname }} { type ipv6_addr flags interval } -{% endfor %} +{% endfor %} +{% endif %} {% endif %} {% endif %} @@ -204,19 +286,4 @@ table ip6 vyos_filter { {% if zone is vyos_defined %} {{ zone_tmpl.zone_chains(zone, state_policy is vyos_defined, True) }} {% endif %} - -{% if state_policy is vyos_defined %} - chain VYOS_STATE_POLICY6 { -{% if state_policy.established is vyos_defined %} - {{ state_policy.established | nft_state_policy('established') }} -{% endif %} -{% if state_policy.invalid is vyos_defined %} - {{ state_policy.invalid | nft_state_policy('invalid') }} -{% endif %} -{% if state_policy.related is vyos_defined %} - {{ state_policy.related | nft_state_policy('related') }} -{% endif %} - return - } -{% endif %} -} +} \ No newline at end of file diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 903cc8535..86a324062 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -41,14 +41,19 @@ def fqdn_config_parse(firewall): firewall['ip6_fqdn'] = {} for domain, path in dict_search_recursive(firewall, 'fqdn'): - fw_name = path[1] # name/ipv6-name - rule = path[3] # rule id - suffix = path[4][0] # source/destination (1 char) - set_name = f'{fw_name}_{rule}_{suffix}' - - if path[0] == 'name': + hook_name = path[1] + priority = path[2] + + fw_name = path[2] + rule = path[4] + suffix = path[5][0] + set_name = f'{hook_name}_{priority}_{rule}_{suffix}' + + if (path[0] == 'ip') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'): firewall['ip_fqdn'][set_name] = domain - elif path[0] == 'ipv6_name': + elif (path[0] == 'ipv6') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name'): + if path[1] == 'ipv6_name': + set_name = f'name6_{priority}_{rule}_{suffix}' firewall['ip6_fqdn'][set_name] = domain def fqdn_resolve(fqdn, ipv6=False): @@ -80,7 +85,7 @@ def nft_action(vyos_action): return 'return' return vyos_action -def parse_rule(rule_conf, fw_name, rule_id, ip_name): +def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): output = [] def_suffix = '6' if ip_name == 'ip6' else '' @@ -129,16 +134,34 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): if 'fqdn' in side_conf: fqdn = side_conf['fqdn'] + hook_name = '' operator = '' if fqdn[0] == '!': operator = '!=' - output.append(f'{ip_name} {prefix}addr {operator} @FQDN_{fw_name}_{rule_id}_{prefix}') + if hook == 'FWD': + hook_name = 'forward' + if hook == 'INP': + hook_name = 'input' + if hook == 'OUT': + hook_name = 'output' + if hook == 'NAM': + hook_name = f'name{def_suffix}' + output.append(f'{ip_name} {prefix}addr {operator} @FQDN_{hook_name}_{fw_name}_{rule_id}_{prefix}') if dict_search_args(side_conf, 'geoip', 'country_code'): operator = '' + hook_name = '' if dict_search_args(side_conf, 'geoip', 'inverse_match') != None: operator = '!=' - output.append(f'{ip_name} {prefix}addr {operator} @GEOIP_CC_{fw_name}_{rule_id}') + if hook == 'FWD': + hook_name = 'forward' + if hook == 'INP': + hook_name = 'input' + if hook == 'OUT': + hook_name = 'output' + if hook == 'NAM': + hook_name = f'name{def_suffix}' + output.append(f'{ip_name} {prefix}addr {operator} @GEOIP_CC_{hook_name}_{fw_name}_{rule_id}') if 'mac_address' in side_conf: suffix = side_conf["mac_address"] @@ -324,7 +347,7 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): if 'recent' in rule_conf: count = rule_conf['recent']['count'] time = rule_conf['recent']['time'] - output.append(f'add @RECENT{def_suffix}_{fw_name}_{rule_id} {{ {ip_name} saddr limit rate over {count}/{time} burst {count} packets }}') + output.append(f'add @RECENT{def_suffix}_{hook}_{fw_name}_{rule_id} {{ {ip_name} saddr limit rate over {count}/{time} burst {count} packets }}') if 'time' in rule_conf: output.append(parse_time(rule_conf['time'])) @@ -348,7 +371,9 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): output.append(parse_policy_set(rule_conf['set'], def_suffix)) if 'action' in rule_conf: - output.append(nft_action(rule_conf['action'])) + # Change action=return to action=action + # #output.append(nft_action(rule_conf['action'])) + output.append(f'{rule_conf["action"]}') if 'jump' in rule_conf['action']: target = rule_conf['jump_target'] output.append(f'NAME{def_suffix}_{target}') @@ -365,7 +390,7 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name): else: output.append('return') - output.append(f'comment "{fw_name}-{rule_id}"') + output.append(f'comment "{hook}-{fw_name}-{rule_id}"') return " ".join(output) def parse_tcp_flags(flags): @@ -493,13 +518,15 @@ def geoip_update(firewall, force=False): # Map country codes to set names for codes, path in dict_search_recursive(firewall, 'country_code'): - set_name = f'GEOIP_CC_{path[1]}_{path[3]}' - if path[0] == 'name': - for code in codes: - ipv4_codes.setdefault(code, []).append(set_name) - elif path[0] == 'ipv6_name': - for code in codes: - ipv6_codes.setdefault(code, []).append(set_name) + set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' + if path[1] == 'ipv6_name': + set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' + if ( path[0] == 'ip' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): + for code in codes: + ipv4_codes.setdefault(code, []).append(set_name) + elif ( path[0] == 'ipv6' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): + for code in codes: + ipv6_codes.setdefault(code, []).append(set_name) if not ipv4_codes and not ipv6_codes: if force: diff --git a/python/vyos/template.py b/python/vyos/template.py index 6469623fd..5a3505b91 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -44,7 +44,6 @@ def _get_environment(location=None): loader=loc_loader, trim_blocks=True, undefined=ChainableUndefined, - extensions=['jinja2.ext.loopcontrols'] ) env.filters.update(_FILTERS) env.tests.update(_TESTS) @@ -574,9 +573,9 @@ def nft_action(vyos_action): return vyos_action @register_filter('nft_rule') -def nft_rule(rule_conf, fw_name, rule_id, ip_name='ip'): +def nft_rule(rule_conf, fw_hook, fw_name, rule_id, ip_name='ip'): from vyos.firewall import parse_rule - return parse_rule(rule_conf, fw_name, rule_id, ip_name) + return parse_rule(rule_conf, fw_hook, fw_name, rule_id, ip_name) @register_filter('nft_default_rule') def nft_default_rule(fw_conf, fw_name, ipv6=False): @@ -587,7 +586,8 @@ def nft_default_rule(fw_conf, fw_name, ipv6=False): action_suffix = default_action[:1].upper() output.append(f'log prefix "[{fw_name[:19]}-default-{action_suffix}]"') - output.append(nft_action(default_action)) + #output.append(nft_action(default_action)) + output.append(f'{default_action}') if 'default_jump_target' in fw_conf: target = fw_conf['default_jump_target'] def_suffix = '6' if ipv6 else '' diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 7242e503a..4c5341e22 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -23,6 +23,7 @@ from sys import exit from vyos.base import Warning from vyos.config import Config +from vyos.configdict import dict_merge from vyos.configdict import node_changed from vyos.configdiff import get_config_diff, Diff from vyos.configdep import set_dependents, call_dependents @@ -36,6 +37,7 @@ from vyos.utils.dict import dict_search_args from vyos.utils.dict import dict_search_recursive from vyos.utils.process import process_named_running from vyos.utils.process import rc_cmd +from vyos.xml import defaults from vyos import ConfigError from vyos import airbag airbag.enable() @@ -95,19 +97,22 @@ def geoip_updated(conf, firewall): updated = False for key, path in dict_search_recursive(firewall, 'geoip'): - set_name = f'GEOIP_CC_{path[1]}_{path[3]}' - if path[0] == 'name': + set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' + if path[1] == 'ipv6_name': + set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' + + if (path[0] == 'ip') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): out['name'].append(set_name) - elif path[0] == 'ipv6_name': + elif (path[0] == 'ipv6') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): out['ipv6_name'].append(set_name) updated = True if 'delete' in node_diff: for key, path in dict_search_recursive(node_diff['delete'], 'geoip'): - set_name = f'GEOIP_CC_{path[1]}_{path[3]}' - if path[0] == 'name': + set_name = f'GEOIP_CC_{path[2]}_{path[4]}' + if path[1] == 'name': out['deleted_name'].append(set_name) - elif path[0] == 'ipv6-name': + elif path[1] == 'ipv6-name': out['deleted_ipv6_name'].append(set_name) updated = True @@ -128,13 +133,14 @@ def get_config(config=None): get_first_key=True, with_recursive_defaults=True) - firewall['group_resync'] = bool('group' in firewall or node_changed(conf, base + ['group'])) + firewall['group_resync'] = bool('group' in firewall or node_changed(conf, base + ['group'])) if firewall['group_resync']: # Update nat and policy-route as firewall groups were updated set_dependents('group_resync', conf) - if 'config_trap' in firewall and firewall['config_trap'] == 'enable': + #if 'config_trap' in firewall and firewall['config_trap'] == 'enable': + if 'config_trap' in firewall and firewall['global_options']['config_trap'] == 'enable': diff = get_config_diff(conf) firewall['trap_diff'] = diff.get_child_nodes_diff_str(base) firewall['trap_targets'] = conf.get_config_dict(['service', 'snmp', 'trap-target'], @@ -159,10 +165,10 @@ def verify_rule(firewall, rule_conf, ipv6): raise ConfigError('jump-target defined, but action jump needed and it is not defined') target = rule_conf['jump_target'] if not ipv6: - if target not in dict_search_args(firewall, 'name'): + if target not in dict_search_args(firewall, 'ip', 'name'): raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') else: - if target not in dict_search_args(firewall, 'ipv6_name'): + if target not in dict_search_args(firewall, 'ipv6', 'ipv6_name'): raise ConfigError(f'Invalid jump-target. Firewall ipv6-name {target} does not exist on the system') if 'queue_options' in rule_conf: @@ -291,95 +297,45 @@ def verify(firewall): for group_name, group in groups.items(): verify_nested_group(group_name, group, groups, []) - for name in ['name', 'ipv6_name']: - if name in firewall: - for name_id, name_conf in firewall[name].items(): - if 'jump' in name_conf['default_action'] and 'default_jump_target' not in name_conf: - raise ConfigError('default-action set to jump, but no default-jump-target specified') - if 'default_jump_target' in name_conf: - target = name_conf['default_jump_target'] - if 'jump' not in name_conf['default_action']: - raise ConfigError('default-jump-target defined,but default-action jump needed and it is not defined') - if name_conf['default_jump_target'] == name_id: - raise ConfigError(f'Loop detected on default-jump-target.') - ## Now need to check that default-jump-target exists (other firewall chain/name) - if target not in dict_search_args(firewall, name): - raise ConfigError(f'Invalid jump-target. Firewall {name} {target} does not exist on the system') - - if 'rule' in name_conf: - for rule_id, rule_conf in name_conf['rule'].items(): - verify_rule(firewall, rule_conf, name == 'ipv6_name') - - if 'interface' in firewall: - for ifname, if_firewall in firewall['interface'].items(): - # verify ifname needs to be disabled, dynamic devices come up later - # verify_interface_exists(ifname) - - for direction in ['in', 'out', 'local']: - name = dict_search_args(if_firewall, direction, 'name') - ipv6_name = dict_search_args(if_firewall, direction, 'ipv6_name') - - if name and dict_search_args(firewall, 'name', name) == None: - raise ConfigError(f'Invalid firewall name "{name}" referenced on interface {ifname}') - - if ipv6_name and dict_search_args(firewall, 'ipv6_name', ipv6_name) == None: - raise ConfigError(f'Invalid firewall ipv6-name "{ipv6_name}" referenced on interface {ifname}') - - local_zone = False - zone_interfaces = [] - - if 'zone' in firewall: - for zone, zone_conf in firewall['zone'].items(): - if 'local_zone' not in zone_conf and 'interface' not in zone_conf: - raise ConfigError(f'Zone "{zone}" has no interfaces and is not the local zone') - - if 'local_zone' in zone_conf: - if local_zone: - raise ConfigError('There cannot be multiple local zones') - if 'interface' in zone_conf: - raise ConfigError('Local zone cannot have interfaces assigned') - if 'intra_zone_filtering' in zone_conf: - raise ConfigError('Local zone cannot use intra-zone-filtering') - local_zone = True - - if 'interface' in zone_conf: - found_duplicates = [intf for intf in zone_conf['interface'] if intf in zone_interfaces] - - if found_duplicates: - raise ConfigError(f'Interfaces cannot be assigned to multiple zones') - - zone_interfaces += zone_conf['interface'] - - if 'intra_zone_filtering' in zone_conf: - intra_zone = zone_conf['intra_zone_filtering'] - - if len(intra_zone) > 1: - raise ConfigError('Only one intra-zone-filtering action must be specified') - - if 'firewall' in intra_zone: - v4_name = dict_search_args(intra_zone, 'firewall', 'name') - if v4_name and not dict_search_args(firewall, 'name', v4_name): - raise ConfigError(f'Firewall name "{v4_name}" does not exist') - - v6_name = dict_search_args(intra_zone, 'firewall', 'ipv6_name') - if v6_name and not dict_search_args(firewall, 'ipv6_name', v6_name): - raise ConfigError(f'Firewall ipv6-name "{v6_name}" does not exist') - - if not v4_name and not v6_name: - raise ConfigError('No firewall names specified for intra-zone-filtering') - - if 'from' in zone_conf: - for from_zone, from_conf in zone_conf['from'].items(): - if from_zone not in firewall['zone']: - raise ConfigError(f'Zone "{zone}" refers to a non-existent or deleted zone "{from_zone}"') - - v4_name = dict_search_args(from_conf, 'firewall', 'name') - if v4_name and not dict_search_args(firewall, 'name', v4_name): - raise ConfigError(f'Firewall name "{v4_name}" does not exist') - - v6_name = dict_search_args(from_conf, 'firewall', 'ipv6_name') - if v6_name and not dict_search_args(firewall, 'ipv6_name', v6_name): - raise ConfigError(f'Firewall ipv6-name "{v6_name}" does not exist') + if 'ip' in firewall: + for name in ['name','forward','input','output']: + if name in firewall['ip']: + for name_id, name_conf in firewall['ip'][name].items(): + if 'jump' in name_conf['default_action'] and 'default_jump_target' not in name_conf: + raise ConfigError('default-action set to jump, but no default-jump-target specified') + if 'default_jump_target' in name_conf: + target = name_conf['default_jump_target'] + if 'jump' not in name_conf['default_action']: + raise ConfigError('default-jump-target defined, but default-action jump needed and it is not defined') + if name_conf['default_jump_target'] == name_id: + raise ConfigError(f'Loop detected on default-jump-target.') + ## Now need to check that default-jump-target exists (other firewall chain/name) + if target not in dict_search_args(firewall['ip'], 'name'): + raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') + + if 'rule' in name_conf: + for rule_id, rule_conf in name_conf['rule'].items(): + verify_rule(firewall, rule_conf, False) + + if 'ipv6' in firewall: + for name in ['ipv6_name','forward','input','output']: + if name in firewall['ipv6']: + for name_id, name_conf in firewall['ipv6'][name].items(): + if 'jump' in name_conf['default_action'] and 'default_jump_target' not in name_conf: + raise ConfigError('default-action set to jump, but no default-jump-target specified') + if 'default_jump_target' in name_conf: + target = name_conf['default_jump_target'] + if 'jump' not in name_conf['default_action']: + raise ConfigError('default-jump-target defined, but default-action jump needed and it is not defined') + if name_conf['default_jump_target'] == name_id: + raise ConfigError(f'Loop detected on default-jump-target.') + ## Now need to check that default-jump-target exists (other firewall chain/name) + if target not in dict_search_args(firewall['ipv6'], 'ipv6_name'): + raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') + + if 'rule' in name_conf: + for rule_id, rule_conf in name_conf['rule'].items(): + verify_rule(firewall, rule_conf, True) return None @@ -387,19 +343,6 @@ def generate(firewall): if not os.path.exists(nftables_conf): firewall['first_install'] = True - if 'zone' in firewall: - for local_zone, local_zone_conf in firewall['zone'].items(): - if 'local_zone' not in local_zone_conf: - continue - - local_zone_conf['from_local'] = {} - - for zone, zone_conf in firewall['zone'].items(): - if zone == local_zone or 'from' not in zone_conf: - continue - if local_zone in zone_conf['from']: - local_zone_conf['from_local'][zone] = zone_conf['from'][local_zone] - render(nftables_conf, 'firewall/nftables.j2', firewall) return None @@ -408,9 +351,8 @@ def apply_sysfs(firewall): paths = glob(conf['sysfs']) value = None - if name in firewall: - conf_value = firewall[name] - + if name in firewall['global_options']: + conf_value = firewall['global_options'][name] if conf_value in conf: value = conf[conf_value] elif conf_value == 'enable': @@ -427,7 +369,7 @@ def post_apply_trap(firewall): if 'first_install' in firewall: return None - if 'config_trap' not in firewall or firewall['config_trap'] != 'enable': + if 'config_trap' not in firewall['global_options'] or firewall['global_options']['config_trap'] != 'enable': return None if not process_named_running('snmpd'): -- cgit v1.2.3 From ac5b9a4630f87a34d367deef690e8a54cc1eabec Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Tue, 23 May 2023 14:56:29 -0300 Subject: T5160: firewall refactor: new cli structure. Add migration script and update smoketest --- smoketest/scripts/cli/test_firewall.py | 462 ++++++++++++++++---------------- src/migration-scripts/firewall/10-to-11 | 373 ++++++++++++++++++++++++++ 2 files changed, 601 insertions(+), 234 deletions(-) create mode 100755 src/migration-scripts/firewall/10-to-11 diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 0c56c2c93..153793453 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -90,19 +90,19 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): return False def test_geoip(self): - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'drop']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'se']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'gb']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'de']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'fr']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'inverse-match']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'se']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'gb']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'de']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'fr']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'inverse-match']) self.cli_commit() nftables_search = [ - ['ip saddr @GEOIP_CC_smoketest_1', 'drop'], - ['ip saddr != @GEOIP_CC_smoketest_2', 'return'] + ['ip saddr @GEOIP_CC_name_smoketest_1', 'drop'], + ['ip saddr != @GEOIP_CC_name_smoketest_2', 'accept'] ] # -t prevents 1000+ GeoIP elements being returned @@ -127,36 +127,33 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'interface-group', 'smoketest_interface', 'interface', 'eth0']) self.cli_set(['firewall', 'group', 'interface-group', 'smoketest_interface', 'interface', 'vtun0']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'source', 'group', 'mac-group', 'smoketest_mac']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'source', 'group', 'domain-group', 'smoketest_domain']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'action', 'accept']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'outbound-interface', 'interface-group', 'smoketest_interface']) - - self.cli_set(['firewall', 'interface', 'eth0', 'in', 'name', 'smoketest']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'destination', 'address', '172.16.10.10']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'protocol', 'tcp_udp']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '2', 'source', 'group', 'mac-group', 'smoketest_mac']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'source', 'group', 'domain-group', 'smoketest_domain']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'outbound-interface', 'interface-group', 'smoketest_interface']) self.cli_commit() self.wait_for_domain_resolver('ip vyos_filter', 'D_smoketest_domain', '192.0.2.5') nftables_search = [ - ['iifname "eth0"', 'jump NAME_smoketest'], - ['ip saddr @N_smoketest_network', 'ip daddr 172.16.10.10', 'th dport @P_smoketest_port', 'return'], + ['ip saddr @N_smoketest_network', 'ip daddr 172.16.10.10', 'th dport @P_smoketest_port', 'accept'], ['elements = { 172.16.99.0/24 }'], ['elements = { 53, 123 }'], - ['ether saddr @M_smoketest_mac', 'return'], + ['ether saddr @M_smoketest_mac', 'accept'], ['elements = { 00:01:02:03:04:05 }'], ['set D_smoketest_domain'], ['elements = { 192.0.2.5, 192.0.2.8,'], ['192.0.2.10, 192.0.2.11 }'], - ['ip saddr @D_smoketest_domain', 'return'], - ['oifname @I_smoketest_interface', 'return'] + ['ip saddr @D_smoketest_domain', 'accept'], + ['oifname @I_smoketest_interface', 'accept'] ] self.verify_nftables(nftables_search, 'ip vyos_filter') @@ -170,12 +167,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '53']) self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port1', 'port', '123']) self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port1', 'include', 'smoketest_port']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network1']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port1']) - self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp']) - - self.cli_set(['firewall', 'interface', 'eth0', 'in', 'name', 'smoketest']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network1']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port1']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp']) self.cli_commit() @@ -187,8 +182,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_delete(['firewall', 'group', 'network-group', 'smoketest_network', 'include', 'smoketest_network1']) nftables_search = [ - ['iifname "eth0"', 'jump NAME_smoketest'], - ['ip saddr @N_smoketest_network1', 'th dport @P_smoketest_port1', 'return'], + ['ip saddr @N_smoketest_network1', 'th dport @P_smoketest_port1', 'accept'], ['elements = { 172.16.99.0/24, 172.16.101.0/24 }'], ['elements = { 53, 123 }'] ] @@ -202,61 +196,75 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): mss_range = '501-1460' conn_mark = '555' - self.cli_set(['firewall', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'source', 'address', '172.16.20.10']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'destination', 'address', '172.16.10.10']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'log', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'log-options', 'level', 'debug']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'ttl', 'eq', '15']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'action', 'reject']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'protocol', 'tcp']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'destination', 'port', '8888']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'log', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'log-options', 'level', 'err']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'tcp', 'flags', 'syn']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'tcp', 'flags', 'not', 'ack']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'ttl', 'gt', '102']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'protocol', 'tcp']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'destination', 'port', '22']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'limit', 'rate', '5/minute']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'log', 'disable']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'action', 'drop']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'protocol', 'tcp']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'destination', 'port', '22']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'recent', 'count', '10']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'recent', 'time', 'minute']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'packet-type', 'host']) - self.cli_set(['firewall', 'name', name, 'rule', '5', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '5', 'protocol', 'tcp']) - self.cli_set(['firewall', 'name', name, 'rule', '5', 'tcp', 'flags', 'syn']) - self.cli_set(['firewall', 'name', name, 'rule', '5', 'tcp', 'mss', mss_range]) - self.cli_set(['firewall', 'name', name, 'rule', '5', 'packet-type', 'broadcast']) - self.cli_set(['firewall', 'name', name, 'rule', '5', 'inbound-interface', 'interface-name', interface]) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'action', 'return']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'protocol', 'gre']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'outbound-interface', 'interface-name', interface]) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'connection-mark', conn_mark]) - - self.cli_set(['firewall', 'interface', interface, 'in', 'name', name]) - self.cli_set(['firewall', 'interface', interface_wc, 'in', 'name', name]) + self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'source', 'address', '172.16.20.10']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'destination', 'address', '172.16.10.10']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'log', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'log-options', 'level', 'debug']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'ttl', 'eq', '15']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'action', 'reject']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'destination', 'port', '8888']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'log', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'log-options', 'level', 'err']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'tcp', 'flags', 'syn']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'tcp', 'flags', 'not', 'ack']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'ttl', 'gt', '102']) + + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'default-action', 'drop']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'destination', 'port', '22']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'limit', 'rate', '5/minute']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'log', 'disable']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'action', 'drop']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'destination', 'port', '22']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'recent', 'count', '10']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'recent', 'time', 'minute']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'packet-type', 'host']) + + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'tcp', 'flags', 'syn']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'tcp', 'mss', mss_range]) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'packet-type', 'broadcast']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'inbound-interface', 'interface-name', interface]) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '6', 'action', 'return']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '6', 'protocol', 'gre']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '6', 'connection-mark', conn_mark]) + + self.cli_set(['firewall', 'ip', 'output', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '5', 'action', 'drop']) + self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '5', 'protocol', 'gre']) + self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '5', 'outbound-interface', 'interface-name', interface_wc]) + self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '6', 'action', 'return']) + self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '6', 'protocol', 'icmp']) + self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '6', 'connection-mark', conn_mark]) self.cli_commit() mark_hex = "{0:#010x}".format(int(conn_mark)) nftables_search = [ - [f'iifname "{interface}"', f'jump NAME_{name}'], - [f'iifname "{interface_wc}"', f'jump NAME_{name}'], - ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[smoketest-1-A]" log level debug', 'ip ttl 15', 'return'], + ['chain VYOS_FORWARD_filter'], + ['type filter hook forward priority filter; policy drop;'], + ['tcp dport 22', 'limit rate 5/minute', 'accept'], + ['tcp dport 22', 'add @RECENT_FWD_filter_4 { ip saddr limit rate over 10/minute burst 10 packets }', 'meta pkttype host', 'drop'], + ['chain VYOS_INPUT_filter'], + ['type filter hook input priority filter; policy drop;'], + ['tcp flags & syn == syn', f'tcp option maxseg size {mss_range}', f'iifname "{interface}"', 'meta pkttype broadcast', 'accept'], + ['meta l4proto gre', f'ct mark {mark_hex}', 'return'], + ['chain VYOS_OUTPUT_filter'], + ['type filter hook output priority filter; policy accept;'], + ['meta l4proto gre', f'oifname "{interface_wc}"', 'drop'], + ['meta l4proto icmp', f'ct mark {mark_hex}', 'return'], + ['chain NAME_smoketest'], + ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'], ['tcp flags syn / syn,ack', 'tcp dport 8888', 'log prefix "[smoketest-2-R]" log level err', 'ip ttl > 102', 'reject'], - ['tcp dport 22', 'limit rate 5/minute', 'return'], - ['log prefix "[smoketest-default-D]"','smoketest default-action', 'drop'], - ['tcp dport 22', 'add @RECENT_smoketest_4 { ip saddr limit rate over 10/minute burst 10 packets }', 'meta pkttype host', 'drop'], - ['tcp flags & syn == syn', f'tcp option maxseg size {mss_range}', f'iifname "{interface}"', 'meta pkttype broadcast'], - ['meta l4proto gre', f'oifname "{interface}"', f'ct mark {mark_hex}', 'return'] + ['log prefix "[smoketest-default-D]"','smoketest default-action', 'drop'] ] self.verify_nftables(nftables_search, 'ip vyos_filter') @@ -266,55 +274,54 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name2 = 'smoketest-adv2' interface = 'eth0' - self.cli_set(['firewall', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'name', name, 'enable-default-log']) - - self.cli_set(['firewall', 'name', name, 'rule', '6', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '64']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '512']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '1024']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'dscp', '17']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'dscp', '52']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'log', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'log-options', 'group', '66']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'log-options', 'snapshot-length', '6666']) - self.cli_set(['firewall', 'name', name, 'rule', '6', 'log-options', 'queue-threshold','32000']) - - self.cli_set(['firewall', 'name', name, 'rule', '7', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '7', 'packet-length', '1-30000']) - self.cli_set(['firewall', 'name', name, 'rule', '7', 'packet-length-exclude', '60000-65535']) - self.cli_set(['firewall', 'name', name, 'rule', '7', 'dscp', '3-11']) - self.cli_set(['firewall', 'name', name, 'rule', '7', 'dscp-exclude', '21-25']) - - self.cli_set(['firewall', 'name', name2, 'default-action', 'jump']) - self.cli_set(['firewall', 'name', name2, 'default-jump-target', name]) - self.cli_set(['firewall', 'name', name2, 'enable-default-log']) - self.cli_set(['firewall', 'name', name2, 'rule', '1', 'source', 'address', '198.51.100.1']) - self.cli_set(['firewall', 'name', name2, 'rule', '1', 'action', 'jump']) - self.cli_set(['firewall', 'name', name2, 'rule', '1', 'jump-target', name]) - - self.cli_set(['firewall', 'name', name2, 'rule', '2', 'protocol', 'tcp']) - self.cli_set(['firewall', 'name', name2, 'rule', '2', 'action', 'queue']) - self.cli_set(['firewall', 'name', name2, 'rule', '2', 'queue', '3']) - self.cli_set(['firewall', 'name', name2, 'rule', '3', 'protocol', 'udp']) - self.cli_set(['firewall', 'name', name2, 'rule', '3', 'action', 'queue']) - self.cli_set(['firewall', 'name', name2, 'rule', '3', 'queue-options', 'fanout']) - self.cli_set(['firewall', 'name', name2, 'rule', '3', 'queue-options', 'bypass']) - self.cli_set(['firewall', 'name', name2, 'rule', '3', 'queue', '0-15']) - - self.cli_set(['firewall', 'interface', interface, 'in', 'name', name]) + self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', name, 'enable-default-log']) + + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'packet-length', '64']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'packet-length', '512']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'packet-length', '1024']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'dscp', '17']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'dscp', '52']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log-options', 'group', '66']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log-options', 'snapshot-length', '6666']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log-options', 'queue-threshold','32000']) + + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'packet-length', '1-30000']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'packet-length-exclude', '60000-65535']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'dscp', '3-11']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'dscp-exclude', '21-25']) + + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'source', 'address', '198.51.100.1']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'action', 'jump']) + self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'jump-target', name]) + + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '2', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '2', 'action', 'queue']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '2', 'queue', '3']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'protocol', 'udp']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'action', 'queue']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'queue-options', 'fanout']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'queue-options', 'bypass']) + self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'queue', '0-15']) self.cli_commit() nftables_search = [ - [f'iifname "{interface}"', f'jump NAME_{name}'], - ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'return'], - ['ip length 1-30000', 'ip length != 60000-65535', 'ip dscp 0x03-0x0b', 'ip dscp != 0x15-0x19', 'return'], - [f'log prefix "[{name}-default-D]"', 'drop'], + ['chain VYOS_FORWARD_filter'], + ['type filter hook forward priority filter; policy accept;'], ['ip saddr 198.51.100.1', f'jump NAME_{name}'], - [f'log prefix "[{name2}-default-J]"', f'jump NAME_{name}'], + ['chain VYOS_INPUT_filter'], + ['type filter hook input priority filter; policy drop;'], [f'meta l4proto tcp','queue to 3'], - [f'meta l4proto udp','queue flags bypass,fanout to 0-15'] + [f'meta l4proto udp','queue flags bypass,fanout to 0-15'], + [f'chain NAME_{name}'], + ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'accept'], + ['ip length 1-30000', 'ip length != 60000-65535', 'ip dscp 0x03-0x0b', 'ip dscp != 0x15-0x19', 'accept'], + [f'log prefix "[{name}-default-D]"', 'drop'] ] self.verify_nftables(nftables_search, 'ip vyos_filter') @@ -325,22 +332,20 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'address-group', 'mask_group', 'address', '1.1.1.1']) - self.cli_set(['firewall', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'action', 'drop']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'destination', 'address', '0.0.1.2']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'destination', 'address-mask', '0.0.255.255']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'destination', 'address', '0.0.1.2']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'destination', 'address-mask', '0.0.255.255']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'source', 'address', '!0.0.3.4']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'source', 'address-mask', '0.0.255.255']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'source', 'address', '!0.0.3.4']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'source', 'address-mask', '0.0.255.255']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'action', 'drop']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'source', 'address-mask', '0.0.255.255']) - - self.cli_set(['firewall', 'interface', interface, 'in', 'name', name]) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'source', 'address-mask', '0.0.255.255']) self.cli_commit() @@ -357,34 +362,46 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name = 'v6-smoketest' interface = 'eth0' - self.cli_set(['firewall', 'ipv6-name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6-name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'source', 'address', '2002::1']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '2002::1:1']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'log', 'enable']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'log-options', 'level', 'crit']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'source', 'address', '2002::1']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '2002::1:1']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'log', 'enable']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'log-options', 'level', 'crit']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'action', 'reject']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'protocol', 'tcp_udp']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'destination', 'port', '8888']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'inbound-interface', 'interface-name', interface]) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'action', 'reject']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'protocol', 'tcp_udp']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'destination', 'port', '8888']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'inbound-interface', 'interface-name', interface]) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'action', 'return']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'protocol', 'gre']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'outbound-interface', 'interface-name', interface]) + self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'action', 'return']) + self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'protocol', 'gre']) + self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'outbound-interface', 'interface-name', interface]) - self.cli_set(['firewall', 'interface', interface, 'in', 'ipv6-name', name]) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'protocol', 'udp']) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'source', 'address', '2002::1:2']) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '3', 'inbound-interface', 'interface-name', interface]) self.cli_commit() nftables_search = [ - [f'iifname "{interface}"', f'jump NAME6_{name}'], - ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[v6-smoketest-1-A]" log level crit', 'return'], + ['chain VYOS_IPV6_FORWARD_filter'], + ['type filter hook forward priority filter; policy accept;'], ['meta l4proto { tcp, udp }', 'th dport 8888', f'iifname "{interface}"', 'reject'], + ['chain VYOS_IPV6_INPUT_filter'], + ['type filter hook input priority filter; policy drop;'], + ['meta l4proto udp', 'ip6 saddr 2002::1:2', f'iifname "{interface}"', 'accept'], + ['chain VYOS_IPV6_OUTPUT_filter'], + ['type filter hook output priority filter; policy drop;'], ['meta l4proto gre', f'oifname "{interface}"', 'return'], - ['smoketest default-action', f'log prefix "[{name}-default-D]"', 'drop'] + [f'chain NAME6_{name}'], + ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[v6-smoketest-1-A]" log level crit', 'accept'], + [f'"{name} default-action drop"', f'log prefix "[{name}-default-D]"', 'drop'] ] self.verify_nftables(nftables_search, 'ip6 vyos_filter') @@ -394,40 +411,39 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name2 = 'v6-smoketest-adv2' interface = 'eth0' - self.cli_set(['firewall', 'ipv6-name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6-name', name, 'enable-default-log']) - - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '65']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '513']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '1025']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'dscp', '18']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'dscp', '53']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'packet-length', '1-1999']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'packet-length-exclude', '60000-65535']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'dscp', '4-14']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'dscp-exclude', '31-35']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'packet-length', '65']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'packet-length', '513']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'packet-length', '1025']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'dscp', '18']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'dscp', '53']) - self.cli_set(['firewall', 'ipv6-name', name2, 'default-action', 'jump']) - self.cli_set(['firewall', 'ipv6-name', name2, 'default-jump-target', name]) - self.cli_set(['firewall', 'ipv6-name', name2, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6-name', name2, 'rule', '1', 'source', 'address', '2001:db8::/64']) - self.cli_set(['firewall', 'ipv6-name', name2, 'rule', '1', 'action', 'jump']) - self.cli_set(['firewall', 'ipv6-name', name2, 'rule', '1', 'jump-target', name]) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'packet-length', '1-1999']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'packet-length-exclude', '60000-65535']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'dscp', '4-14']) + self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'dscp-exclude', '31-35']) - self.cli_set(['firewall', 'interface', interface, 'in', 'ipv6-name', name]) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'source', 'address', '2001:db8::/64']) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'action', 'jump']) + self.cli_set(['firewall', 'ipv6', 'input', 'filter', 'rule', '1', 'jump-target', name]) self.cli_commit() nftables_search = [ - [f'iifname "{interface}"', f'jump NAME6_{name}'], - ['ip6 length { 65, 513, 1025 }', 'ip6 dscp { af21, 0x35 }', 'return'], - ['ip6 length 1-1999', 'ip6 length != 60000-65535', 'ip6 dscp 0x04-0x0e', 'ip6 dscp != 0x1f-0x23', 'return'], - [f'log prefix "[{name}-default-D]"', 'drop'], + ['chain VYOS_IPV6_FORWARD_filter'], + ['type filter hook forward priority filter; policy drop;'], + ['ip6 length 1-1999', 'ip6 length != 60000-65535', 'ip6 dscp 0x04-0x0e', 'ip6 dscp != 0x1f-0x23', 'accept'], + ['chain VYOS_IPV6_INPUT_filter'], + ['type filter hook input priority filter; policy accept;'], ['ip6 saddr 2001:db8::/64', f'jump NAME6_{name}'], - [f'log prefix "[{name2}-default-J]"', f'jump NAME6_{name}'] + [f'chain NAME6_{name}'], + ['ip6 length { 65, 513, 1025 }', 'ip6 dscp { af21, 0x35 }', 'accept'], + [f'log prefix "[{name}-default-D]"', 'drop'] ] self.verify_nftables(nftables_search, 'ip6 vyos_filter') @@ -438,22 +454,20 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'ipv6-address-group', 'mask_group', 'address', '::beef']) - self.cli_set(['firewall', 'ipv6-name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6-name', name, 'enable-default-log']) - - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'action', 'drop']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '::1111:2222:3333:4444']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'destination', 'address-mask', '::ffff:ffff:ffff:ffff']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'source', 'address', '!::aaaa:bbbb:cccc:dddd']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '::1111:2222:3333:4444']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'destination', 'address-mask', '::ffff:ffff:ffff:ffff']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'action', 'drop']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) - self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '2', 'source', 'address', '!::aaaa:bbbb:cccc:dddd']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '2', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) - self.cli_set(['firewall', 'interface', interface, 'in', 'ipv6-name', name]) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) + self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) self.cli_commit() @@ -465,52 +479,32 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.verify_nftables(nftables_search, 'ip6 vyos_filter') - def test_state_policy(self): - self.cli_set(['firewall', 'state-policy', 'established', 'action', 'accept']) - self.cli_set(['firewall', 'state-policy', 'related', 'action', 'accept']) - self.cli_set(['firewall', 'state-policy', 'invalid', 'action', 'drop']) - - self.cli_commit() - - chains = { - 'ip vyos_filter': ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL'], - 'ip6 vyos_filter': ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL'] - } - - for table in ['ip vyos_filter', 'ip6 vyos_filter']: - for chain in chains[table]: - nftables_output = cmd(f'sudo nft list chain {table} {chain}') - self.assertTrue('jump VYOS_STATE_POLICY' in nftables_output) - def test_ipv4_state_and_status_rules(self): name = 'smoketest-state' interface = 'eth0' - self.cli_set(['firewall', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'state', 'established', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '1', 'state', 'related', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'action', 'reject']) - self.cli_set(['firewall', 'name', name, 'rule', '2', 'state', 'invalid', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '3', 'state', 'new', 'enable']) - - self.cli_set(['firewall', 'name', name, 'rule', '3', 'connection-status', 'nat', 'destination']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'action', 'accept']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'state', 'new', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'state', 'established', 'enable']) - self.cli_set(['firewall', 'name', name, 'rule', '4', 'connection-status', 'nat', 'source']) - - self.cli_set(['firewall', 'interface', interface, 'in', 'name', name]) + self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'state', 'established', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'state', 'related', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'action', 'reject']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'state', 'invalid', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'state', 'new', 'enable']) + + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'connection-status', 'nat', 'destination']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'action', 'accept']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'state', 'new', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'state', 'established', 'enable']) + self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'connection-status', 'nat', 'source']) self.cli_commit() nftables_search = [ - [f'iifname "{interface}"', f'jump NAME_{name}'], - ['ct state { established, related }', 'return'], + ['ct state { established, related }', 'accept'], ['ct state invalid', 'reject'], - ['ct state new', 'ct status dnat', 'return'], - ['ct state { established, new }', 'ct status snat', 'return'], + ['ct state new', 'ct status dnat', 'accept'], + ['ct state { established, new }', 'ct status snat', 'accept'], ['drop', f'comment "{name} default-action drop"'] ] @@ -534,7 +528,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.assertNotEqual(f.read().strip(), conf['default'], msg=path) def test_zone_basic(self): - self.cli_set(['firewall', 'name', 'smoketest', 'default-action', 'drop']) + self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'default-action', 'drop']) self.cli_set(['firewall', 'zone', 'smoketest-eth0', 'interface', 'eth0']) self.cli_set(['firewall', 'zone', 'smoketest-eth0', 'from', 'smoketest-local', 'firewall', 'name', 'smoketest']) self.cli_set(['firewall', 'zone', 'smoketest-local', 'local-zone']) diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11 new file mode 100755 index 000000000..b2880afac --- /dev/null +++ b/src/migration-scripts/firewall/10-to-11 @@ -0,0 +1,373 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2023 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 . + +# T5160: Firewall re-writing + +# cli changes from: +# set firewall name ... +# set firewall ipv6-name ... +# To +# set firewall ip name +# set firewall ipv6 ipv6-name + +## Also from 'firewall interface' removed. +## in and out: + # set firewall interface [in|out] [name | ipv6-name] + # To + # set firewall [ip | ipv6] forward filter rule <5,10,15,...> [inbound-interface | outboubd-interface] interface-name + # set firewall [ip | ipv6] forward filter rule <5,10,15,...> action jump + # set firewall [ip | ipv6] forward filter rule <5,10,15,...> jump-target +## local: + # set firewall interface local [name | ipv6-name] + # To + # set firewall [ip | ipv6] input filter rule <5,10,15,...> inbound-interface interface-name + # set firewall [ip | ipv6] input filter rule <5,10,15,...> action jump + # set firewall [ip | ipv6] input filter rule <5,10,15,...> jump-target + +import re + +from sys import argv +from sys import exit + +from vyos.configtree import ConfigTree +from vyos.ifconfig import Section + +if (len(argv) < 1): + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +base = ['firewall'] +config = ConfigTree(config_file) + +if not config.exists(base): + # Nothing to do + exit(0) + +### Migration of state policies +if config.exists(base + ['state-policy']): + for family in ['ip', 'ipv6']: + for hook in ['forward', 'input', 'output']: + for priority in ['filter']: + # Add default-action== accept for compatibility reasons: + config.set(base + [family, hook, priority, 'default-action'], value='accept') + position = 1 + for state in config.list_nodes(base + ['state-policy']): + action = config.return_value(base + ['state-policy', state, 'action']) + config.set(base + [family, hook, priority, 'rule']) + config.set_tag(base + [family, hook, priority, 'rule']) + config.set(base + [family, hook, priority, 'rule', position, 'state', state], value='enable') + config.set(base + [family, hook, priority, 'rule', position, 'action'], value=action) + position = position + 1 + config.delete(base + ['state-policy']) +############ + +## migration of global options: +for option in ['all-ping', 'broadcast-ping', 'config-trap', 'ip-src-route', 'ipv6-receive-redirects', 'ipv6-src-route', 'log-martians', + 'receive-redirects', 'resolver-cache', 'resolver-internal', 'send-redirects', 'source-validation', 'syn-cookies', 'twa-hazards-protection']: + if config.exists(base + [option]): + val = config.return_value(base + [option]) + config.set(base + ['global-options', option], value=val) + config.delete(base + [option]) + +### Migration of firewall name and ipv6-name +if config.exists(base + ['name']): + config.set(['firewall', 'ip', 'name']) + config.set_tag(['firewall', 'ip', 'name']) + + for ipv4name in config.list_nodes(base + ['name']): + config.copy(base + ['name', ipv4name], base + ['ip', 'name', ipv4name]) + config.delete(base + ['name']) + +if config.exists(base + ['ipv6-name']): + config.set(['firewall', 'ipv6', 'ipv6-name']) + config.set_tag(['firewall', 'ipv6', 'ipv6-name']) + + for ipv6name in config.list_nodes(base + ['ipv6-name']): + config.copy(base + ['ipv6-name', ipv6name], base + ['ipv6', 'ipv6-name', ipv6name]) + config.delete(base + ['ipv6-name']) + +### Migration of firewall interface +if config.exists(base + ['interface']): + fwd_ipv4_rule = 5 + inp_ipv4_rule = 5 + fwd_ipv6_rule = 5 + inp_ipv6_rule = 5 + for iface in config.list_nodes(base + ['interface']): + for direction in ['in', 'out', 'local']: + if config.exists(base + ['interface', iface, direction]): + if config.exists(base + ['interface', iface, direction, 'name']): + target = config.return_value(base + ['interface', iface, direction, 'name']) + if direction == 'in': + # Add default-action== accept for compatibility reasons: + config.set(base + ['ip', 'forward', 'filter', 'default-action'], value='accept') + new_base = base + ['ip', 'forward', 'filter', 'rule'] + config.set(new_base) + config.set_tag(new_base) + config.set(new_base + [fwd_ipv4_rule, 'inbound-interface', 'interface-name'], value=iface) + config.set(new_base + [fwd_ipv4_rule, 'action'], value='jump') + config.set(new_base + [fwd_ipv4_rule, 'jump-target'], value=target) + fwd_ipv4_rule = fwd_ipv4_rule + 5 + elif direction == 'out': + # Add default-action== accept for compatibility reasons: + config.set(base + ['ip', 'forward', 'filter', 'default-action'], value='accept') + new_base = base + ['ip', 'forward', 'filter', 'rule'] + config.set(new_base) + config.set_tag(new_base) + config.set(new_base + [fwd_ipv4_rule, 'outbound-interface', 'interface-name'], value=iface) + config.set(new_base + [fwd_ipv4_rule, 'action'], value='jump') + config.set(new_base + [fwd_ipv4_rule, 'jump-target'], value=target) + fwd_ipv4_rule = fwd_ipv4_rule + 5 + else: + # Add default-action== accept for compatibility reasons: + config.set(base + ['ip', 'input', 'filter', 'default-action'], value='accept') + new_base = base + ['ip', 'input', 'filter', 'rule'] + config.set(new_base) + config.set_tag(new_base) + config.set(new_base + [inp_ipv4_rule, 'inbound-interface', 'interface-name'], value=iface) + config.set(new_base + [inp_ipv4_rule, 'action'], value='jump') + config.set(new_base + [inp_ipv4_rule, 'jump-target'], value=target) + inp_ipv4_rule = inp_ipv4_rule + 5 + + if config.exists(base + ['interface', iface, direction, 'ipv6-name']): + target = config.return_value(base + ['interface', iface, direction, 'ipv6-name']) + if direction == 'in': + # Add default-action== accept for compatibility reasons: + config.set(base + ['ipv6', 'forward', 'filter', 'default-action'], value='accept') + new_base = base + ['ipv6', 'forward', 'filter', 'rule'] + config.set(new_base) + config.set_tag(new_base) + config.set(new_base + [fwd_ipv6_rule, 'inbound-interface', 'interface-name'], value=iface) + config.set(new_base + [fwd_ipv6_rule, 'action'], value='jump') + config.set(new_base + [fwd_ipv6_rule, 'jump-target'], value=target) + fwd_ipv6_rule = fwd_ipv6_rule + 5 + elif direction == 'out': + # Add default-action== accept for compatibility reasons: + config.set(base + ['ipv6', 'forward', 'filter', 'default-action'], value='accept') + new_base = base + ['ipv6', 'forward', 'filter', 'rule'] + config.set(new_base) + config.set_tag(new_base) + config.set(new_base + [fwd_ipv6_rule, 'outbound-interface', 'interface-name'], value=iface) + config.set(new_base + [fwd_ipv6_rule, 'action'], value='jump') + config.set(new_base + [fwd_ipv6_rule, 'jump-target'], value=target) + fwd_ipv6_rule = fwd_ipv6_rule + 5 + else: + new_base = base + ['ipv6', 'input', 'filter', 'rule'] + # Add default-action== accept for compatibility reasons: + config.set(base + ['ipv6', 'input', 'filter', 'default-action'], value='accept') + config.set(new_base) + config.set_tag(new_base) + config.set(new_base + [inp_ipv6_rule, 'inbound-interface', 'interface-name'], value=iface) + config.set(new_base + [inp_ipv6_rule, 'action'], value='jump') + config.set(new_base + [inp_ipv6_rule, 'jump-target'], value=target) + inp_ipv6_rule = inp_ipv6_rule + 5 + + config.delete(base + ['interface']) + + +### Migration of zones config v2: +### User interface groups +if config.exists(base + ['zone']): + inp_ipv4_rule = 101 + inp_ipv6_rule = 101 + fwd_ipv4_rule = 101 + fwd_ipv6_rule = 101 + out_ipv4_rule = 101 + out_ipv6_rule = 101 + local_zone = 'False' + + for zone in config.list_nodes(base + ['zone']): + if config.exists(base + ['zone', zone, 'local-zone']): + local_zone = 'True' + # Add default-action== accept for compatibility reasons: + config.set(base + ['ip', 'input', 'filter', 'default-action'], value='accept') + config.set(base + ['ipv6', 'input', 'filter', 'default-action'], value='accept') + config.set(base + ['ip', 'output', 'filter', 'default-action'], value='accept') + config.set(base + ['ipv6', 'output', 'filter', 'default-action'], value='accept') + for from_zone in config.list_nodes(base + ['zone', zone, 'from']): + group_name = 'IG_' + from_zone + if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']): + # ipv4 input ruleset + target_ipv4_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']) + config.set(base + ['ip', 'input', 'filter', 'rule']) + config.set_tag(base + ['ip', 'input', 'filter', 'rule']) + config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'action'], value='jump') + config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'jump-target'], value=target_ipv4_chain) + inp_ipv4_rule = inp_ipv4_rule + 5 + if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']): + # ipv6 input ruleset + target_ipv6_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']) + config.set(base + ['ipv6', 'input', 'filter', 'rule']) + config.set_tag(base + ['ipv6', 'input', 'filter', 'rule']) + config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'inbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'action'], value='jump') + config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'jump-target'], value=target_ipv6_chain) + inp_ipv6_rule = inp_ipv6_rule + 5 + + # Migrate: set firewall zone default-action + # Options: drop or reject. If not specified, is drop + if config.exists(base + ['zone', zone, 'default-action']): + local_def_action = config.return_value(base + ['zone', zone, 'default-action']) + else: + local_def_action = 'drop' + config.set(base + ['ip', 'input', 'filter', 'rule']) + config.set_tag(base + ['ip', 'input', 'filter', 'rule']) + config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'action'], value=local_def_action) + config.set(base + ['ipv6', 'input', 'filter', 'rule']) + config.set_tag(base + ['ipv6', 'input', 'filter', 'rule']) + config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'action'], value=local_def_action) + if config.exists(base + ['zone', zone, 'enable-default-log']): + config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'log'], value='enable') + config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'log'], value='enable') + + else: + # It's not a local zone + group_name = 'IG_' + zone + # Add default-action== accept for compatibility reasons: + config.set(base + ['ip', 'forward', 'filter', 'default-action'], value='accept') + config.set(base + ['ipv6', 'forward', 'filter', 'default-action'], value='accept') + # intra-filtering migration. By default accept + intra_zone_ipv4_action = 'accept' + intra_zone_ipv6_action = 'accept' + + if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'action']): + intra_zone_ipv4_action = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'action']) + intra_zone_ipv6_action = intra_zone_ipv4_action + else: + if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'name']): + intra_zone_ipv4_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'name']) + intra_zone_ipv4_action = 'jump' + if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']): + intra_zone_ipv6_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']) + intra_zone_ipv6_action = 'jump' + config.set(base + ['ip', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ip', 'forward', 'filter', 'rule']) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=intra_zone_ipv4_action) + config.set_tag(base + ['ipv6', 'forward', 'filter', 'rule']) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'inbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'action'], value=intra_zone_ipv6_action) + if intra_zone_ipv4_action == 'jump': + if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'name']): + intra_zone_ipv4_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'name']) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'jump-target'], value=intra_zone_ipv4_target) + if intra_zone_ipv6_action == 'jump': + if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']): + intra_zone_ipv6_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'jump-target'], value=intra_zone_ipv6_target) + fwd_ipv4_rule = fwd_ipv4_rule + 5 + fwd_ipv6_rule = fwd_ipv6_rule + 5 + + if config.exists(base + ['zone', zone, 'interface']): + # Create interface group IG_ + group_name = 'IG_' + zone + config.set(base + ['group', 'interface-group'], value=group_name) + config.set_tag(base + ['group', 'interface-group']) + for iface in config.return_values(base + ['zone', zone, 'interface']): + config.set(base + ['group', 'interface-group', group_name, 'interface'], value=iface, replace=False) + + if config.exists(base + ['zone', zone, 'from']): + for from_zone in config.list_nodes(base + ['zone', zone, 'from']): + from_group = 'IG_' + from_zone + if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']): + target_ipv4_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']) + if config.exists(base + ['zone', from_zone, 'local-zone']): + # It's from LOCAL zone -> Output filtering + config.set(base + ['ip', 'output', 'filter', 'rule']) + config.set_tag(base + ['ip', 'output', 'filter', 'rule']) + config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'action'], value='jump') + config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'jump-target'], value=target_ipv4_chain) + out_ipv4_rule = out_ipv4_rule + 5 + else: + # It's not LOCAL zone -> forward filtering + config.set(base + ['ip', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ip', 'forward', 'filter', 'rule']) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=from_group) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value='jump') + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'jump-target'], value=target_ipv4_chain) + fwd_ipv4_rule = fwd_ipv4_rule + 5 + if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']): + target_ipv6_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']) + if config.exists(base + ['zone', from_zone, 'local-zone']): + # It's from LOCAL zone -> Output filtering + config.set(base + ['ipv6', 'output', 'filter', 'rule']) + config.set_tag(base + ['ipv6', 'output', 'filter', 'rule']) + config.set(base + ['ipv6', 'output', 'filter', 'rule', out_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv6', 'output', 'filter', 'rule', out_ipv6_rule, 'action'], value='jump') + config.set(base + ['ipv6', 'output', 'filter', 'rule', out_ipv6_rule, 'jump-target'], value=target_ipv6_chain) + out_ipv6_rule = out_ipv6_rule + 5 + else: + # It's not LOCAL zone -> forward filtering + config.set(base + ['ipv6', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ipv6', 'forward', 'filter', 'rule']) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'inbound-interface', 'interface-group'], value=from_group) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'action'], value='jump') + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'jump-target'], value=target_ipv6_chain) + fwd_ipv6_rule = fwd_ipv6_rule + 5 + + ## Now need to migrate: set firewall zone default-action # action=drop if not specified. + if config.exists(base + ['zone', zone, 'default-action']): + def_action = config.return_value(base + ['zone', zone, 'default-action']) + else: + def_action = 'drop' + config.set(base + ['ip', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ip', 'forward', 'filter', 'rule']) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=def_action) + description = 'zone_' + zone + ' default-action' + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'description'], value=description) + config.set(base + ['ipv6', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ipv6', 'forward', 'filter', 'rule']) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'action'], value=def_action) + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'description'], value=description) + + if config.exists(base + ['zone', zone, 'enable-default-log']): + config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'log'], value='enable') + config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'log'], value='enable') + fwd_ipv4_rule = fwd_ipv4_rule + 5 + fwd_ipv6_rule = fwd_ipv6_rule + 5 + + # Migrate default-action (force to be drop in output chain) if local zone is defined + if local_zone == 'True': + # General drop in output change if needed + config.set(base + ['ip', 'output', 'filter', 'rule']) + config.set_tag(base + ['ip', 'output', 'filter', 'rule']) + config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'action'], value=local_def_action) + config.set(base + ['ipv6', 'output', 'filter', 'rule']) + config.set_tag(base + ['ipv6', 'output', 'filter', 'rule']) + config.set(base + ['ipv6', 'output', 'filter', 'rule', out_ipv6_rule, 'action'], value=local_def_action) + + config.delete(base + ['zone']) + +###### END migration zones v2 + +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 -- cgit v1.2.3 From dbf7501d0c75cd626170f53e93f7ddd4d6a67584 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Tue, 23 May 2023 16:00:48 -0300 Subject: T5160: firewall refactor: re-add missing code in template.py which was accidentaly removed. Update smokestest: remove zone test and fix test_sysfs test --- python/vyos/template.py | 1 + smoketest/scripts/cli/test_firewall.py | 32 +------------------------------- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/python/vyos/template.py b/python/vyos/template.py index 5a3505b91..e167488c6 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -44,6 +44,7 @@ def _get_environment(location=None): loader=loc_loader, trim_blocks=True, undefined=ChainableUndefined, + extensions=['jinja2.ext.loopcontrols'] ) env.filters.update(_FILTERS) env.tests.update(_TESTS) diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 153793453..640b7971c 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -517,7 +517,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): with open(path, 'r') as f: self.assertEqual(f.read().strip(), conf['default'], msg=path) - self.cli_set(['firewall', name.replace("_", "-"), conf['test_value']]) + self.cli_set(['firewall', 'global-options', name.replace("_", "-"), conf['test_value']]) self.cli_commit() @@ -527,35 +527,5 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): with open(path, 'r') as f: self.assertNotEqual(f.read().strip(), conf['default'], msg=path) - def test_zone_basic(self): - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'default-action', 'drop']) - self.cli_set(['firewall', 'zone', 'smoketest-eth0', 'interface', 'eth0']) - self.cli_set(['firewall', 'zone', 'smoketest-eth0', 'from', 'smoketest-local', 'firewall', 'name', 'smoketest']) - self.cli_set(['firewall', 'zone', 'smoketest-local', 'local-zone']) - self.cli_set(['firewall', 'zone', 'smoketest-local', 'from', 'smoketest-eth0', 'firewall', 'name', 'smoketest']) - - self.cli_commit() - - nftables_search = [ - ['chain VZONE_smoketest-eth0'], - ['chain VZONE_smoketest-local_IN'], - ['chain VZONE_smoketest-local_OUT'], - ['oifname "eth0"', 'jump VZONE_smoketest-eth0'], - ['jump VZONE_smoketest-local_IN'], - ['jump VZONE_smoketest-local_OUT'], - ['iifname "eth0"', 'jump NAME_smoketest'], - ['oifname "eth0"', 'jump NAME_smoketest'] - ] - - nftables_output = cmd('sudo nft list table ip vyos_filter') - - for search in nftables_search: - matched = False - for line in nftables_output.split("\n"): - if all(item in line for item in search): - matched = True - break - self.assertTrue(matched) - if __name__ == '__main__': unittest.main(verbosity=2) -- cgit v1.2.3 From 342db936a02a02ba04867f932137638485ef0a6f Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Mon, 29 May 2023 18:48:12 +0000 Subject: T5160: firewall refactor. Update op-mode commands to new syntax. --- op-mode-definitions/firewall.xml.in | 204 ++++++++++++++++++++++++++++++++---- src/op_mode/firewall.py | 186 +++++++++++++++----------------- 2 files changed, 267 insertions(+), 123 deletions(-) diff --git a/op-mode-definitions/firewall.xml.in b/op-mode-definitions/firewall.xml.in index b5dee7c9e..b29e93f5e 100644 --- a/op-mode-definitions/firewall.xml.in +++ b/op-mode-definitions/firewall.xml.in @@ -131,46 +131,206 @@ sudo ${vyos_op_scripts_dir}/firewall.py --action show_group - + - Show IPv6 firewall chains - - firewall ipv6-name - + Show IPv6 firewall - + + + Show IPv6 forward firewall ruleset + + + + + Show IPv6 forward filter firewall ruleset + + + + + Show summary of IPv6 forward filter firewall rules + + firewall ipv6 forward filter rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 --ipv6 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --ipv6 + + + + + + Show IPv6 input firewall ruleset + + + + + Show IPv6 forward input firewall ruleset + + + + + Show summary of IPv6 input filter firewall rules + + firewall ipv6 input filter rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 --ipv6 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --ipv6 + + + + + + Show IPv6 output firewall ruleset + + + + + Show IPv6 output filter firewall ruleset + + + + + Show summary of IPv6 output filter firewall rules + + firewall ipv6 output filter rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 --ipv6 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --ipv6 + + + + - Show summary of IPv6 firewall rules + Show IPv6 custom firewall chains - firewall ipv6-name ${COMP_WORDS[6]} rule + firewall ipv6 ipv6-name - sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --rule $6 --ipv6 + + + + Show summary of IPv6 custom firewall ruleset + + firewall ipv6 ipv6-name ${COMP_WORDS[6]} rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 --ipv6 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --ipv6 - sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --ipv6 - - + sudo ${vyos_op_scripts_dir}/firewall.py --action show_family --family $3 + + - Show IPv4 firewall chains - - firewall name - + Show IPv4 firewall - + + + Show IPv4 forward firewall ruleset + + + + + Show IPv4 forward filter firewall ruleset + + + + + Show summary of IPv4 forward filter firewall rules + + firewall ip forward filter rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 + + + + + + Show IPv4 input firewall ruleset + + + + + Show IPv4 forward input firewall ruleset + + + + + Show summary of IPv4 input filter firewall rules + + firewall ip input filter rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 + + + + + + Show IPv4 output firewall ruleset + + + + + Show IPv4 output filter firewall ruleset + + + + + Show summary of IPv4 output filter firewall rules + + firewall ip output filter rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 + + + + - Show summary of IPv4 firewall rules + Show IPv4 custom firewall chains - firewall name ${COMP_WORDS[6]} rule + firewall ip name - sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 --rule $6 + + + + Show summary of IPv4 custom firewall ruleset + + firewall ip name ${COMP_WORDS[6]} rule + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 + + + sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 - sudo ${vyos_op_scripts_dir}/firewall.py --action show --name $4 - + sudo ${vyos_op_scripts_dir}/firewall.py --action show_family --family $3 + Show statistics of firewall application diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py index 8260bbb77..8eb883f81 100755 --- a/src/op_mode/firewall.py +++ b/src/op_mode/firewall.py @@ -24,62 +24,27 @@ from vyos.config import Config from vyos.utils.process import cmd from vyos.utils.dict import dict_search_args -def get_firewall_interfaces(firewall, name=None, ipv6=False): - directions = ['in', 'out', 'local'] - - if 'interface' in firewall: - for ifname, if_conf in firewall['interface'].items(): - for direction in directions: - if direction not in if_conf: - continue - - fw_conf = if_conf[direction] - name_str = f'({ifname},{direction})' - - if 'name' in fw_conf: - fw_name = fw_conf['name'] - - if not name: - firewall['name'][fw_name]['interface'].append(name_str) - elif not ipv6 and name == fw_name: - firewall['interface'].append(name_str) - - if 'ipv6_name' in fw_conf: - fw_name = fw_conf['ipv6_name'] - - if not name: - firewall['ipv6_name'][fw_name]['interface'].append(name_str) - elif ipv6 and name == fw_name: - firewall['interface'].append(name_str) - - return firewall - -def get_config_firewall(conf, name=None, ipv6=False, interfaces=True): +def get_config_firewall(conf, hook=None, priority=None, ipv6=False, interfaces=True): config_path = ['firewall'] - if name: - config_path += ['ipv6-name' if ipv6 else 'name', name] + if hook: + config_path += ['ipv6' if ipv6 else 'ip', hook] + if priority: + config_path += [priority] firewall = conf.get_config_dict(config_path, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) - if firewall and interfaces: - if name: - firewall['interface'] = {} - else: - if 'name' in firewall: - for fw_name, name_conf in firewall['name'].items(): - name_conf['interface'] = [] - - if 'ipv6_name' in firewall: - for fw_name, name_conf in firewall['ipv6_name'].items(): - name_conf['interface'] = [] - get_firewall_interfaces(firewall, name, ipv6) return firewall -def get_nftables_details(name, ipv6=False): +def get_nftables_details(hook, priority, ipv6=False): suffix = '6' if ipv6 else '' name_prefix = 'NAME6_' if ipv6 else 'NAME_' - command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{name}' + if hook == 'name' or hook == 'ipv6-name': + command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{priority}' + else: + up_hook = hook.upper() + command = f'sudo nft list chain ip{suffix} vyos_filter VYOS_{up_hook}_{priority}' + try: results = cmd(command) except: @@ -87,7 +52,7 @@ def get_nftables_details(name, ipv6=False): out = {} for line in results.split('\n'): - comment_search = re.search(rf'{name}[\- ](\d+|default-action)', line) + comment_search = re.search(rf'{priority}[\- ](\d+|default-action)', line) if not comment_search: continue @@ -102,18 +67,15 @@ def get_nftables_details(name, ipv6=False): out[rule_id] = rule return out -def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None): +def output_firewall_name(hook, priority, firewall_conf, ipv6=False, single_rule_id=None): ip_str = 'IPv6' if ipv6 else 'IPv4' - print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n') - - if name_conf['interface']: - print('Active on: {0}\n'.format(" ".join(name_conf['interface']))) + print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {priority}"\n') - details = get_nftables_details(name, ipv6) + details = get_nftables_details(hook, priority, ipv6) rows = [] - if 'rule' in name_conf: - for rule_id, rule_conf in name_conf['rule'].items(): + if 'rule' in firewall_conf: + for rule_id, rule_conf in firewall_conf['rule'].items(): if single_rule_id and rule_id != single_rule_id: continue @@ -128,8 +90,8 @@ def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None): row.append(rule_details['conditions']) rows.append(row) - if 'default_action' in name_conf and not single_rule_id: - row = ['default', name_conf['default_action'], 'all'] + if 'default_action' in firewall_conf and not single_rule_id: + row = ['default', firewall_conf['default_action'], 'all'] if 'default-action' in details: rule_details = details['default-action'] row.append(rule_details.get('packets', 0)) @@ -140,18 +102,15 @@ def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None): header = ['Rule', 'Action', 'Protocol', 'Packets', 'Bytes', 'Conditions'] print(tabulate.tabulate(rows, header) + '\n') -def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id=None): +def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_rule_id=None): ip_str = 'IPv6' if ipv6 else 'IPv4' - print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n') - - if name_conf['interface']: - print('Active on: {0}\n'.format(" ".join(name_conf['interface']))) + print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {prior}"\n') - details = get_nftables_details(name, ipv6) + details = get_nftables_details(prior, ipv6) rows = [] - if 'rule' in name_conf: - for rule_id, rule_conf in name_conf['rule'].items(): + if 'rule' in prior_conf: + for rule_id, rule_conf in prior_conf['rule'].items(): if single_rule_id and rule_id != single_rule_id: continue @@ -174,7 +133,7 @@ def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id= row.append(dest_addr) rows.append(row) - if 'default_action' in name_conf and not single_rule_id: + if 'default_action' in prior_conf and not single_rule_id: row = ['default'] if 'default-action' in details: rule_details = details['default-action'] @@ -183,7 +142,7 @@ def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id= else: row.append('0') row.append('0') - row.append(name_conf['default_action']) + row.append(prior_conf['default_action']) row.append('0.0.0.0/0') # Source row.append('0.0.0.0/0') # Dest rows.append(row) @@ -201,29 +160,47 @@ def show_firewall(): if not firewall: return - if 'name' in firewall: - for name, name_conf in firewall['name'].items(): - output_firewall_name(name, name_conf, ipv6=False) + if 'ip' in firewall: + for hook, hook_conf in firewall['ip'].items(): + for prior, prior_conf in firewall['ip'][hook].items(): + output_firewall_name(hook, prior, prior_conf, ipv6=False) + + if 'ipv6' in firewall: + for hook, hook_conf in firewall['ipv6'].items(): + for prior, prior_conf in firewall['ipv6'][hook].items(): + output_firewall_name(hook, prior, prior_conf, ipv6=True) + +def show_firewall_family(family): + print(f'Rulesets {family} Information') + + conf = Config() + firewall = get_config_firewall(conf) + + if not firewall: + return - if 'ipv6_name' in firewall: - for name, name_conf in firewall['ipv6_name'].items(): - output_firewall_name(name, name_conf, ipv6=True) + for hook, hook_conf in firewall[family].items(): + for prior, prior_conf in firewall[family][hook].items(): + if family == 'ipv6': + output_firewall_name(hook, prior, prior_conf, ipv6=True) + else: + output_firewall_name(hook, prior, prior_conf, ipv6=False) -def show_firewall_name(name, ipv6=False): +def show_firewall_name(hook, priority, ipv6=False): print('Ruleset Information') conf = Config() - firewall = get_config_firewall(conf, name, ipv6) + firewall = get_config_firewall(conf, hook, priority, ipv6) if firewall: - output_firewall_name(name, firewall, ipv6) + output_firewall_name(hook, priority, firewall, ipv6) -def show_firewall_rule(name, rule_id, ipv6=False): +def show_firewall_rule(hook, priority, rule_id, ipv6=False): print('Rule Information') conf = Config() - firewall = get_config_firewall(conf, name, ipv6) + firewall = get_config_firewall(conf, hook, priority, ipv6) if firewall: - output_firewall_name(name, firewall, ipv6, rule_id) + output_firewall_name(hook, priority, firewall, ipv6, rule_id) def show_firewall_group(name=None): conf = Config() @@ -284,28 +261,28 @@ def show_summary(): if not firewall: return - header = ['Ruleset Name', 'Description', 'References'] + header = ['Ruleset Hook', 'Ruleset Priority', 'Description', 'References'] v4_out = [] v6_out = [] - if 'name' in firewall: - for name, name_conf in firewall['name'].items(): - description = name_conf.get('description', '') - interfaces = ", ".join(name_conf['interface']) - v4_out.append([name, description, interfaces]) + if 'ip' in firewall: + for hook, hook_conf in firewall['ip'].items(): + for prior, prior_conf in firewall['ip'][hook].items(): + description = prior_conf.get('description', '') + v4_out.append([hook, prior, description]) - if 'ipv6_name' in firewall: - for name, name_conf in firewall['ipv6_name'].items(): - description = name_conf.get('description', '') - interfaces = ", ".join(name_conf['interface']) - v6_out.append([name, description, interfaces or 'N/A']) + if 'ipv6' in firewall: + for hook, hook_conf in firewall['ipv6'].items(): + for prior, prior_conf in firewall['ipv6'][hook].items(): + description = prior_conf.get('description', '') + v6_out.append([hook, prior, description]) if v6_out: - print('\nIPv6 name:\n') + print('\nIPv6 Ruleset:\n') print(tabulate.tabulate(v6_out, header) + '\n') if v4_out: - print('\nIPv4 name:\n') + print('\nIPv4 Ruleset:\n') print(tabulate.tabulate(v4_out, header) + '\n') show_firewall_group() @@ -319,18 +296,23 @@ def show_statistics(): if not firewall: return - if 'name' in firewall: - for name, name_conf in firewall['name'].items(): - output_firewall_name_statistics(name, name_conf, ipv6=False) + if 'ip' in firewall: + for hook, hook_conf in firewall['ip'].items(): + for prior, prior_conf in firewall['ip'][hook].items(): + output_firewall_name_statistics(hook,prior, prior_conf, ipv6=False) - if 'ipv6_name' in firewall: - for name, name_conf in firewall['ipv6_name'].items(): - output_firewall_name_statistics(name, name_conf, ipv6=True) + if 'ipv6' in firewall: + for hook, hook_conf in firewall['ipv6'].items(): + for prior, prior_conf in firewall['ipv6'][hook].items(): + output_firewall_name_statistics(hook,prior, prior_conf, ipv6=True) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--action', help='Action', required=False) parser.add_argument('--name', help='Firewall name', required=False, action='store', nargs='?', default='') + parser.add_argument('--family', help='IP family', required=False, action='store', nargs='?', default='') + parser.add_argument('--hook', help='Firewall hook', required=False, action='store', nargs='?', default='') + parser.add_argument('--priority', help='Firewall priority', required=False, action='store', nargs='?', default='') parser.add_argument('--rule', help='Firewall Rule ID', required=False) parser.add_argument('--ipv6', help='IPv6 toggle', action='store_true') @@ -338,11 +320,13 @@ if __name__ == '__main__': if args.action == 'show': if not args.rule: - show_firewall_name(args.name, args.ipv6) + show_firewall_name(args.hook, args.priority, args.ipv6) else: - show_firewall_rule(args.name, args.rule, args.ipv6) + show_firewall_rule(args.hook, args.priority, args.rule, args.ipv6) elif args.action == 'show_all': show_firewall() + elif args.action == 'show_family': + show_firewall_family(args.family) elif args.action == 'show_group': show_firewall_group(args.name) elif args.action == 'show_statistics': -- cgit v1.2.3 From 68d14fe80145542ffd08a5f7d5cde6c090a0de07 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Wed, 31 May 2023 15:07:42 +0000 Subject: T5160: firewall refactor: change firewall ip to firewall ipv4 --- data/templates/firewall/nftables.j2 | 30 +-- interface-definitions/firewall.xml.in | 2 +- .../include/firewall/ipv4-custom-name.xml.i | 6 +- .../include/firewall/ipv4-hook-forward.xml.i | 4 +- .../include/firewall/ipv4-hook-input.xml.i | 4 +- .../include/firewall/ipv4-hook-output.xml.i | 4 +- .../include/firewall/ipv4-hook-prerouting.xml.i | 10 +- op-mode-definitions/firewall.xml.in | 12 +- python/vyos/firewall.py | 4 +- smoketest/scripts/cli/test_firewall.py | 254 ++++++++++----------- src/conf_mode/firewall.py | 53 ++++- src/migration-scripts/firewall/10-to-11 | 110 ++++----- src/op_mode/firewall.py | 20 +- 13 files changed, 273 insertions(+), 240 deletions(-) diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index dcfe71a58..98ceebaa5 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -1,16 +1,15 @@ #!/usr/sbin/nft -f {% import 'firewall/nftables-defines.j2' as group_tmpl %} -{% import 'firewall/nftables-zone.j2' as zone_tmpl %} {% if first_install is not vyos_defined %} delete table ip vyos_filter {% endif %} table ip vyos_filter { -{% if ip is vyos_defined %} -{% if ip.forward is vyos_defined %} +{% if ipv4 is vyos_defined %} +{% if ipv4.forward is vyos_defined %} {% set ns = namespace(sets=[]) %} -{% for prior, conf in ip.forward.items() %} +{% for prior, conf in ipv4.forward.items() %} {% set def_action = conf.default_action %} chain VYOS_FORWARD_{{ prior }} { type filter hook forward priority {{ prior }}; policy {{ def_action }}; @@ -33,9 +32,9 @@ table ip vyos_filter { {% endfor %} {% endif %} -{% if ip.input is vyos_defined %} +{% if ipv4.input is vyos_defined %} {% set ns = namespace(sets=[]) %} -{% for prior, conf in ip.input.items() %} +{% for prior, conf in ipv4.input.items() %} {% set def_action = conf.default_action %} chain VYOS_INPUT_{{ prior }} { type filter hook input priority {{ prior }}; policy {{ def_action }}; @@ -58,9 +57,9 @@ table ip vyos_filter { {% endfor %} {% endif %} -{% if ip.output is vyos_defined %} +{% if ipv4.output is vyos_defined %} {% set ns = namespace(sets=[]) %} -{% for prior, conf in ip.output.items() %} +{% for prior, conf in ipv4.output.items() %} {% set def_action = conf.default_action %} chain VYOS_OUTPUT_{{ prior }} { type filter hook output priority {{ prior }}; policy {{ def_action }}; @@ -87,9 +86,9 @@ table ip vyos_filter { type filter hook prerouting priority -450; policy accept; ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return } -{% if ip.prerouting is vyos_defined %} +{% if ipv4.prerouting is vyos_defined %} {% set ns = namespace(sets=[]) %} -{% for prior, conf in ip.prerouting.items() %} +{% for prior, conf in ipv4.prerouting.items() %} chain VYOS_PREROUTING_{{ prior }} { type filter hook prerouting priority {{ prior }}; policy accept; {% if conf.rule is vyos_defined %} @@ -112,9 +111,9 @@ table ip vyos_filter { } {% endfor %} {% endif %} -{% if ip.name is vyos_defined %} +{% if ipv4.name is vyos_defined %} {% set ns = namespace(sets=[]) %} -{% for name_text, conf in ip.name.items() %} +{% for name_text, conf in ipv4.name.items() %} chain NAME_{{ name_text }} { {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} @@ -152,10 +151,6 @@ table ip vyos_filter { {% endif %} {{ group_tmpl.groups(group, False) }} - -{% if zone is vyos_defined %} -{{ zone_tmpl.zone_chains(zone, state_policy is vyos_defined, False) }} -{% endif %} } {% if first_install is not vyos_defined %} @@ -283,7 +278,4 @@ table ip6 vyos_filter { {{ group_tmpl.groups(group, True) }} -{% if zone is vyos_defined %} -{{ zone_tmpl.zone_chains(zone, state_policy is vyos_defined, True) }} -{% endif %} } \ No newline at end of file diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 9b36f92e8..127f4b7e7 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -284,7 +284,7 @@ - + IPv4 firewall diff --git a/interface-definitions/include/firewall/ipv4-custom-name.xml.i b/interface-definitions/include/firewall/ipv4-custom-name.xml.i index b2f8271f7..7fd802f3b 100644 --- a/interface-definitions/include/firewall/ipv4-custom-name.xml.i +++ b/interface-definitions/include/firewall/ipv4-custom-name.xml.i @@ -14,13 +14,13 @@ Set jump target. Action jump must be defined in default-action to use this setting - firewall ip name + firewall ipv4 name - IP Firewall custom rule number + IPv4 Firewall custom rule number u32:1-999999 Number for this firewall rule @@ -38,7 +38,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ip name + firewall ipv4 name diff --git a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i index 6179afe31..beb9df64e 100644 --- a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i @@ -13,7 +13,7 @@ #include - IP Firewall forward filter rule number + IPv4 Firewall forward filter rule number u32:1-999999 Number for this firewall rule @@ -31,7 +31,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ip name + firewall ipv4 name diff --git a/interface-definitions/include/firewall/ipv4-hook-input.xml.i b/interface-definitions/include/firewall/ipv4-hook-input.xml.i index f9746378b..1a2e1399f 100644 --- a/interface-definitions/include/firewall/ipv4-hook-input.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-input.xml.i @@ -13,7 +13,7 @@ #include - IP Firewall input filter rule number + IPv4 Firewall input filter rule number u32:1-999999 Number for this firewall rule @@ -30,7 +30,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ip name + firewall ipv4 name diff --git a/interface-definitions/include/firewall/ipv4-hook-output.xml.i b/interface-definitions/include/firewall/ipv4-hook-output.xml.i index a1820f314..e870e2b79 100644 --- a/interface-definitions/include/firewall/ipv4-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-output.xml.i @@ -13,7 +13,7 @@ #include - IP Firewall output filter rule number + IPv4 Firewall output filter rule number u32:1-999999 Number for this firewall rule @@ -30,7 +30,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ip name + firewall ipv4 name diff --git a/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i b/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i index 229a25ef4..c38918375 100644 --- a/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i @@ -13,7 +13,7 @@ #include - IP Firewall prerouting filter rule number + IPv4 Firewall prerouting filter rule number u32:1-999999 Number for this firewall rule @@ -30,7 +30,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ip name + firewall ipv4 name @@ -49,13 +49,13 @@ Set jump target. Action jump must be defined in default-action to use this setting - firewall ip name + firewall ipv4 name - IP Firewall prerouting raw rule number + IPv4 Firewall prerouting raw rule number u32:1-999999 Number for this firewall rule @@ -72,7 +72,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ip name + firewall ipv4 name diff --git a/op-mode-definitions/firewall.xml.in b/op-mode-definitions/firewall.xml.in index b29e93f5e..164ce6b60 100644 --- a/op-mode-definitions/firewall.xml.in +++ b/op-mode-definitions/firewall.xml.in @@ -231,7 +231,7 @@ sudo ${vyos_op_scripts_dir}/firewall.py --action show_family --family $3 - + Show IPv4 firewall @@ -250,7 +250,7 @@ Show summary of IPv4 forward filter firewall rules - firewall ip forward filter rule + firewall ipv4 forward filter rule sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 @@ -274,7 +274,7 @@ Show summary of IPv4 input filter firewall rules - firewall ip input filter rule + firewall ipv4 input filter rule sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 @@ -298,7 +298,7 @@ Show summary of IPv4 output filter firewall rules - firewall ip output filter rule + firewall ipv4 output filter rule sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 @@ -312,7 +312,7 @@ Show IPv4 custom firewall chains - firewall ip name + firewall ipv4 name @@ -320,7 +320,7 @@ Show summary of IPv4 custom firewall ruleset - firewall ip name ${COMP_WORDS[6]} rule + firewall ipv4 name ${COMP_WORDS[6]} rule sudo ${vyos_op_scripts_dir}/firewall.py --action show --hook $4 --priority $5 --rule $7 diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 86a324062..bb32556af 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -49,7 +49,7 @@ def fqdn_config_parse(firewall): suffix = path[5][0] set_name = f'{hook_name}_{priority}_{rule}_{suffix}' - if (path[0] == 'ip') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'): + if (path[0] == 'ipv4') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'): firewall['ip_fqdn'][set_name] = domain elif (path[0] == 'ipv6') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name'): if path[1] == 'ipv6_name': @@ -521,7 +521,7 @@ def geoip_update(firewall, force=False): set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' if path[1] == 'ipv6_name': set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' - if ( path[0] == 'ip' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): + if ( path[0] == 'ipv4' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): for code in codes: ipv4_codes.setdefault(code, []).append(set_name) elif ( path[0] == 'ipv6' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 640b7971c..7a7628873 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -90,13 +90,13 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): return False def test_geoip(self): - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'se']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'gb']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'de']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'fr']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'inverse-match']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'se']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'source', 'geoip', 'country-code', 'gb']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'de']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'country-code', 'fr']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '2', 'source', 'geoip', 'inverse-match']) self.cli_commit() @@ -127,17 +127,17 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'interface-group', 'smoketest_interface', 'interface', 'eth0']) self.cli_set(['firewall', 'group', 'interface-group', 'smoketest_interface', 'interface', 'vtun0']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'destination', 'address', '172.16.10.10']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'protocol', 'tcp_udp']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '2', 'source', 'group', 'mac-group', 'smoketest_mac']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'source', 'group', 'domain-group', 'smoketest_domain']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'outbound-interface', 'interface-group', 'smoketest_interface']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'destination', 'address', '172.16.10.10']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'protocol', 'tcp_udp']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '2', 'source', 'group', 'mac-group', 'smoketest_mac']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'source', 'group', 'domain-group', 'smoketest_domain']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'outbound-interface', 'interface-group', 'smoketest_interface']) self.cli_commit() @@ -167,10 +167,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '53']) self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port1', 'port', '123']) self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port1', 'include', 'smoketest_port']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network1']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port1']) - self.cli_set(['firewall', 'ip', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network1']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'destination', 'group', 'port-group', 'smoketest_port1']) + self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'rule', '1', 'protocol', 'tcp_udp']) self.cli_commit() @@ -196,53 +196,53 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): mss_range = '501-1460' conn_mark = '555' - self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'source', 'address', '172.16.20.10']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'destination', 'address', '172.16.10.10']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'log', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'log-options', 'level', 'debug']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'ttl', 'eq', '15']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'action', 'reject']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'protocol', 'tcp']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'destination', 'port', '8888']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'log', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'log-options', 'level', 'err']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'tcp', 'flags', 'syn']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'tcp', 'flags', 'not', 'ack']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'ttl', 'gt', '102']) - - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'default-action', 'drop']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'protocol', 'tcp']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'destination', 'port', '22']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'limit', 'rate', '5/minute']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '3', 'log', 'disable']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'action', 'drop']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'protocol', 'tcp']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'destination', 'port', '22']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'recent', 'count', '10']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'recent', 'time', 'minute']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '4', 'packet-type', 'host']) - - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'protocol', 'tcp']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'tcp', 'flags', 'syn']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'tcp', 'mss', mss_range]) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'packet-type', 'broadcast']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '5', 'inbound-interface', 'interface-name', interface]) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '6', 'action', 'return']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '6', 'protocol', 'gre']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '6', 'connection-mark', conn_mark]) - - self.cli_set(['firewall', 'ip', 'output', 'filter', 'default-action', 'accept']) - self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '5', 'action', 'drop']) - self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '5', 'protocol', 'gre']) - self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '5', 'outbound-interface', 'interface-name', interface_wc]) - self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '6', 'action', 'return']) - self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '6', 'protocol', 'icmp']) - self.cli_set(['firewall', 'ip', 'output', 'filter', 'rule', '6', 'connection-mark', conn_mark]) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'source', 'address', '172.16.20.10']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'destination', 'address', '172.16.10.10']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'log', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'log-options', 'level', 'debug']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'ttl', 'eq', '15']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'action', 'reject']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'destination', 'port', '8888']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'log', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'log-options', 'level', 'err']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'tcp', 'flags', 'syn']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'tcp', 'flags', 'not', 'ack']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'ttl', 'gt', '102']) + + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'destination', 'port', '22']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'limit', 'rate', '5/minute']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '3', 'log', 'disable']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'destination', 'port', '22']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'recent', 'count', '10']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'recent', 'time', 'minute']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '4', 'packet-type', 'host']) + + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'tcp', 'flags', 'syn']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'tcp', 'mss', mss_range]) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'packet-type', 'broadcast']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '5', 'inbound-interface', 'interface-name', interface]) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'action', 'return']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'protocol', 'gre']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '6', 'connection-mark', conn_mark]) + + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'protocol', 'gre']) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '5', 'outbound-interface', 'interface-name', interface_wc]) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '6', 'action', 'return']) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '6', 'protocol', 'icmp']) + self.cli_set(['firewall', 'ipv4', 'output', 'filter', 'rule', '6', 'connection-mark', conn_mark]) self.cli_commit() @@ -274,39 +274,39 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name2 = 'smoketest-adv2' interface = 'eth0' - self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', name, 'enable-default-log']) - - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'packet-length', '64']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'packet-length', '512']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'packet-length', '1024']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'dscp', '17']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'dscp', '52']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log-options', 'group', '66']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log-options', 'snapshot-length', '6666']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '6', 'log-options', 'queue-threshold','32000']) - - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'packet-length', '1-30000']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'packet-length-exclude', '60000-65535']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'dscp', '3-11']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '7', 'dscp-exclude', '21-25']) - - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'default-action', 'accept']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'source', 'address', '198.51.100.1']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'action', 'jump']) - self.cli_set(['firewall', 'ip', 'forward', 'filter', 'rule', '1', 'jump-target', name]) - - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '2', 'protocol', 'tcp']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '2', 'action', 'queue']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '2', 'queue', '3']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'protocol', 'udp']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'action', 'queue']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'queue-options', 'fanout']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'queue-options', 'bypass']) - self.cli_set(['firewall', 'ip', 'input', 'filter', 'rule', '3', 'queue', '0-15']) + self.cli_set(['firewall', 'ip4', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ip4', 'name', name, 'enable-default-log']) + + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'packet-length', '64']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'packet-length', '512']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'packet-length', '1024']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'dscp', '17']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'dscp', '52']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'log', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'log-options', 'group', '66']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'log-options', 'snapshot-length', '6666']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'log-options', 'queue-threshold','32000']) + + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'packet-length', '1-30000']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'packet-length-exclude', '60000-65535']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'dscp', '3-11']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'dscp-exclude', '21-25']) + + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'source', 'address', '198.51.100.1']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'action', 'jump']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'jump-target', name]) + + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'action', 'queue']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '2', 'queue', '3']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'protocol', 'udp']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'action', 'queue']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'queue-options', 'fanout']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'queue-options', 'bypass']) + self.cli_set(['firewall', 'ipv4', 'input', 'filter', 'rule', '3', 'queue', '0-15']) self.cli_commit() @@ -332,20 +332,20 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'address-group', 'mask_group', 'address', '1.1.1.1']) - self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'destination', 'address', '0.0.1.2']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'destination', 'address-mask', '0.0.255.255']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'destination', 'address', '0.0.1.2']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'destination', 'address-mask', '0.0.255.255']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'source', 'address', '!0.0.3.4']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'source', 'address-mask', '0.0.255.255']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'source', 'address', '!0.0.3.4']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'source', 'address-mask', '0.0.255.255']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'source', 'address-mask', '0.0.255.255']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'source', 'address-mask', '0.0.255.255']) self.cli_commit() @@ -483,20 +483,20 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name = 'smoketest-state' interface = 'eth0' - self.cli_set(['firewall', 'ip', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'state', 'established', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '1', 'state', 'related', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'action', 'reject']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '2', 'state', 'invalid', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'state', 'new', 'enable']) - - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '3', 'connection-status', 'nat', 'destination']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'action', 'accept']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'state', 'new', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'state', 'established', 'enable']) - self.cli_set(['firewall', 'ip', 'name', name, 'rule', '4', 'connection-status', 'nat', 'source']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'state', 'established', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '1', 'state', 'related', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'action', 'reject']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '2', 'state', 'invalid', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'state', 'new', 'enable']) + + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '3', 'connection-status', 'nat', 'destination']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'state', 'new', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'state', 'established', 'enable']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '4', 'connection-status', 'nat', 'source']) self.cli_commit() diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 4c5341e22..a50ae2ec6 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -101,7 +101,7 @@ def geoip_updated(conf, firewall): if path[1] == 'ipv6_name': set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' - if (path[0] == 'ip') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): + if (path[0] == 'ipv4') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): out['name'].append(set_name) elif (path[0] == 'ipv6') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): out['ipv6_name'].append(set_name) @@ -133,6 +133,47 @@ def get_config(config=None): get_first_key=True, with_recursive_defaults=True) + # We have gathered the dict representation of the CLI, but there are + # default options which we need to update into the dictionary retrived. + # XXX: T2665: we currently have no nice way for defaults under tag + # nodes, thus we load the defaults "by hand" + default_values = defaults(base) + + for family in ['ipv4', 'ipv6']: + for tmp in ['name', 'ipv6_name', 'forward', 'input', 'output', 'prerouting']: + if tmp in default_values[family]: + del default_values[family][tmp] + + + firewall = dict_merge(default_values, firewall) + + # Merge in defaults for IPv4 ruleset + if 'name' in firewall['ipv4']: + default_values = defaults(base + ['ipv4'] + ['name']) + for name in firewall['ipv4']['name']: + firewall['ipv4']['name'][name] = dict_merge(default_values, + firewall['ipv4']['name'][name]) + for hook in ['forward', 'input', 'output', 'prerouting']: + if hook in firewall['ipv4']: + for priority in ['filter', 'mangle', 'raw']: + if priority in firewall['ipv4'][hook]: + default_values = defaults(base + ['ipv4'] + [hook] + [priority]) + firewall['ipv4'][hook][priority] = dict_merge(default_values, + firewall['ipv4'][hook][priority]) + + # Merge in defaults for IPv6 ruleset + if 'ipv6_name' in firewall['ipv6']: + default_values = defaults(base + ['ipv6'] + ['ipv6-name']) + for ipv6_name in firewall['ipv6']['ipv6_name']: + firewall['ipv6']['ipv6_name'][ipv6_name] = dict_merge(default_values, + firewall['ipv6']['ipv6_name'][ipv6_name]) + for hook in ['forward', 'input', 'output', 'prerouting']: + if hook in firewall['ipv6']: + for priority in ['filter', 'mangle', 'raw']: + if priority in firewall['ipv6'][hook]: + default_values = defaults(base + ['ipv6'] + [hook] + [priority]) + firewall['ipv6'][hook][priority] = dict_merge(default_values, + firewall['ipv6'][hook][priority]) firewall['group_resync'] = bool('group' in firewall or node_changed(conf, base + ['group'])) if firewall['group_resync']: @@ -165,7 +206,7 @@ def verify_rule(firewall, rule_conf, ipv6): raise ConfigError('jump-target defined, but action jump needed and it is not defined') target = rule_conf['jump_target'] if not ipv6: - if target not in dict_search_args(firewall, 'ip', 'name'): + if target not in dict_search_args(firewall, 'ipv4', 'name'): raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') else: if target not in dict_search_args(firewall, 'ipv6', 'ipv6_name'): @@ -297,10 +338,10 @@ def verify(firewall): for group_name, group in groups.items(): verify_nested_group(group_name, group, groups, []) - if 'ip' in firewall: + if 'ipv4' in firewall: for name in ['name','forward','input','output']: - if name in firewall['ip']: - for name_id, name_conf in firewall['ip'][name].items(): + if name in firewall['ipv4']: + for name_id, name_conf in firewall['ipv4'][name].items(): if 'jump' in name_conf['default_action'] and 'default_jump_target' not in name_conf: raise ConfigError('default-action set to jump, but no default-jump-target specified') if 'default_jump_target' in name_conf: @@ -310,7 +351,7 @@ def verify(firewall): if name_conf['default_jump_target'] == name_id: raise ConfigError(f'Loop detected on default-jump-target.') ## Now need to check that default-jump-target exists (other firewall chain/name) - if target not in dict_search_args(firewall['ip'], 'name'): + if target not in dict_search_args(firewall['ipv4'], 'name'): raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') if 'rule' in name_conf: diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11 index b2880afac..9dad86b62 100755 --- a/src/migration-scripts/firewall/10-to-11 +++ b/src/migration-scripts/firewall/10-to-11 @@ -20,22 +20,22 @@ # set firewall name ... # set firewall ipv6-name ... # To -# set firewall ip name +# set firewall ipv4 name # set firewall ipv6 ipv6-name ## Also from 'firewall interface' removed. ## in and out: # set firewall interface [in|out] [name | ipv6-name] # To - # set firewall [ip | ipv6] forward filter rule <5,10,15,...> [inbound-interface | outboubd-interface] interface-name - # set firewall [ip | ipv6] forward filter rule <5,10,15,...> action jump - # set firewall [ip | ipv6] forward filter rule <5,10,15,...> jump-target + # set firewall [ipv4 | ipv6] forward filter rule <5,10,15,...> [inbound-interface | outboubd-interface] interface-name + # set firewall [ipv4 | ipv6] forward filter rule <5,10,15,...> action jump + # set firewall [ipv4 | ipv6] forward filter rule <5,10,15,...> jump-target ## local: # set firewall interface local [name | ipv6-name] # To - # set firewall [ip | ipv6] input filter rule <5,10,15,...> inbound-interface interface-name - # set firewall [ip | ipv6] input filter rule <5,10,15,...> action jump - # set firewall [ip | ipv6] input filter rule <5,10,15,...> jump-target + # set firewall [ipv4 | ipv6] input filter rule <5,10,15,...> inbound-interface interface-name + # set firewall [ipv4 | ipv6] input filter rule <5,10,15,...> action jump + # set firewall [ipv4 | ipv6] input filter rule <5,10,15,...> jump-target import re @@ -63,7 +63,7 @@ if not config.exists(base): ### Migration of state policies if config.exists(base + ['state-policy']): - for family in ['ip', 'ipv6']: + for family in ['ipv4', 'ipv6']: for hook in ['forward', 'input', 'output']: for priority in ['filter']: # Add default-action== accept for compatibility reasons: @@ -89,11 +89,11 @@ for option in ['all-ping', 'broadcast-ping', 'config-trap', 'ip-src-route', 'ipv ### Migration of firewall name and ipv6-name if config.exists(base + ['name']): - config.set(['firewall', 'ip', 'name']) - config.set_tag(['firewall', 'ip', 'name']) + config.set(['firewall', 'ipv4', 'name']) + config.set_tag(['firewall', 'ipv4', 'name']) for ipv4name in config.list_nodes(base + ['name']): - config.copy(base + ['name', ipv4name], base + ['ip', 'name', ipv4name]) + config.copy(base + ['name', ipv4name], base + ['ipv4', 'name', ipv4name]) config.delete(base + ['name']) if config.exists(base + ['ipv6-name']): @@ -117,8 +117,8 @@ if config.exists(base + ['interface']): target = config.return_value(base + ['interface', iface, direction, 'name']) if direction == 'in': # Add default-action== accept for compatibility reasons: - config.set(base + ['ip', 'forward', 'filter', 'default-action'], value='accept') - new_base = base + ['ip', 'forward', 'filter', 'rule'] + config.set(base + ['ipv4', 'forward', 'filter', 'default-action'], value='accept') + new_base = base + ['ipv4', 'forward', 'filter', 'rule'] config.set(new_base) config.set_tag(new_base) config.set(new_base + [fwd_ipv4_rule, 'inbound-interface', 'interface-name'], value=iface) @@ -127,8 +127,8 @@ if config.exists(base + ['interface']): fwd_ipv4_rule = fwd_ipv4_rule + 5 elif direction == 'out': # Add default-action== accept for compatibility reasons: - config.set(base + ['ip', 'forward', 'filter', 'default-action'], value='accept') - new_base = base + ['ip', 'forward', 'filter', 'rule'] + config.set(base + ['ipv4', 'forward', 'filter', 'default-action'], value='accept') + new_base = base + ['ipv4', 'forward', 'filter', 'rule'] config.set(new_base) config.set_tag(new_base) config.set(new_base + [fwd_ipv4_rule, 'outbound-interface', 'interface-name'], value=iface) @@ -137,8 +137,8 @@ if config.exists(base + ['interface']): fwd_ipv4_rule = fwd_ipv4_rule + 5 else: # Add default-action== accept for compatibility reasons: - config.set(base + ['ip', 'input', 'filter', 'default-action'], value='accept') - new_base = base + ['ip', 'input', 'filter', 'rule'] + config.set(base + ['ipv4', 'input', 'filter', 'default-action'], value='accept') + new_base = base + ['ipv4', 'input', 'filter', 'rule'] config.set(new_base) config.set_tag(new_base) config.set(new_base + [inp_ipv4_rule, 'inbound-interface', 'interface-name'], value=iface) @@ -197,20 +197,20 @@ if config.exists(base + ['zone']): if config.exists(base + ['zone', zone, 'local-zone']): local_zone = 'True' # Add default-action== accept for compatibility reasons: - config.set(base + ['ip', 'input', 'filter', 'default-action'], value='accept') + config.set(base + ['ipv4', 'input', 'filter', 'default-action'], value='accept') config.set(base + ['ipv6', 'input', 'filter', 'default-action'], value='accept') - config.set(base + ['ip', 'output', 'filter', 'default-action'], value='accept') + config.set(base + ['ipv4', 'output', 'filter', 'default-action'], value='accept') config.set(base + ['ipv6', 'output', 'filter', 'default-action'], value='accept') for from_zone in config.list_nodes(base + ['zone', zone, 'from']): group_name = 'IG_' + from_zone if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']): # ipv4 input ruleset target_ipv4_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']) - config.set(base + ['ip', 'input', 'filter', 'rule']) - config.set_tag(base + ['ip', 'input', 'filter', 'rule']) - config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) - config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'action'], value='jump') - config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'jump-target'], value=target_ipv4_chain) + config.set(base + ['ipv4', 'input', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'input', 'filter', 'rule']) + config.set(base + ['ipv4', 'input', 'filter', 'rule', inp_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv4', 'input', 'filter', 'rule', inp_ipv4_rule, 'action'], value='jump') + config.set(base + ['ipv4', 'input', 'filter', 'rule', inp_ipv4_rule, 'jump-target'], value=target_ipv4_chain) inp_ipv4_rule = inp_ipv4_rule + 5 if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']): # ipv6 input ruleset @@ -228,21 +228,21 @@ if config.exists(base + ['zone']): local_def_action = config.return_value(base + ['zone', zone, 'default-action']) else: local_def_action = 'drop' - config.set(base + ['ip', 'input', 'filter', 'rule']) - config.set_tag(base + ['ip', 'input', 'filter', 'rule']) - config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'action'], value=local_def_action) + config.set(base + ['ipv4', 'input', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'input', 'filter', 'rule']) + config.set(base + ['ipv4', 'input', 'filter', 'rule', inp_ipv4_rule, 'action'], value=local_def_action) config.set(base + ['ipv6', 'input', 'filter', 'rule']) config.set_tag(base + ['ipv6', 'input', 'filter', 'rule']) config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'action'], value=local_def_action) if config.exists(base + ['zone', zone, 'enable-default-log']): - config.set(base + ['ip', 'input', 'filter', 'rule', inp_ipv4_rule, 'log'], value='enable') + config.set(base + ['ipv4', 'input', 'filter', 'rule', inp_ipv4_rule, 'log'], value='enable') config.set(base + ['ipv6', 'input', 'filter', 'rule', inp_ipv6_rule, 'log'], value='enable') else: # It's not a local zone group_name = 'IG_' + zone # Add default-action== accept for compatibility reasons: - config.set(base + ['ip', 'forward', 'filter', 'default-action'], value='accept') + config.set(base + ['ipv4', 'forward', 'filter', 'default-action'], value='accept') config.set(base + ['ipv6', 'forward', 'filter', 'default-action'], value='accept') # intra-filtering migration. By default accept intra_zone_ipv4_action = 'accept' @@ -258,11 +258,11 @@ if config.exists(base + ['zone']): if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']): intra_zone_ipv6_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']) intra_zone_ipv6_action = 'jump' - config.set(base + ['ip', 'forward', 'filter', 'rule']) - config.set_tag(base + ['ip', 'forward', 'filter', 'rule']) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=intra_zone_ipv4_action) + config.set(base + ['ipv4', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'forward', 'filter', 'rule']) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=intra_zone_ipv4_action) config.set_tag(base + ['ipv6', 'forward', 'filter', 'rule']) config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'inbound-interface', 'interface-group'], value=group_name) @@ -270,7 +270,7 @@ if config.exists(base + ['zone']): if intra_zone_ipv4_action == 'jump': if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'name']): intra_zone_ipv4_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'name']) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'jump-target'], value=intra_zone_ipv4_target) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'jump-target'], value=intra_zone_ipv4_target) if intra_zone_ipv6_action == 'jump': if config.exists(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']): intra_zone_ipv6_target = config.return_value(base + ['zone', zone, 'intra-zone-filtering', 'firewall', 'ipv6-name']) @@ -293,20 +293,20 @@ if config.exists(base + ['zone']): target_ipv4_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'name']) if config.exists(base + ['zone', from_zone, 'local-zone']): # It's from LOCAL zone -> Output filtering - config.set(base + ['ip', 'output', 'filter', 'rule']) - config.set_tag(base + ['ip', 'output', 'filter', 'rule']) - config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) - config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'action'], value='jump') - config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'jump-target'], value=target_ipv4_chain) + config.set(base + ['ipv4', 'output', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'output', 'filter', 'rule']) + config.set(base + ['ipv4', 'output', 'filter', 'rule', out_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv4', 'output', 'filter', 'rule', out_ipv4_rule, 'action'], value='jump') + config.set(base + ['ipv4', 'output', 'filter', 'rule', out_ipv4_rule, 'jump-target'], value=target_ipv4_chain) out_ipv4_rule = out_ipv4_rule + 5 else: # It's not LOCAL zone -> forward filtering - config.set(base + ['ip', 'forward', 'filter', 'rule']) - config.set_tag(base + ['ip', 'forward', 'filter', 'rule']) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=from_group) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value='jump') - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'jump-target'], value=target_ipv4_chain) + config.set(base + ['ipv4', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'forward', 'filter', 'rule']) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=from_group) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value='jump') + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'jump-target'], value=target_ipv4_chain) fwd_ipv4_rule = fwd_ipv4_rule + 5 if config.exists(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']): target_ipv6_chain = config.return_value(base + ['zone', zone, 'from', from_zone, 'firewall', 'ipv6-name']) @@ -333,12 +333,12 @@ if config.exists(base + ['zone']): def_action = config.return_value(base + ['zone', zone, 'default-action']) else: def_action = 'drop' - config.set(base + ['ip', 'forward', 'filter', 'rule']) - config.set_tag(base + ['ip', 'forward', 'filter', 'rule']) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=def_action) + config.set(base + ['ipv4', 'forward', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'forward', 'filter', 'rule']) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=def_action) description = 'zone_' + zone + ' default-action' - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'description'], value=description) + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'description'], value=description) config.set(base + ['ipv6', 'forward', 'filter', 'rule']) config.set_tag(base + ['ipv6', 'forward', 'filter', 'rule']) config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) @@ -346,7 +346,7 @@ if config.exists(base + ['zone']): config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'description'], value=description) if config.exists(base + ['zone', zone, 'enable-default-log']): - config.set(base + ['ip', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'log'], value='enable') + config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'log'], value='enable') config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'log'], value='enable') fwd_ipv4_rule = fwd_ipv4_rule + 5 fwd_ipv6_rule = fwd_ipv6_rule + 5 @@ -354,9 +354,9 @@ if config.exists(base + ['zone']): # Migrate default-action (force to be drop in output chain) if local zone is defined if local_zone == 'True': # General drop in output change if needed - config.set(base + ['ip', 'output', 'filter', 'rule']) - config.set_tag(base + ['ip', 'output', 'filter', 'rule']) - config.set(base + ['ip', 'output', 'filter', 'rule', out_ipv4_rule, 'action'], value=local_def_action) + config.set(base + ['ipv4', 'output', 'filter', 'rule']) + config.set_tag(base + ['ipv4', 'output', 'filter', 'rule']) + config.set(base + ['ipv4', 'output', 'filter', 'rule', out_ipv4_rule, 'action'], value=local_def_action) config.set(base + ['ipv6', 'output', 'filter', 'rule']) config.set_tag(base + ['ipv6', 'output', 'filter', 'rule']) config.set(base + ['ipv6', 'output', 'filter', 'rule', out_ipv6_rule, 'action'], value=local_def_action) diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py index 8eb883f81..ff7e2f398 100755 --- a/src/op_mode/firewall.py +++ b/src/op_mode/firewall.py @@ -27,7 +27,7 @@ from vyos.utils.dict import dict_search_args def get_config_firewall(conf, hook=None, priority=None, ipv6=False, interfaces=True): config_path = ['firewall'] if hook: - config_path += ['ipv6' if ipv6 else 'ip', hook] + config_path += ['ipv6' if ipv6 else 'ipv4', hook] if priority: config_path += [priority] @@ -160,9 +160,9 @@ def show_firewall(): if not firewall: return - if 'ip' in firewall: - for hook, hook_conf in firewall['ip'].items(): - for prior, prior_conf in firewall['ip'][hook].items(): + if 'ipv4' in firewall: + for hook, hook_conf in firewall['ipv4'].items(): + for prior, prior_conf in firewall['ipv4'][hook].items(): output_firewall_name(hook, prior, prior_conf, ipv6=False) if 'ipv6' in firewall: @@ -265,9 +265,9 @@ def show_summary(): v4_out = [] v6_out = [] - if 'ip' in firewall: - for hook, hook_conf in firewall['ip'].items(): - for prior, prior_conf in firewall['ip'][hook].items(): + if 'ipv4' in firewall: + for hook, hook_conf in firewall['ipv4'].items(): + for prior, prior_conf in firewall['ipv4'][hook].items(): description = prior_conf.get('description', '') v4_out.append([hook, prior, description]) @@ -296,9 +296,9 @@ def show_statistics(): if not firewall: return - if 'ip' in firewall: - for hook, hook_conf in firewall['ip'].items(): - for prior, prior_conf in firewall['ip'][hook].items(): + if 'ipv4' in firewall: + for hook, hook_conf in firewall['ipv4'].items(): + for prior, prior_conf in firewall['ipv4'][hook].items(): output_firewall_name_statistics(hook,prior, prior_conf, ipv6=False) if 'ipv6' in firewall: -- cgit v1.2.3 From d898739b78f4563b3e170684bbc1d248c62553fe Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Wed, 31 May 2023 18:41:53 +0000 Subject: T5160: T5250: while refactoring, fix reference column for op-mode command show_firewall_group. --- src/op_mode/firewall.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py index ff7e2f398..852a7248a 100755 --- a/src/op_mode/firewall.py +++ b/src/op_mode/firewall.py @@ -211,19 +211,32 @@ def show_firewall_group(name=None): def find_references(group_type, group_name): out = [] - for name_type in ['name', 'ipv6_name']: - if name_type not in firewall: - continue - for name, name_conf in firewall[name_type].items(): - if 'rule' not in name_conf: + family = [] + if group_type in ['address_group', 'network_group']: + family = ['ipv4'] + elif group_type == 'ipv6_address_group': + family = ['ipv6'] + group_type = 'address_group' + elif group_type == 'ipv6_network_group': + family = ['ipv6'] + group_type = 'network_group' + else: + family = ['ipv4', 'ipv6'] + + for item in family: + for name_type in ['name', 'ipv6_name', 'forward', 'input', 'output']: + if name_type not in firewall[item]: continue - for rule_id, rule_conf in name_conf['rule'].items(): - source_group = dict_search_args(rule_conf, 'source', 'group', group_type) - dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type) - if source_group and group_name == source_group: - out.append(f'{name}-{rule_id}') - elif dest_group and group_name == dest_group: - out.append(f'{name}-{rule_id}') + for name, name_conf in firewall[item][name_type].items(): + if 'rule' not in name_conf: + continue + for rule_id, rule_conf in name_conf['rule'].items(): + source_group = dict_search_args(rule_conf, 'source', 'group', group_type) + dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type) + if source_group and group_name == source_group: + out.append(f'{name}-{rule_id}') + elif dest_group and group_name == dest_group: + out.append(f'{name}-{rule_id}') return out header = ['Name', 'Type', 'References', 'Members'] -- cgit v1.2.3 From 68694d022d8f63cfeef42430220efc56d4a1433c Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Thu, 1 Jun 2023 12:49:21 +0000 Subject: T5160: firewal refactor: fix tabulation for geo-ip parsing code. Typo fix in firewall smoketest --- python/vyos/firewall.py | 12 ++++++------ smoketest/scripts/cli/test_firewall.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index bb32556af..b028f0af0 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -521,12 +521,12 @@ def geoip_update(firewall, force=False): set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' if path[1] == 'ipv6_name': set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' - if ( path[0] == 'ipv4' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): - for code in codes: - ipv4_codes.setdefault(code, []).append(set_name) - elif ( path[0] == 'ipv6' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): - for code in codes: - ipv6_codes.setdefault(code, []).append(set_name) + if ( path[0] == 'ipv4' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): + for code in codes: + ipv4_codes.setdefault(code, []).append(set_name) + elif ( path[0] == 'ipv6' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): + for code in codes: + ipv6_codes.setdefault(code, []).append(set_name) if not ipv4_codes and not ipv6_codes: if force: diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 7a7628873..bd7666313 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -274,8 +274,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name2 = 'smoketest-adv2' interface = 'eth0' - self.cli_set(['firewall', 'ip4', 'name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ip4', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'name', name, 'enable-default-log']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'action', 'accept']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '6', 'packet-length', '64']) -- cgit v1.2.3 From dbb069151f372ea521fad2edcd83f2d33631e6c7 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Fri, 2 Jun 2023 14:35:26 +0000 Subject: T5160: firewall refactor: fix firewall template for correct rule parsing that contains fqnd and/or geo-ip in base chains. Fix mig script --- data/templates/firewall/nftables.j2 | 112 ++++++++------------------------ src/migration-scripts/firewall/10-to-11 | 1 + 2 files changed, 29 insertions(+), 84 deletions(-) diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index 98ceebaa5..1c70a6b77 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -7,8 +7,8 @@ delete table ip vyos_filter {% endif %} table ip vyos_filter { {% if ipv4 is vyos_defined %} +{% set ns = namespace(sets=[]) %} {% if ipv4.forward is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv4.forward.items() %} {% set def_action = conf.default_action %} chain VYOS_FORWARD_{{ prior }} { @@ -23,17 +23,9 @@ table ip vyos_filter { {% endif %} } {% endfor %} -{% for set_name in ns.sets %} - set RECENT_{{ set_name }} { - type ipv4_addr - size 65535 - flags dynamic - } -{% endfor %} {% endif %} {% if ipv4.input is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv4.input.items() %} {% set def_action = conf.default_action %} chain VYOS_INPUT_{{ prior }} { @@ -48,17 +40,9 @@ table ip vyos_filter { {% endif %} } {% endfor %} -{% for set_name in ns.sets %} - set RECENT_{{ set_name }} { - type ipv4_addr - size 65535 - flags dynamic - } -{% endfor %} {% endif %} {% if ipv4.output is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv4.output.items() %} {% set def_action = conf.default_action %} chain VYOS_OUTPUT_{{ prior }} { @@ -73,24 +57,16 @@ table ip vyos_filter { {% endif %} } {% endfor %} -{% for set_name in ns.sets %} - set RECENT_{{ set_name }} { - type ipv4_addr - size 65535 - flags dynamic - } -{% endfor %} {% endif %} - chain VYOS_FRAG_MARK { type filter hook prerouting priority -450; policy accept; ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return } {% if ipv4.prerouting is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv4.prerouting.items() %} +{% set def_action = conf.default_action %} chain VYOS_PREROUTING_{{ prior }} { - type filter hook prerouting priority {{ prior }}; policy accept; + type filter hook prerouting priority {{ prior }}; policy {{ def_action }}; {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('PRE', prior, rule_id) }} @@ -100,19 +76,11 @@ table ip vyos_filter { {% endfor %} {% endif %} {{ conf | nft_default_rule(prior) }} - # jump VYOS_POST_FW - } -{% endfor %} -{% for set_name in ns.sets %} - set RECENT_{{ set_name }} { - type ipv4_addr - size 65535 - flags dynamic } {% endfor %} {% endif %} + {% if ipv4.name is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for name_text, conf in ipv4.name.items() %} chain NAME_{{ name_text }} { {% if conf.rule is vyos_defined %} @@ -126,30 +94,30 @@ table ip vyos_filter { {{ conf | nft_default_rule(name_text) }} } {% endfor %} -{% for set_name in ns.sets %} +{% endif %} + +{% for set_name in ns.sets %} set RECENT_{{ set_name }} { type ipv4_addr size 65535 flags dynamic } -{% endfor %} -{% for set_name in ip_fqdn %} +{% endfor %} +{% for set_name in ip_fqdn %} set FQDN_{{ set_name }} { type ipv4_addr flags interval } -{% endfor %} -{% if geoip_updated.name is vyos_defined %} -{% for setname in geoip_updated.name %} +{% endfor %} +{% if geoip_updated.name is vyos_defined %} +{% for setname in geoip_updated.name %} set {{ setname }} { type ipv4_addr flags interval } -{% endfor %} -{% endif %} +{% endfor %} {% endif %} {% endif %} - {{ group_tmpl.groups(group, False) }} } @@ -158,8 +126,8 @@ delete table ip6 vyos_filter {% endif %} table ip6 vyos_filter { {% if ipv6 is vyos_defined %} +{% set ns = namespace(sets=[]) %} {% if ipv6.forward is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv6.forward.items() %} {% set def_action = conf.default_action %} chain VYOS_IPV6_FORWARD_{{ prior }} { @@ -174,17 +142,9 @@ table ip6 vyos_filter { {% endif %} } {% endfor %} -{% for set_name in ns.sets %} - set RECENT6_{{ set_name }} { - type ipv6_addr - size 65535 - flags dynamic - } -{% endfor %} {% endif %} {% if ipv6.input is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv6.input.items() %} {% set def_action = conf.default_action %} chain VYOS_IPV6_INPUT_{{ prior }} { @@ -199,17 +159,9 @@ table ip6 vyos_filter { {% endif %} } {% endfor %} -{% for set_name in ns.sets %} - set RECENT6_{{ set_name }} { - type ipv6_addr - size 65535 - flags dynamic - } -{% endfor %} {% endif %} {% if ipv6.output is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for prior, conf in ipv6.output.items() %} {% set def_action = conf.default_action %} chain VYOS_IPV6_OUTPUT_{{ prior }} { @@ -224,21 +176,14 @@ table ip6 vyos_filter { {% endif %} } {% endfor %} -{% for set_name in ns.sets %} - set RECENT6_{{ set_name }} { - type ipv6_addr - size 65535 - flags dynamic - } -{% endfor %} {% endif %} + chain VYOS_FRAG6_MARK { type filter hook prerouting priority -450; policy accept; exthdr frag exists meta mark set 0xffff1 return } {% if ipv6.ipv6_name is vyos_defined %} -{% set ns = namespace(sets=[]) %} {% for name_text, conf in ipv6.ipv6_name.items() %} chain NAME6_{{ name_text }} { {% if conf.rule is vyos_defined %} @@ -252,30 +197,29 @@ table ip6 vyos_filter { {{ conf | nft_default_rule(name_text, ipv6=True) }} } {% endfor %} -{% for set_name in ip6_fqdn %} - set FQDN_{{ set_name }} { - type ipv6_addr - flags interval - } -{% endfor %} -{% for set_name in ns.sets %} +{% endif %} + +{% for set_name in ns.sets %} set RECENT6_{{ set_name }} { type ipv6_addr size 65535 flags dynamic } -{% endfor %} -{% if geoip_updated.ipv6_name is vyos_defined %} -{% for setname in geoip_updated.ipv6_name %} +{% endfor %} +{% for set_name in ip6_fqdn %} + set FQDN_{{ set_name }} { + type ipv6_addr + flags interval + } +{% endfor %} +{% if geoip_updated.ipv6_name is vyos_defined %} +{% for setname in geoip_updated.ipv6_name %} set {{ setname }} { type ipv6_addr flags interval } -{% endfor %} -{% endif %} +{% endfor %} {% endif %} {% endif %} - {{ group_tmpl.groups(group, True) }} - } \ No newline at end of file diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11 index 9dad86b62..8cd2a4df8 100755 --- a/src/migration-scripts/firewall/10-to-11 +++ b/src/migration-scripts/firewall/10-to-11 @@ -263,6 +263,7 @@ if config.exists(base + ['zone']): config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'outbound-interface', 'interface-group'], value=group_name) config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'inbound-interface', 'interface-group'], value=group_name) config.set(base + ['ipv4', 'forward', 'filter', 'rule', fwd_ipv4_rule, 'action'], value=intra_zone_ipv4_action) + config.set(base + ['ipv6', 'forward', 'filter', 'rule']) config.set_tag(base + ['ipv6', 'forward', 'filter', 'rule']) config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'outbound-interface', 'interface-group'], value=group_name) config.set(base + ['ipv6', 'forward', 'filter', 'rule', fwd_ipv6_rule, 'inbound-interface', 'interface-group'], value=group_name) -- cgit v1.2.3 From 0300bf433d9aaff81fdecf9eeaabba8d06c1999f Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Mon, 3 Jul 2023 16:32:37 -0300 Subject: T5160: firewall refactor: move to . Also fix some unexpected behaviour with geoip. --- data/templates/firewall/nftables.j2 | 4 +- .../include/firewall/ipv6-custom-name.xml.i | 6 +-- .../include/firewall/ipv6-hook-forward.xml.i | 2 +- .../include/firewall/ipv6-hook-input.xml.i | 2 +- .../include/firewall/ipv6-hook-output.xml.i | 2 +- python/vyos/firewall.py | 15 +++---- smoketest/scripts/cli/test_firewall.py | 52 +++++++++++----------- src/conf_mode/firewall.py | 36 +++++++-------- src/migration-scripts/firewall/10-to-11 | 8 ++-- 9 files changed, 63 insertions(+), 64 deletions(-) diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index 1c70a6b77..10cbc68cb 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -183,8 +183,8 @@ table ip6 vyos_filter { exthdr frag exists meta mark set 0xffff1 return } -{% if ipv6.ipv6_name is vyos_defined %} -{% for name_text, conf in ipv6.ipv6_name.items() %} +{% if ipv6.name is vyos_defined %} +{% for name_text, conf in ipv6.name.items() %} chain NAME6_{{ name_text }} { {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} diff --git a/interface-definitions/include/firewall/ipv6-custom-name.xml.i b/interface-definitions/include/firewall/ipv6-custom-name.xml.i index 6275036c1..4b6777293 100644 --- a/interface-definitions/include/firewall/ipv6-custom-name.xml.i +++ b/interface-definitions/include/firewall/ipv6-custom-name.xml.i @@ -1,5 +1,5 @@ - + IPv6 custom firewall @@ -14,7 +14,7 @@ Set jump target. Action jump must be defined in default-action to use this setting - firewall ipv6 ipv6-name + firewall ipv6 name @@ -38,7 +38,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ipv6 ipv6-name + firewall ipv6 name diff --git a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i index 042bd9931..25e1bd288 100644 --- a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i @@ -31,7 +31,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ipv6 ipv6-name + firewall ipv6 name diff --git a/interface-definitions/include/firewall/ipv6-hook-input.xml.i b/interface-definitions/include/firewall/ipv6-hook-input.xml.i index 8c41e0aca..f9a4d71b4 100644 --- a/interface-definitions/include/firewall/ipv6-hook-input.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-input.xml.i @@ -30,7 +30,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ipv6 ipv6-name + firewall ipv6 name diff --git a/interface-definitions/include/firewall/ipv6-hook-output.xml.i b/interface-definitions/include/firewall/ipv6-hook-output.xml.i index 9b756d870..9bf73a778 100644 --- a/interface-definitions/include/firewall/ipv6-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-output.xml.i @@ -30,7 +30,7 @@ Set jump target. Action jump must be defined to use this setting - firewall ipv6 ipv6-name + firewall ipv6 name diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index b028f0af0..4aa509fe2 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -51,8 +51,8 @@ def fqdn_config_parse(firewall): if (path[0] == 'ipv4') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'): firewall['ip_fqdn'][set_name] = domain - elif (path[0] == 'ipv6') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name'): - if path[1] == 'ipv6_name': + elif (path[0] == 'ipv6') and (path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name'): + if path[1] == 'name': set_name = f'name6_{priority}_{rule}_{suffix}' firewall['ip6_fqdn'][set_name] = domain @@ -160,8 +160,8 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): if hook == 'OUT': hook_name = 'output' if hook == 'NAM': - hook_name = f'name{def_suffix}' - output.append(f'{ip_name} {prefix}addr {operator} @GEOIP_CC_{hook_name}_{fw_name}_{rule_id}') + hook_name = f'name' + output.append(f'{ip_name} {prefix}addr {operator} @GEOIP_CC{def_suffix}_{hook_name}_{fw_name}_{rule_id}') if 'mac_address' in side_conf: suffix = side_conf["mac_address"] @@ -519,12 +519,11 @@ def geoip_update(firewall, force=False): # Map country codes to set names for codes, path in dict_search_recursive(firewall, 'country_code'): set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' - if path[1] == 'ipv6_name': - set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' - if ( path[0] == 'ipv4' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): + if ( path[0] == 'ipv4'): for code in codes: ipv4_codes.setdefault(code, []).append(set_name) - elif ( path[0] == 'ipv6' ) and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): + elif ( path[0] == 'ipv6' ): + set_name = f'GEOIP_CC6_{path[1]}_{path[2]}_{path[4]}' for code in codes: ipv6_codes.setdefault(code, []).append(set_name) diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index bd7666313..9412ce984 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -362,14 +362,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name = 'v6-smoketest' interface = 'eth0' - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'source', 'address', '2002::1']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '2002::1:1']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'log', 'enable']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'log-options', 'level', 'crit']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'source', 'address', '2002::1']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'destination', 'address', '2002::1:1']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'log', 'enable']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'log-options', 'level', 'crit']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'default-action', 'accept']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'action', 'reject']) @@ -411,15 +411,15 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): name2 = 'v6-smoketest-adv2' interface = 'eth0' - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'packet-length', '65']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'packet-length', '513']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'packet-length', '1025']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'dscp', '18']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'dscp', '53']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'packet-length', '65']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'packet-length', '513']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'packet-length', '1025']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'dscp', '18']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'dscp', '53']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'action', 'accept']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '4', 'packet-length', '1-1999']) @@ -454,20 +454,20 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'group', 'ipv6-address-group', 'mask_group', 'address', '::beef']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'enable-default-log']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'enable-default-log']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '::1111:2222:3333:4444']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '1', 'destination', 'address-mask', '::ffff:ffff:ffff:ffff']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'destination', 'address', '::1111:2222:3333:4444']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '1', 'destination', 'address-mask', '::ffff:ffff:ffff:ffff']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '2', 'action', 'accept']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '2', 'source', 'address', '!::aaaa:bbbb:cccc:dddd']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '2', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '2', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '2', 'source', 'address', '!::aaaa:bbbb:cccc:dddd']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '2', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) - self.cli_set(['firewall', 'ipv6', 'ipv6-name', name, 'rule', '3', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'source', 'group', 'address-group', 'mask_group']) + self.cli_set(['firewall', 'ipv6', 'name', name, 'rule', '3', 'source', 'address-mask', '::ffff:ffff:ffff:ffff']) self.cli_commit() diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index a50ae2ec6..c8b1e27db 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -98,21 +98,21 @@ def geoip_updated(conf, firewall): for key, path in dict_search_recursive(firewall, 'geoip'): set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' - if path[1] == 'ipv6_name': - set_name = f'GEOIP_CC_name6_{path[2]}_{path[4]}' - - if (path[0] == 'ipv4') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'name' ): + if (path[0] == 'ipv4'): out['name'].append(set_name) - elif (path[0] == 'ipv6') and ( path[1] == 'forward' or path[1] == 'input' or path[1] == 'output' or path[1] == 'ipv6_name' ): + elif (path[0] == 'ipv6'): + set_name = f'GEOIP_CC6_{path[1]}_{path[2]}_{path[4]}' out['ipv6_name'].append(set_name) + updated = True if 'delete' in node_diff: for key, path in dict_search_recursive(node_diff['delete'], 'geoip'): - set_name = f'GEOIP_CC_{path[2]}_{path[4]}' - if path[1] == 'name': + set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' + if (path[0] == 'ipv4'): out['deleted_name'].append(set_name) - elif path[1] == 'ipv6-name': + elif (path[0] == 'ipv6'): + set_name = f'GEOIP_CC_{path[1]}_{path[2]}_{path[4]}' out['deleted_ipv6_name'].append(set_name) updated = True @@ -140,7 +140,7 @@ def get_config(config=None): default_values = defaults(base) for family in ['ipv4', 'ipv6']: - for tmp in ['name', 'ipv6_name', 'forward', 'input', 'output', 'prerouting']: + for tmp in ['name', 'forward', 'input', 'output', 'prerouting']: if tmp in default_values[family]: del default_values[family][tmp] @@ -162,11 +162,11 @@ def get_config(config=None): firewall['ipv4'][hook][priority]) # Merge in defaults for IPv6 ruleset - if 'ipv6_name' in firewall['ipv6']: - default_values = defaults(base + ['ipv6'] + ['ipv6-name']) - for ipv6_name in firewall['ipv6']['ipv6_name']: - firewall['ipv6']['ipv6_name'][ipv6_name] = dict_merge(default_values, - firewall['ipv6']['ipv6_name'][ipv6_name]) + if 'name' in firewall['ipv6']: + default_values = defaults(base + ['ipv6'] + ['name']) + for ipv6_name in firewall['ipv6']['name']: + firewall['ipv6']['name'][ipv6_name] = dict_merge(default_values, + firewall['ipv6']['name'][ipv6_name]) for hook in ['forward', 'input', 'output', 'prerouting']: if hook in firewall['ipv6']: for priority in ['filter', 'mangle', 'raw']: @@ -209,8 +209,8 @@ def verify_rule(firewall, rule_conf, ipv6): if target not in dict_search_args(firewall, 'ipv4', 'name'): raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') else: - if target not in dict_search_args(firewall, 'ipv6', 'ipv6_name'): - raise ConfigError(f'Invalid jump-target. Firewall ipv6-name {target} does not exist on the system') + if target not in dict_search_args(firewall, 'ipv6', 'name'): + raise ConfigError(f'Invalid jump-target. Firewall ipv6 name {target} does not exist on the system') if 'queue_options' in rule_conf: if 'queue' not in rule_conf['action']: @@ -359,7 +359,7 @@ def verify(firewall): verify_rule(firewall, rule_conf, False) if 'ipv6' in firewall: - for name in ['ipv6_name','forward','input','output']: + for name in ['name','forward','input','output']: if name in firewall['ipv6']: for name_id, name_conf in firewall['ipv6'][name].items(): if 'jump' in name_conf['default_action'] and 'default_jump_target' not in name_conf: @@ -371,7 +371,7 @@ def verify(firewall): if name_conf['default_jump_target'] == name_id: raise ConfigError(f'Loop detected on default-jump-target.') ## Now need to check that default-jump-target exists (other firewall chain/name) - if target not in dict_search_args(firewall['ipv6'], 'ipv6_name'): + if target not in dict_search_args(firewall['ipv6'], 'name'): raise ConfigError(f'Invalid jump-target. Firewall name {target} does not exist on the system') if 'rule' in name_conf: diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11 index 8cd2a4df8..8afcb64fd 100755 --- a/src/migration-scripts/firewall/10-to-11 +++ b/src/migration-scripts/firewall/10-to-11 @@ -21,7 +21,7 @@ # set firewall ipv6-name ... # To # set firewall ipv4 name -# set firewall ipv6 ipv6-name +# set firewall ipv6 name ## Also from 'firewall interface' removed. ## in and out: @@ -97,11 +97,11 @@ if config.exists(base + ['name']): config.delete(base + ['name']) if config.exists(base + ['ipv6-name']): - config.set(['firewall', 'ipv6', 'ipv6-name']) - config.set_tag(['firewall', 'ipv6', 'ipv6-name']) + config.set(['firewall', 'ipv6', 'name']) + config.set_tag(['firewall', 'ipv6', 'name']) for ipv6name in config.list_nodes(base + ['ipv6-name']): - config.copy(base + ['ipv6-name', ipv6name], base + ['ipv6', 'ipv6-name', ipv6name]) + config.copy(base + ['ipv6-name', ipv6name], base + ['ipv6', 'name', ipv6name]) config.delete(base + ['ipv6-name']) ### Migration of firewall interface -- cgit v1.2.3 From a07a46d5d4ace155bc540aee6c745b600d6498b0 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Tue, 4 Jul 2023 10:44:45 +0000 Subject: T5160: firewall refactor: change default value for from to if default-action is not specified in base chains --- .../include/firewall/default-action-base-chains.xml.i | 2 +- smoketest/scripts/cli/test_firewall.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/interface-definitions/include/firewall/default-action-base-chains.xml.i b/interface-definitions/include/firewall/default-action-base-chains.xml.i index ba7c63cd6..aa62abf3d 100644 --- a/interface-definitions/include/firewall/default-action-base-chains.xml.i +++ b/interface-definitions/include/firewall/default-action-base-chains.xml.i @@ -17,6 +17,6 @@ (drop|accept) - drop + accept diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 9412ce984..7a13f396f 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -254,7 +254,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['tcp dport 22', 'limit rate 5/minute', 'accept'], ['tcp dport 22', 'add @RECENT_FWD_filter_4 { ip saddr limit rate over 10/minute burst 10 packets }', 'meta pkttype host', 'drop'], ['chain VYOS_INPUT_filter'], - ['type filter hook input priority filter; policy drop;'], + ['type filter hook input priority filter; policy accept;'], ['tcp flags & syn == syn', f'tcp option maxseg size {mss_range}', f'iifname "{interface}"', 'meta pkttype broadcast', 'accept'], ['meta l4proto gre', f'ct mark {mark_hex}', 'return'], ['chain VYOS_OUTPUT_filter'], @@ -294,7 +294,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'dscp', '3-11']) self.cli_set(['firewall', 'ipv4', 'name', name, 'rule', '7', 'dscp-exclude', '21-25']) - self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'default-action', 'drop']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'source', 'address', '198.51.100.1']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'action', 'jump']) self.cli_set(['firewall', 'ipv4', 'forward', 'filter', 'rule', '1', 'jump-target', name]) @@ -312,10 +312,10 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): nftables_search = [ ['chain VYOS_FORWARD_filter'], - ['type filter hook forward priority filter; policy accept;'], + ['type filter hook forward priority filter; policy drop;'], ['ip saddr 198.51.100.1', f'jump NAME_{name}'], ['chain VYOS_INPUT_filter'], - ['type filter hook input priority filter; policy drop;'], + ['type filter hook input priority filter; policy accept;'], [f'meta l4proto tcp','queue to 3'], [f'meta l4proto udp','queue flags bypass,fanout to 0-15'], [f'chain NAME_{name}'], @@ -394,7 +394,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['type filter hook forward priority filter; policy accept;'], ['meta l4proto { tcp, udp }', 'th dport 8888', f'iifname "{interface}"', 'reject'], ['chain VYOS_IPV6_INPUT_filter'], - ['type filter hook input priority filter; policy drop;'], + ['type filter hook input priority filter; policy accept;'], ['meta l4proto udp', 'ip6 saddr 2002::1:2', f'iifname "{interface}"', 'accept'], ['chain VYOS_IPV6_OUTPUT_filter'], ['type filter hook output priority filter; policy drop;'], @@ -436,7 +436,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): nftables_search = [ ['chain VYOS_IPV6_FORWARD_filter'], - ['type filter hook forward priority filter; policy drop;'], + ['type filter hook forward priority filter; policy accept;'], ['ip6 length 1-1999', 'ip6 length != 60000-65535', 'ip6 dscp 0x04-0x0e', 'ip6 dscp != 0x1f-0x23', 'accept'], ['chain VYOS_IPV6_INPUT_filter'], ['type filter hook input priority filter; policy accept;'], -- cgit v1.2.3 From f57ad85b346a08bd3aa31d95c9a7438f783c2b6e Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Tue, 4 Jul 2023 09:58:26 -0300 Subject: T5160: firewall refactor: fix regexep for connection-status. Create new file with common matcher for ipv4 and ipv6, and use include on all chains for all this comman matchers --- .../include/firewall/common-rule-inet.xml.i | 374 +++++++++++++++++++++ .../include/firewall/common-rule-ipv4-raw.xml.i | 2 +- .../include/firewall/common-rule-ipv4.xml.i | 354 +------------------ .../include/firewall/common-rule-ipv6.xml.i | 354 +------------------ .../include/firewall/ipv4-custom-name.xml.i | 8 - .../include/firewall/ipv4-hook-forward.xml.i | 8 - .../include/firewall/ipv4-hook-input.xml.i | 8 - .../include/firewall/ipv4-hook-output.xml.i | 8 - .../include/firewall/ipv6-custom-name.xml.i | 8 - .../include/firewall/ipv6-hook-forward.xml.i | 8 - .../include/firewall/ipv6-hook-input.xml.i | 8 - .../include/firewall/ipv6-hook-output.xml.i | 8 - 12 files changed, 385 insertions(+), 763 deletions(-) create mode 100644 interface-definitions/include/firewall/common-rule-inet.xml.i diff --git a/interface-definitions/include/firewall/common-rule-inet.xml.i b/interface-definitions/include/firewall/common-rule-inet.xml.i new file mode 100644 index 000000000..7a2eb86d4 --- /dev/null +++ b/interface-definitions/include/firewall/common-rule-inet.xml.i @@ -0,0 +1,374 @@ + +#include +#include +#include +#include +#include +#include + + + Option to disable firewall rule + + + + + + IP fragment match + + + + + Second and further fragments of fragmented packets + + + + + + Head fragments or unfragmented packets + + + + + + + + Inbound IPsec packets + + + + + Inbound IPsec packets + + + + + + Inbound non-IPsec packets + + + + + + + + Rate limit using a token bucket filter + + + + + Maximum number of packets to allow in excess of rate + + u32:0-4294967295 + Maximum number of packets to allow in excess of rate + + + + + + + + + Maximum average matching rate + + txt + integer/unit (Example: 5/minute) + + + \d+/(second|minute|hour|day) + + + + + + + + Option to log packets matching rule + + enable disable + + + enable + Enable log + + + disable + Disable log + + + (enable|disable) + + + + + + Option to log packets matching rule + + enable disable + + + enable + Enable log + + + disable + Disable log + + + (enable|disable) + + + +#include + + + Connection status + + + + + NAT connection status + + destination source + + + destination + Match connections that are subject to destination NAT + + + source + Match connections that are subject to source NAT + + + (destination|source) + + + + + + + + Protocol to match (protocol name, number, or "all") + + + all tcp_udp + + + all + All IP protocols + + + tcp_udp + Both TCP and UDP + + + u32:0-255 + IP protocol number + + + <protocol> + IP protocol name + + + !<protocol> + IP protocol name + + + + + + + + + Parameters for matching recently seen sources + + + + + Source addresses seen more than N times + + u32:1-255 + Source addresses seen more than N times + + + + + + + + + Source addresses seen in the last second/minute/hour + + second minute hour + + + second + Source addresses seen COUNT times in the last second + + + minute + Source addresses seen COUNT times in the last minute + + + hour + Source addresses seen COUNT times in the last hour + + + (second|minute|hour) + + + + + + + + Session state + + + + + Established state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + Invalid state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + New state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + + Related state + + enable disable + + + enable + Enable + + + disable + Disable + + + (enable|disable) + + + + + +#include + + + Time to match rule + + + + + Date to start matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to start matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Date to stop matching rule + + txt + Enter date using following notation - YYYY-MM-DD + + + (\d{4}\-\d{2}\-\d{2}) + + + + + + Time of day to stop matching rule + + txt + Enter time using using 24 hour notation - hh:mm:ss + + + ([0-2][0-9](\:[0-5][0-9]){1,2}) + + + + + + Comma separated weekdays to match rule on + + txt + Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday) + + + u32:0-6 + Day number (0 = Sunday ... 6 = Saturday) + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i index 86af2fb0e..a1071a09a 100644 --- a/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i @@ -165,7 +165,7 @@ Match connections that are subject to source NAT - ^(destination|source)$ + (destination|source) diff --git a/interface-definitions/include/firewall/common-rule-ipv4.xml.i b/interface-definitions/include/firewall/common-rule-ipv4.xml.i index b873d99a3..4ed179ae7 100644 --- a/interface-definitions/include/firewall/common-rule-ipv4.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv4.xml.i @@ -1,11 +1,6 @@ -#include -#include -#include -#include -#include +#include #include -#include Destination parameters @@ -20,31 +15,6 @@ #include - - - Option to disable firewall rule - - - - - - IP fragment match - - - - - Second and further fragments of fragmented packets - - - - - - Head fragments or unfragmented packets - - - - - ICMP type and code information @@ -77,176 +47,14 @@ #include - - - Inbound IPsec packets - - - - - Inbound IPsec packets - - - - - - Inbound non-IPsec packets - - - - - - - - Rate limit using a token bucket filter - - - - - Maximum number of packets to allow in excess of rate - - u32:0-4294967295 - Maximum number of packets to allow in excess of rate - - - - - - - - - Maximum average matching rate - - txt - integer/unit (Example: 5/minute) - - - \d+/(second|minute|hour|day) - - - - - - - - Option to log packets matching rule - - enable disable - - - enable - Enable log - - - disable - Disable log - - - (enable|disable) - - - -#include - - - Connection status - - - - - NAT connection status - - destination source - - - destination - Match connections that are subject to destination NAT - - - source - Match connections that are subject to source NAT - - - ^(destination|source)$ - - - - - - + - Protocol to match (protocol name, number, or "all") + Set jump target. Action jump must be defined to use this setting - - all tcp_udp + firewall ipv4 name - - all - All IP protocols - - - tcp_udp - Both TCP and UDP - - - u32:0-255 - IP protocol number - - - <protocol> - IP protocol name - - - !<protocol> - IP protocol name - - - - - - - Parameters for matching recently seen sources - - - - - Source addresses seen more than N times - - u32:1-255 - Source addresses seen more than N times - - - - - - - - - Source addresses seen in the last second/minute/hour - - second minute hour - - - second - Source addresses seen COUNT times in the last second - - - minute - Source addresses seen COUNT times in the last minute - - - hour - Source addresses seen COUNT times in the last hour - - - (second|minute|hour) - - - - - Source parameters @@ -261,156 +69,4 @@ #include - - - Session state - - - - - Established state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - - Invalid state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - - New state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - - Related state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - -#include - - - Time to match rule - - - - - Date to start matching rule - - txt - Enter date using following notation - YYYY-MM-DD - - - (\d{4}\-\d{2}\-\d{2}) - - - - - - Time of day to start matching rule - - txt - Enter time using using 24 hour notation - hh:mm:ss - - - ([0-2][0-9](\:[0-5][0-9]){1,2}) - - - - - - Date to stop matching rule - - txt - Enter date using following notation - YYYY-MM-DD - - - (\d{4}\-\d{2}\-\d{2}) - - - - - - Time of day to stop matching rule - - txt - Enter time using using 24 hour notation - hh:mm:ss - - - ([0-2][0-9](\:[0-5][0-9]){1,2}) - - - - - - Comma separated weekdays to match rule on - - txt - Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday) - - - u32:0-6 - Day number (0 = Sunday ... 6 = Saturday) - - - - - - + \ No newline at end of file diff --git a/interface-definitions/include/firewall/common-rule-ipv6.xml.i b/interface-definitions/include/firewall/common-rule-ipv6.xml.i index 758281335..6219557db 100644 --- a/interface-definitions/include/firewall/common-rule-ipv6.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv6.xml.i @@ -1,11 +1,6 @@ -#include -#include -#include -#include -#include +#include #include -#include Destination parameters @@ -20,31 +15,6 @@ #include - - - Option to disable firewall rule - - - - - - IP fragment match - - - - - Second and further fragments of fragmented packets - - - - - - Head fragments or unfragmented packets - - - - - ICMPv6 type and code information @@ -77,176 +47,14 @@ #include - - - Inbound IPsec packets - - - - - Inbound IPsec packets - - - - - - Inbound non-IPsec packets - - - - - - - - Rate limit using a token bucket filter - - - - - Maximum number of packets to allow in excess of rate - - u32:0-4294967295 - Maximum number of packets to allow in excess of rate - - - - - - - - - Maximum average matching rate - - txt - integer/unit (Example: 5/minute) - - - \d+/(second|minute|hour|day) - - - - - - - - Option to log packets matching rule - - enable disable - - - enable - Enable log - - - disable - Disable log - - - (enable|disable) - - - -#include - - - Connection status - - - - - NAT connection status - - destination source - - - destination - Match connections that are subject to destination NAT - - - source - Match connections that are subject to source NAT - - - ^(destination|source)$ - - - - - - + - Protocol to match (protocol name, number, or "all") + Set jump target. Action jump must be defined to use this setting - - all tcp_udp + firewall ipv6 name - - all - All IP protocols - - - tcp_udp - Both TCP and UDP - - - u32:0-255 - IP protocol number - - - <protocol> - IP protocol name - - - !<protocol> - IP protocol name - - - - - - - Parameters for matching recently seen sources - - - - - Source addresses seen more than N times - - u32:1-255 - Source addresses seen more than N times - - - - - - - - - Source addresses seen in the last second/minute/hour - - second minute hour - - - second - Source addresses seen COUNT times in the last second - - - minute - Source addresses seen COUNT times in the last minute - - - hour - Source addresses seen COUNT times in the last hour - - - (second|minute|hour) - - - - - Source parameters @@ -261,156 +69,4 @@ #include - - - Session state - - - - - Established state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - - Invalid state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - - New state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - - Related state - - enable disable - - - enable - Enable - - - disable - Disable - - - (enable|disable) - - - - - -#include - - - Time to match rule - - - - - Date to start matching rule - - txt - Enter date using following notation - YYYY-MM-DD - - - (\d{4}\-\d{2}\-\d{2}) - - - - - - Time of day to start matching rule - - txt - Enter time using using 24 hour notation - hh:mm:ss - - - ([0-2][0-9](\:[0-5][0-9]){1,2}) - - - - - - Date to stop matching rule - - txt - Enter date using following notation - YYYY-MM-DD - - - (\d{4}\-\d{2}\-\d{2}) - - - - - - Time of day to stop matching rule - - txt - Enter time using using 24 hour notation - hh:mm:ss - - - ([0-2][0-9](\:[0-5][0-9]){1,2}) - - - - - - Comma separated weekdays to match rule on - - txt - Name of day (Monday, Tuesday, Wednesday, Thursdays, Friday, Saturday, Sunday) - - - u32:0-6 - Day number (0 = Sunday ... 6 = Saturday) - - - - - - + \ No newline at end of file diff --git a/interface-definitions/include/firewall/ipv4-custom-name.xml.i b/interface-definitions/include/firewall/ipv4-custom-name.xml.i index 7fd802f3b..9d6ecfaf2 100644 --- a/interface-definitions/include/firewall/ipv4-custom-name.xml.i +++ b/interface-definitions/include/firewall/ipv4-custom-name.xml.i @@ -34,14 +34,6 @@ #include #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv4 name - - - diff --git a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i index beb9df64e..08ee96419 100644 --- a/interface-definitions/include/firewall/ipv4-hook-forward.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-forward.xml.i @@ -27,14 +27,6 @@ #include #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv4 name - - - diff --git a/interface-definitions/include/firewall/ipv4-hook-input.xml.i b/interface-definitions/include/firewall/ipv4-hook-input.xml.i index 1a2e1399f..32b0ec94f 100644 --- a/interface-definitions/include/firewall/ipv4-hook-input.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-input.xml.i @@ -26,14 +26,6 @@ #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv4 name - - - diff --git a/interface-definitions/include/firewall/ipv4-hook-output.xml.i b/interface-definitions/include/firewall/ipv4-hook-output.xml.i index e870e2b79..d50d1e93b 100644 --- a/interface-definitions/include/firewall/ipv4-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-output.xml.i @@ -26,14 +26,6 @@ #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv4 name - - - diff --git a/interface-definitions/include/firewall/ipv6-custom-name.xml.i b/interface-definitions/include/firewall/ipv6-custom-name.xml.i index 4b6777293..81610babf 100644 --- a/interface-definitions/include/firewall/ipv6-custom-name.xml.i +++ b/interface-definitions/include/firewall/ipv6-custom-name.xml.i @@ -34,14 +34,6 @@ #include #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv6 name - - - diff --git a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i index 25e1bd288..20ab8dbe8 100644 --- a/interface-definitions/include/firewall/ipv6-hook-forward.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-forward.xml.i @@ -27,14 +27,6 @@ #include #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv6 name - - - diff --git a/interface-definitions/include/firewall/ipv6-hook-input.xml.i b/interface-definitions/include/firewall/ipv6-hook-input.xml.i index f9a4d71b4..e34958f28 100644 --- a/interface-definitions/include/firewall/ipv6-hook-input.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-input.xml.i @@ -26,14 +26,6 @@ #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv6 name - - - diff --git a/interface-definitions/include/firewall/ipv6-hook-output.xml.i b/interface-definitions/include/firewall/ipv6-hook-output.xml.i index 9bf73a778..eb4ea7ac3 100644 --- a/interface-definitions/include/firewall/ipv6-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-output.xml.i @@ -26,14 +26,6 @@ #include #include - - - Set jump target. Action jump must be defined to use this setting - - firewall ipv6 name - - - -- cgit v1.2.3 From 4e07fa25f551325fd90b92426e4693107090d346 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Fri, 11 Aug 2023 18:26:53 +0000 Subject: T5460: remove config-trap from firewall --- .../include/firewall/global-options.xml.i | 20 -------------------- src/conf_mode/firewall.py | 15 --------------- src/migration-scripts/firewall/10-to-11 | 12 ++++++------ 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/interface-definitions/include/firewall/global-options.xml.i b/interface-definitions/include/firewall/global-options.xml.i index 3204a239d..a63874cb0 100644 --- a/interface-definitions/include/firewall/global-options.xml.i +++ b/interface-definitions/include/firewall/global-options.xml.i @@ -44,26 +44,6 @@ disable - - - SNMP trap generation on firewall configuration changes - - enable disable - - - enable - Enable sending SNMP trap on firewall configuration change - - - disable - Disable sending SNMP trap on firewall configuration change - - - (enable|disable) - - - disable - Policy for handling IPv4 packets with source route option diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index c8b1e27db..7c09dfe9b 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -180,14 +180,6 @@ def get_config(config=None): # Update nat and policy-route as firewall groups were updated set_dependents('group_resync', conf) - #if 'config_trap' in firewall and firewall['config_trap'] == 'enable': - if 'config_trap' in firewall and firewall['global_options']['config_trap'] == 'enable': - diff = get_config_diff(conf) - firewall['trap_diff'] = diff.get_child_nodes_diff_str(base) - firewall['trap_targets'] = conf.get_config_dict(['service', 'snmp', 'trap-target'], - key_mangling=('-', '_'), get_first_key=True, - no_tag_node_value_mangle=True) - firewall['geoip_updated'] = geoip_updated(conf, firewall) fqdn_config_parse(firewall) @@ -327,10 +319,6 @@ def verify_nested_group(group_name, group, groups, seen): verify_nested_group(g, groups[g], groups, seen) def verify(firewall): - if 'config_trap' in firewall and firewall['config_trap'] == 'enable': - if not firewall['trap_targets']: - raise ConfigError(f'Firewall config-trap enabled but "service snmp trap-target" is not defined') - if 'group' in firewall: for group_type in nested_group_types: if group_type in firewall['group']: @@ -410,9 +398,6 @@ def post_apply_trap(firewall): if 'first_install' in firewall: return None - if 'config_trap' not in firewall['global_options'] or firewall['global_options']['config_trap'] != 'enable': - return None - if not process_named_running('snmpd'): return None diff --git a/src/migration-scripts/firewall/10-to-11 b/src/migration-scripts/firewall/10-to-11 index 8afcb64fd..716c5a240 100755 --- a/src/migration-scripts/firewall/10-to-11 +++ b/src/migration-scripts/firewall/10-to-11 @@ -45,7 +45,7 @@ from sys import exit from vyos.configtree import ConfigTree from vyos.ifconfig import Section -if (len(argv) < 1): +if len(argv) < 2: print("Must specify file name!") exit(1) @@ -77,14 +77,14 @@ if config.exists(base + ['state-policy']): config.set(base + [family, hook, priority, 'rule', position, 'action'], value=action) position = position + 1 config.delete(base + ['state-policy']) -############ ## migration of global options: for option in ['all-ping', 'broadcast-ping', 'config-trap', 'ip-src-route', 'ipv6-receive-redirects', 'ipv6-src-route', 'log-martians', 'receive-redirects', 'resolver-cache', 'resolver-internal', 'send-redirects', 'source-validation', 'syn-cookies', 'twa-hazards-protection']: if config.exists(base + [option]): - val = config.return_value(base + [option]) - config.set(base + ['global-options', option], value=val) + if option != 'config-trap': + val = config.return_value(base + [option]) + config.set(base + ['global-options', option], value=val) config.delete(base + [option]) ### Migration of firewall name and ipv6-name @@ -182,7 +182,7 @@ if config.exists(base + ['interface']): config.delete(base + ['interface']) -### Migration of zones config v2: +### Migration of zones: ### User interface groups if config.exists(base + ['zone']): inp_ipv4_rule = 101 @@ -364,7 +364,7 @@ if config.exists(base + ['zone']): config.delete(base + ['zone']) -###### END migration zones v2 +###### END migration zones try: with open(file_name, 'w') as f: -- cgit v1.2.3