From 6871c5541c1962e63d7a9b75d2bb43df2a8d372b Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Wed, 15 May 2024 17:09:16 +0000 Subject: T3900: add support for raw table in firewall. --- data/templates/firewall/nftables.j2 | 46 ++- interface-definitions/firewall.xml.in | 2 + .../include/firewall/action-and-notrack.xml.i | 8 +- .../include/firewall/add-addr-to-group-ipv4.xml.i | 25 ++ .../include/firewall/add-addr-to-group-ipv6.xml.i | 25 ++ .../include/firewall/common-rule-inet.xml.i | 239 +--------------- .../include/firewall/common-rule-ipv4-raw.xml.i | 309 +-------------------- .../include/firewall/common-rule-ipv4.xml.i | 57 +--- .../include/firewall/common-rule-ipv6-raw.xml.i | 50 ++++ .../include/firewall/common-rule-ipv6.xml.i | 57 +--- .../include/firewall/connection-status.xml.i | 28 ++ .../include/firewall/fragment.xml.i | 21 ++ interface-definitions/include/firewall/icmp.xml.i | 34 +++ .../include/firewall/icmpv6.xml.i | 34 +++ .../include/firewall/ipv4-hook-output.xml.i | 27 ++ .../include/firewall/ipv4-hook-prerouting.xml.i | 34 --- .../include/firewall/ipv6-hook-output.xml.i | 27 ++ .../include/firewall/ipv6-hook-prerouting.xml.i | 51 ++++ interface-definitions/include/firewall/limit.xml.i | 33 +++ .../include/firewall/protocol.xml.i | 34 +++ .../include/firewall/recent.xml.i | 44 +++ interface-definitions/include/firewall/time.xml.i | 70 +++++ .../include/policy/route-common.xml.i | 72 +---- .../include/policy/route-ipv4.xml.i | 33 +-- python/vyos/firewall.py | 6 +- smoketest/scripts/cli/test_firewall.py | 40 ++- src/conf_mode/firewall.py | 4 +- src/conf_mode/system_conntrack.py | 3 + 28 files changed, 625 insertions(+), 788 deletions(-) create mode 100644 interface-definitions/include/firewall/add-addr-to-group-ipv4.xml.i create mode 100644 interface-definitions/include/firewall/add-addr-to-group-ipv6.xml.i create mode 100644 interface-definitions/include/firewall/common-rule-ipv6-raw.xml.i create mode 100644 interface-definitions/include/firewall/connection-status.xml.i create mode 100644 interface-definitions/include/firewall/fragment.xml.i create mode 100644 interface-definitions/include/firewall/icmp.xml.i create mode 100644 interface-definitions/include/firewall/icmpv6.xml.i create mode 100644 interface-definitions/include/firewall/ipv6-hook-prerouting.xml.i create mode 100644 interface-definitions/include/firewall/limit.xml.i create mode 100644 interface-definitions/include/firewall/protocol.xml.i create mode 100644 interface-definitions/include/firewall/recent.xml.i create mode 100644 interface-definitions/include/firewall/time.xml.i diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index 833df3a67..343917fee 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -57,7 +57,7 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule('FWD-filter', 'ipv4') }} + {{ conf | nft_default_rule('FWD-' + prior, 'ipv4') }} } {% endfor %} {% endif %} @@ -77,7 +77,7 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule('INP-filter', 'ipv4') }} + {{ conf | nft_default_rule('INP-' + prior, 'ipv4') }} } {% endfor %} {% endif %} @@ -97,14 +97,11 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule('OUT-filter', 'ipv4') }} + {{ conf | nft_default_rule('OUT-' + prior, 'ipv4') }} } {% 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 %} {% for prior, conf in ipv4.prerouting.items() %} chain VYOS_PREROUTING_{{ prior }} { @@ -117,11 +114,16 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule('PRE-filter', 'ipv4') }} + {{ conf | nft_default_rule('PRE-' + prior, 'ipv4') }} } {% 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.name is vyos_defined %} {% for name_text, conf in ipv4.name.items() %} chain NAME_{{ name_text }} { @@ -202,13 +204,13 @@ table ip6 vyos_filter { {% 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('FWD', prior, rule_id ,'ip6') }} + {{ 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 %} - {{ conf | nft_default_rule('FWD-filter', 'ipv6') }} + {{ conf | nft_default_rule('FWD-' + prior, 'ipv6') }} } {% endfor %} {% endif %} @@ -222,13 +224,13 @@ table ip6 vyos_filter { {% 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('INP', prior, rule_id ,'ip6') }} + {{ 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 %} - {{ conf | nft_default_rule('INP-filter', 'ipv6') }} + {{ conf | nft_default_rule('INP-' + prior, 'ipv6') }} } {% endfor %} {% endif %} @@ -242,17 +244,33 @@ table ip6 vyos_filter { {% 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('OUT', prior, rule_id ,'ip6') }} + {{ 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 %} - {{ conf | nft_default_rule('OUT-filter', 'ipv6') }} + {{ conf | nft_default_rule('OUT-' + prior, 'ipv6') }} } {% endfor %} {% endif %} +{% if ipv6.prerouting is vyos_defined %} +{% for prior, conf in ipv6.prerouting.items() %} + chain VYOS_IPV6_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, 'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['PRE_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('PRE-' + prior, 'ipv6') }} + } +{% endfor %} +{% endif %} chain VYOS_FRAG6_MARK { type filter hook prerouting priority -450; policy accept; exthdr frag exists meta mark set 0xffff1 return diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 24e63c5ec..dc4625af0 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -378,6 +378,7 @@ #include #include #include + #include #include @@ -389,6 +390,7 @@ #include #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 index 5f81a1451..e063c58d5 100644 --- a/interface-definitions/include/firewall/action-and-notrack.xml.i +++ b/interface-definitions/include/firewall/action-and-notrack.xml.i @@ -3,12 +3,16 @@ Rule action - accept jump notrack reject return drop queue + accept continue jump notrack reject return drop queue accept Accept matching entries + + continue + Continue parsing next rule + jump Jump to another chain @@ -34,7 +38,7 @@ Igone connection tracking - (accept|jump|notrack|reject|return|drop|queue) + (accept|continue|jump|notrack|reject|return|drop|queue) diff --git a/interface-definitions/include/firewall/add-addr-to-group-ipv4.xml.i b/interface-definitions/include/firewall/add-addr-to-group-ipv4.xml.i new file mode 100644 index 000000000..a47cadd55 --- /dev/null +++ b/interface-definitions/include/firewall/add-addr-to-group-ipv4.xml.i @@ -0,0 +1,25 @@ + + + + Add ip address to dynamic address-group + + + + + Add source ip addresses to dynamic address-group + + + #include + + + + + Add destination ip addresses to dynamic address-group + + + #include + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/add-addr-to-group-ipv6.xml.i b/interface-definitions/include/firewall/add-addr-to-group-ipv6.xml.i new file mode 100644 index 000000000..2cb077450 --- /dev/null +++ b/interface-definitions/include/firewall/add-addr-to-group-ipv6.xml.i @@ -0,0 +1,25 @@ + + + + Add ipv6 address to dynamic ipv6-address-group + + + + + Add source ipv6 addresses to dynamic ipv6-address-group + + + #include + + + + + Add destination ipv6 addresses to dynamic ipv6-address-group + + + #include + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/common-rule-inet.xml.i b/interface-definitions/include/firewall/common-rule-inet.xml.i index bef1c3da5..55ffa3a8b 100644 --- a/interface-definitions/include/firewall/common-rule-inet.xml.i +++ b/interface-definitions/include/firewall/common-rule-inet.xml.i @@ -1,235 +1,24 @@ #include -#include -#include -#include -#include -#include #include -#include +#include +#include +#include #include - - - IP fragment match - - - - - Second and further fragments of fragmented packets - - - - - - Head fragments or unfragmented 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) - - - - - +#include +#include +#include +#include #include #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) - - - - - -#include +#include +#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) - - - - - +#include 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 e7468bfba..960c960db 100644 --- a/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv4-raw.xml.i @@ -1,9 +1,22 @@ +#include #include #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include Destination parameters @@ -18,228 +31,6 @@ #include -#include - - - 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 @@ -254,74 +45,4 @@ #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) - - - - - - + \ No newline at end of file diff --git a/interface-definitions/include/firewall/common-rule-ipv4.xml.i b/interface-definitions/include/firewall/common-rule-ipv4.xml.i index 158c7a662..803b94b06 100644 --- a/interface-definitions/include/firewall/common-rule-ipv4.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv4.xml.i @@ -1,29 +1,8 @@ +#include #include +#include #include - - - Add ip address to dynamic address-group - - - - - Add source ip addresses to dynamic address-group - - - #include - - - - - Add destination ip addresses to dynamic address-group - - - #include - - - - Destination parameters @@ -39,38 +18,6 @@ #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 diff --git a/interface-definitions/include/firewall/common-rule-ipv6-raw.xml.i b/interface-definitions/include/firewall/common-rule-ipv6-raw.xml.i new file mode 100644 index 000000000..958167b89 --- /dev/null +++ b/interface-definitions/include/firewall/common-rule-ipv6-raw.xml.i @@ -0,0 +1,50 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + Destination parameters + + + #include + #include + #include + #include + #include + #include + #include + #include + + + + + Source parameters + + + #include + #include + #include + #include + #include + #include + #include + #include + + + \ 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 78eeb361e..bb176fe71 100644 --- a/interface-definitions/include/firewall/common-rule-ipv6.xml.i +++ b/interface-definitions/include/firewall/common-rule-ipv6.xml.i @@ -1,29 +1,8 @@ +#include #include #include - - - Add ipv6 address to dynamic ipv6-address-group - - - - - Add source ipv6 addresses to dynamic ipv6-address-group - - - #include - - - - - Add destination ipv6 addresses to dynamic ipv6-address-group - - - #include - - - - +#include Destination parameters @@ -39,38 +18,6 @@ #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 diff --git a/interface-definitions/include/firewall/connection-status.xml.i b/interface-definitions/include/firewall/connection-status.xml.i new file mode 100644 index 000000000..5236c2f4f --- /dev/null +++ b/interface-definitions/include/firewall/connection-status.xml.i @@ -0,0 +1,28 @@ + + + + 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) + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/fragment.xml.i b/interface-definitions/include/firewall/fragment.xml.i new file mode 100644 index 000000000..1f4c11055 --- /dev/null +++ b/interface-definitions/include/firewall/fragment.xml.i @@ -0,0 +1,21 @@ + + + + IP fragment match + + + + + Second and further fragments of fragmented packets + + + + + + Head fragments or unfragmented packets + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/icmp.xml.i b/interface-definitions/include/firewall/icmp.xml.i new file mode 100644 index 000000000..deb50a410 --- /dev/null +++ b/interface-definitions/include/firewall/icmp.xml.i @@ -0,0 +1,34 @@ + + + + ICMP type and code information + + + + + ICMP code + + u32:0-255 + ICMP code (0-255) + + + + + + + + + ICMP type + + u32:0-255 + ICMP type (0-255) + + + + + + + #include + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/icmpv6.xml.i b/interface-definitions/include/firewall/icmpv6.xml.i new file mode 100644 index 000000000..c0118626e --- /dev/null +++ b/interface-definitions/include/firewall/icmpv6.xml.i @@ -0,0 +1,34 @@ + + + + ICMPv6 type and code information + + + + + ICMPv6 code + + u32:0-255 + ICMPv6 code (0-255) + + + + + + + + + ICMPv6 type + + u32:0-255 + ICMPv6 type (0-255) + + + + + + + #include + + + \ 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 index 2b537ce5e..ca47ae09b 100644 --- a/interface-definitions/include/firewall/ipv4-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-output.xml.i @@ -31,6 +31,33 @@ + + + IPv4 firewall output raw + + + #include + #include + #include + + + IPv4 Firewall output raw rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + + diff --git a/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i b/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i index c38918375..17ecfe824 100644 --- a/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i +++ b/interface-definitions/include/firewall/ipv4-hook-prerouting.xml.i @@ -4,40 +4,6 @@ IPv4 prerouting firewall - - - IPv4 firewall prerouting filter - - - #include - #include - - - IPv4 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 ipv4 name - - - - - - - IPv4 firewall prerouting raw diff --git a/interface-definitions/include/firewall/ipv6-hook-output.xml.i b/interface-definitions/include/firewall/ipv6-hook-output.xml.i index ffe1c72b8..f877cfaaf 100644 --- a/interface-definitions/include/firewall/ipv6-hook-output.xml.i +++ b/interface-definitions/include/firewall/ipv6-hook-output.xml.i @@ -30,6 +30,33 @@ + + + + IPv6 firewall output raw + + + #include + #include + #include + + + IPv6 Firewall output raw rule number + + u32:1-999999 + Number for this firewall rule + + + + + Firewall rule number must be between 1 and 999999 + + + #include + #include + + + diff --git a/interface-definitions/include/firewall/ipv6-hook-prerouting.xml.i b/interface-definitions/include/firewall/ipv6-hook-prerouting.xml.i new file mode 100644 index 000000000..3f384828d --- /dev/null +++ b/interface-definitions/include/firewall/ipv6-hook-prerouting.xml.i @@ -0,0 +1,51 @@ + + + + IPv6 prerouting firewall + + + + + IPv6 firewall prerouting raw + + + #include + #include + + + Set jump target. Action jump must be defined in default-action to use this setting + + firewall ipv6 name + + + + + + IPv6 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 ipv6 name + + + + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/limit.xml.i b/interface-definitions/include/firewall/limit.xml.i new file mode 100644 index 000000000..21068dec2 --- /dev/null +++ b/interface-definitions/include/firewall/limit.xml.i @@ -0,0 +1,33 @@ + + + + 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) + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/protocol.xml.i b/interface-definitions/include/firewall/protocol.xml.i new file mode 100644 index 000000000..e391cae41 --- /dev/null +++ b/interface-definitions/include/firewall/protocol.xml.i @@ -0,0 +1,34 @@ + + + + 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 + + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/recent.xml.i b/interface-definitions/include/firewall/recent.xml.i new file mode 100644 index 000000000..38f40b916 --- /dev/null +++ b/interface-definitions/include/firewall/recent.xml.i @@ -0,0 +1,44 @@ + + + + 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) + + + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/time.xml.i b/interface-definitions/include/firewall/time.xml.i new file mode 100644 index 000000000..7bd737450 --- /dev/null +++ b/interface-definitions/include/firewall/time.xml.i @@ -0,0 +1,70 @@ + + + + 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/policy/route-common.xml.i b/interface-definitions/include/policy/route-common.xml.i index e412fe58e..97795601e 100644 --- a/interface-definitions/include/policy/route-common.xml.i +++ b/interface-definitions/include/policy/route-common.xml.i @@ -3,75 +3,9 @@ #include #include #include - - - 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 - - u32:0-4294967295 - Maximum average matching rate - - - - - - - - +#include +#include +#include #include diff --git a/interface-definitions/include/policy/route-ipv4.xml.i b/interface-definitions/include/policy/route-ipv4.xml.i index 1f717a1a4..c12abcae2 100644 --- a/interface-definitions/include/policy/route-ipv4.xml.i +++ b/interface-definitions/include/policy/route-ipv4.xml.i @@ -10,36 +10,5 @@ #include - - - ICMP type and code information - - - - - ICMP code (0-255) - - u32:0-255 - ICMP code (0-255) - - - - - - - - - ICMP type (0-255) - - u32:0-255 - ICMP type (0-255) - - - - - - - #include - - +#include diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index d7b7b80a8..664df28cc 100644 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -178,6 +178,8 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): hook_name = 'input' if hook == 'OUT': hook_name = 'output' + if hook == 'PRE': + hook_name = 'prerouting' 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}') @@ -193,6 +195,8 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): hook_name = 'input' if hook == 'OUT': hook_name = 'output' + if hook == 'PRE': + hook_name = 'prerouting' if hook == 'NAM': hook_name = f'name' output.append(f'{ip_name} {prefix}addr {operator} @GEOIP_CC{def_suffix}_{hook_name}_{fw_name}_{rule_id}') @@ -477,8 +481,6 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): output.append(f'tcp option maxseg size set {mss}') if 'action' in rule_conf: - # Change action=return to action=action - # #output.append(nft_action(rule_conf['action'])) if rule_conf['action'] == 'offload': offload_target = rule_conf['offload_target'] output.append(f'flow add @VYOS_FLOWTABLE_{offload_target}') diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index c47562714..5cf2b2146 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -236,6 +236,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): 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_set(['firewall', 'ipv4', 'output', 'raw', 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'output', 'raw', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv4', 'output', 'raw', 'rule', '1', 'protocol', 'udp']) + + self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'destination', 'port', '23']) + self.cli_commit() mark_hex = "{0:#010x}".format(int(conn_mark)) @@ -256,6 +264,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['meta l4proto gre', f'oifname != "{interface}"', 'drop'], ['meta l4proto icmp', f'ct mark {mark_hex}', 'return'], ['log prefix "[ipv4-OUT-filter-default-D]"','OUT-filter default-action drop', 'drop'], + ['chain VYOS_OUTPUT_raw'], + ['type filter hook output priority raw; policy accept;'], + ['udp', 'accept'], + ['OUT-raw default-action drop', 'drop'], + ['chain VYOS_PREROUTING_raw'], + ['type filter hook prerouting priority raw; policy accept;'], + ['tcp dport 23', 'drop'], + ['PRE-raw default-action accept', 'accept'], ['chain NAME_smoketest'], ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[ipv4-NAM-smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'], ['tcp flags syn / syn,ack', 'tcp dport 8888', 'log prefix "[ipv4-NAM-smoketest-2-R]" log level err', 'ip ttl > 102', 'reject'], @@ -446,16 +462,24 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'destination', 'port', '8888']) self.cli_set(['firewall', 'ipv6', 'forward', 'filter', 'rule', '2', 'inbound-interface', 'name', interface]) + 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', 'name', interface]) + self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'default-action', 'drop']) self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'default-log']) 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', 'name', interface]) - 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', 'name', interface]) + self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'default-action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'rule', '1', 'protocol', 'udp']) + + self.cli_set(['firewall', 'ipv6', 'prerouting', 'raw', 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv6', 'prerouting', 'raw', 'rule', '1', 'protocol', 'tcp']) + self.cli_set(['firewall', 'ipv6', 'prerouting', 'raw', 'rule', '1', 'destination', 'port', '23']) self.cli_commit() @@ -472,6 +496,14 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['type filter hook output priority filter; policy accept;'], ['meta l4proto gre', f'oifname "{interface}"', 'return'], ['log prefix "[ipv6-OUT-filter-default-D]"','OUT-filter default-action drop', 'drop'], + ['chain VYOS_IPV6_OUTPUT_raw'], + ['type filter hook output priority raw; policy accept;'], + ['udp', 'accept'], + ['OUT-raw default-action drop', 'drop'], + ['chain VYOS_IPV6_PREROUTING_raw'], + ['type filter hook prerouting priority raw; policy accept;'], + ['tcp dport 23', 'drop'], + ['PRE-raw default-action accept', 'accept'], [f'chain NAME6_{name}'], ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[ipv6-NAM-v6-smoketest-1-A]" log level crit', 'accept'], [f'"{name} default-action drop"', f'log prefix "[ipv6-{name}-default-D]"', 'drop'], diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index e96e57154..acf3805d2 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -351,7 +351,7 @@ def verify(firewall): verify_nested_group(group_name, group, groups, []) if 'ipv4' in firewall: - for name in ['name','forward','input','output']: + for name in ['name','forward','input','output', 'prerouting']: 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: @@ -371,7 +371,7 @@ def verify(firewall): verify_rule(firewall, rule_conf, False) if 'ipv6' in firewall: - for name in ['name','forward','input','output']: + for name in ['name','forward','input','output', 'prerouting']: 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: diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py index 031fe63b0..d9c38fd95 100755 --- a/src/conf_mode/system_conntrack.py +++ b/src/conf_mode/system_conntrack.py @@ -18,6 +18,7 @@ import os from sys import exit +from vyos.base import Warning from vyos.config import Config from vyos.configdep import set_dependents, call_dependents from vyos.utils.dict import dict_search @@ -165,6 +166,8 @@ def verify(conntrack): if not group_obj: Warning(f'{error_group} "{group_name}" has no members!') + Warning(f'It is prefered to defined {inet} conntrack ignore rules in the section') + if dict_search_args(conntrack, 'timeout', 'custom', inet, 'rule') != None: for rule, rule_config in conntrack['timeout']['custom'][inet]['rule'].items(): if 'protocol' not in rule_config: -- cgit v1.2.3 From 770edf016838523c248e3c8a36c5f327a0b98415 Mon Sep 17 00:00:00 2001 From: Nicolas Fort Date: Fri, 24 May 2024 16:44:41 +0000 Subject: T3900: T6394: extend functionalities in firewall; move netfilter sysctl timeout parameters defined in conntrack to firewall global-opton section. --- data/templates/conntrack/sysctl.conf.j2 | 20 +-- data/templates/firewall/sysctl-firewall.conf.j2 | 28 ++++ .../conntrack/timeout-common-protocols.xml.i | 172 --------------------- .../include/firewall/action-and-notrack.xml.i | 2 +- .../include/firewall/global-options.xml.i | 8 + .../firewall/timeout-common-protocols.xml.i | 171 ++++++++++++++++++++ .../include/version/firewall-version.xml.i | 2 +- interface-definitions/system_conntrack.xml.in | 1 - smoketest/scripts/cli/test_firewall.py | 96 +++++++++++- smoketest/scripts/cli/test_system_conntrack.py | 60 ------- src/conf_mode/firewall.py | 39 +---- src/conf_mode/system_conntrack.py | 2 +- src/migration-scripts/firewall/15-to-16 | 55 +++++++ 13 files changed, 363 insertions(+), 293 deletions(-) create mode 100644 data/templates/firewall/sysctl-firewall.conf.j2 delete mode 100644 interface-definitions/include/conntrack/timeout-common-protocols.xml.i create mode 100644 interface-definitions/include/firewall/timeout-common-protocols.xml.i create mode 100755 src/migration-scripts/firewall/15-to-16 diff --git a/data/templates/conntrack/sysctl.conf.j2 b/data/templates/conntrack/sysctl.conf.j2 index 986f75c61..554512f4d 100644 --- a/data/templates/conntrack/sysctl.conf.j2 +++ b/data/templates/conntrack/sysctl.conf.j2 @@ -3,25 +3,7 @@ net.netfilter.nf_conntrack_expect_max = {{ expect_table_size }} net.netfilter.nf_conntrack_max = {{ table_size }} - net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }} - net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }} net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }} - -net.netfilter.nf_conntrack_icmp_timeout = {{ timeout.icmp }} -net.netfilter.nf_conntrack_generic_timeout = {{ timeout.other }} - -net.netfilter.nf_conntrack_tcp_timeout_close_wait = {{ timeout.tcp.close_wait }} -net.netfilter.nf_conntrack_tcp_timeout_close = {{ timeout.tcp.close }} -net.netfilter.nf_conntrack_tcp_timeout_established = {{ timeout.tcp.established }} -net.netfilter.nf_conntrack_tcp_timeout_fin_wait = {{ timeout.tcp.fin_wait }} -net.netfilter.nf_conntrack_tcp_timeout_last_ack = {{ timeout.tcp.last_ack }} -net.netfilter.nf_conntrack_tcp_timeout_syn_recv = {{ timeout.tcp.syn_recv }} -net.netfilter.nf_conntrack_tcp_timeout_syn_sent = {{ timeout.tcp.syn_sent }} -net.netfilter.nf_conntrack_tcp_timeout_time_wait = {{ timeout.tcp.time_wait }} - -net.netfilter.nf_conntrack_udp_timeout = {{ timeout.udp.other }} -net.netfilter.nf_conntrack_udp_timeout_stream = {{ timeout.udp.stream }} - -net.netfilter.nf_conntrack_acct = {{ '1' if flow_accounting is vyos_defined else '0' }} +net.netfilter.nf_conntrack_acct = {{ '1' if flow_accounting is vyos_defined else '0' }} \ No newline at end of file diff --git a/data/templates/firewall/sysctl-firewall.conf.j2 b/data/templates/firewall/sysctl-firewall.conf.j2 new file mode 100644 index 000000000..b9c3311e2 --- /dev/null +++ b/data/templates/firewall/sysctl-firewall.conf.j2 @@ -0,0 +1,28 @@ +# Autogenerated by firewall.py + +# gloabl options +net.ipv4.icmp_echo_ignore_all = {{ 0 if global_options.all_ping == 'enable' else 1 }} +net.ipv4.icmp_echo_ignore_broadcasts = {{ 0 if global_options.broadcast_ping == 'enable' else 1 }} +net.ipv4.conf.all.bc_forwarding = {{ 1 if global_options.directed_broadcast == 'enable' else 0 }} +net.ipv4.conf.*.accept_source_route = {{ 1 if global_options.ip_src_route == 'enable' else 0 }} +net.ipv6.conf.*.accept_redirects = {{ 1 if global_options.ipv6_receive_redirects == 'enable' else 0 }} +net.ipv6.conf.*.accept_source_route = {{ 0 if global_options.ipv6_src_route == 'enable' else -1 }} +net.ipv4.conf.all.log_martians = {{ 1 if global_options.log_martians == 'enable' else 0 }} +net.ipv4.conf.*.accept_redirects = {{ 1 if global_options.receive_redirects == 'enable' else 0 }} +net.ipv4.conf.*.send_redirects = {{ 1 if global_options.send_redirects == 'enable' else 0 }} +net.ipv4.tcp_syncookies = {{ 1 if global_options.syn_cookies == 'enable' else 0 }} +net.ipv4.tcp_rfc1337 = {{ 1 if global_options.twa_hazards_protection == 'enable' else 0 }} + +## Timeout values: +net.netfilter.nf_conntrack_icmp_timeout = {{ global_options.timeout.icmp }} +net.netfilter.nf_conntrack_generic_timeout = {{ global_options.timeout.other }} +net.netfilter.nf_conntrack_tcp_timeout_close_wait = {{ global_options.timeout.tcp.close_wait }} +net.netfilter.nf_conntrack_tcp_timeout_close = {{ global_options.timeout.tcp.close }} +net.netfilter.nf_conntrack_tcp_timeout_established = {{ global_options.timeout.tcp.established }} +net.netfilter.nf_conntrack_tcp_timeout_fin_wait = {{ global_options.timeout.tcp.fin_wait }} +net.netfilter.nf_conntrack_tcp_timeout_last_ack = {{ global_options.timeout.tcp.last_ack }} +net.netfilter.nf_conntrack_tcp_timeout_syn_recv = {{ global_options.timeout.tcp.syn_recv }} +net.netfilter.nf_conntrack_tcp_timeout_syn_sent = {{ global_options.timeout.tcp.syn_sent }} +net.netfilter.nf_conntrack_tcp_timeout_time_wait = {{ global_options.timeout.tcp.time_wait }} +net.netfilter.nf_conntrack_udp_timeout = {{ global_options.timeout.udp.other }} +net.netfilter.nf_conntrack_udp_timeout_stream = {{ global_options.timeout.udp.stream }} diff --git a/interface-definitions/include/conntrack/timeout-common-protocols.xml.i b/interface-definitions/include/conntrack/timeout-common-protocols.xml.i deleted file mode 100644 index 2676d846e..000000000 --- a/interface-definitions/include/conntrack/timeout-common-protocols.xml.i +++ /dev/null @@ -1,172 +0,0 @@ - - - - ICMP timeout in seconds - - u32:1-21474836 - ICMP timeout in seconds - - - - - - 30 - - - - Generic connection timeout in seconds - - u32:1-21474836 - Generic connection timeout in seconds - - - - - - 600 - - - - TCP connection timeout options - - - - - TCP CLOSE-WAIT timeout in seconds - - u32:1-21474836 - TCP CLOSE-WAIT timeout in seconds - - - - - - 60 - - - - TCP CLOSE timeout in seconds - - u32:1-21474836 - TCP CLOSE timeout in seconds - - - - - - 10 - - - - TCP ESTABLISHED timeout in seconds - - u32:1-21474836 - TCP ESTABLISHED timeout in seconds - - - - - - 432000 - - - - TCP FIN-WAIT timeout in seconds - - u32:1-21474836 - TCP FIN-WAIT timeout in seconds - - - - - - 120 - - - - TCP LAST-ACK timeout in seconds - - u32:1-21474836 - TCP LAST-ACK timeout in seconds - - - - - - 30 - - - - TCP SYN-RECEIVED timeout in seconds - - u32:1-21474836 - TCP SYN-RECEIVED timeout in seconds - - - - - - 60 - - - - TCP SYN-SENT timeout in seconds - - u32:1-21474836 - TCP SYN-SENT timeout in seconds - - - - - - 120 - - - - TCP TIME-WAIT timeout in seconds - - u32:1-21474836 - TCP TIME-WAIT timeout in seconds - - - - - - 120 - - - - - - UDP timeout options - - - - - UDP generic timeout in seconds - - u32:1-21474836 - UDP generic timeout in seconds - - - - - - 30 - - - - UDP stream timeout in seconds - - u32:1-21474836 - UDP stream timeout in seconds - - - - - - 180 - - - - diff --git a/interface-definitions/include/firewall/action-and-notrack.xml.i b/interface-definitions/include/firewall/action-and-notrack.xml.i index e063c58d5..de11f7dd5 100644 --- a/interface-definitions/include/firewall/action-and-notrack.xml.i +++ b/interface-definitions/include/firewall/action-and-notrack.xml.i @@ -35,7 +35,7 @@ notrack - Igone connection tracking + Ignore connection tracking (accept|continue|jump|notrack|reject|return|drop|queue) diff --git a/interface-definitions/include/firewall/global-options.xml.i b/interface-definitions/include/firewall/global-options.xml.i index 9cd0b3239..9039b76fd 100644 --- a/interface-definitions/include/firewall/global-options.xml.i +++ b/interface-definitions/include/firewall/global-options.xml.i @@ -244,6 +244,14 @@ enable + + + Connection timeout options + + + #include + + RFC1337 TCP TIME-WAIT assasination hazards protection diff --git a/interface-definitions/include/firewall/timeout-common-protocols.xml.i b/interface-definitions/include/firewall/timeout-common-protocols.xml.i new file mode 100644 index 000000000..037d7d2b1 --- /dev/null +++ b/interface-definitions/include/firewall/timeout-common-protocols.xml.i @@ -0,0 +1,171 @@ + + + + ICMP timeout in seconds + + u32:1-21474836 + ICMP timeout in seconds + + + + + + 30 + + + + Generic connection timeout in seconds + + u32:1-21474836 + Generic connection timeout in seconds + + + + + + 600 + + + + TCP connection timeout options + + + + + TCP CLOSE-WAIT timeout in seconds + + u32:1-21474836 + TCP CLOSE-WAIT timeout in seconds + + + + + + 60 + + + + TCP CLOSE timeout in seconds + + u32:1-21474836 + TCP CLOSE timeout in seconds + + + + + + 10 + + + + TCP ESTABLISHED timeout in seconds + + u32:1-21474836 + TCP ESTABLISHED timeout in seconds + + + + + + 432000 + + + + TCP FIN-WAIT timeout in seconds + + u32:1-21474836 + TCP FIN-WAIT timeout in seconds + + + + + + 120 + + + + TCP LAST-ACK timeout in seconds + + u32:1-21474836 + TCP LAST-ACK timeout in seconds + + + + + + 30 + + + + TCP SYN-RECEIVED timeout in seconds + + u32:1-21474836 + TCP SYN-RECEIVED timeout in seconds + + + + + + 60 + + + + TCP SYN-SENT timeout in seconds + + u32:1-21474836 + TCP SYN-SENT timeout in seconds + + + + + + 120 + + + + TCP TIME-WAIT timeout in seconds + + u32:1-21474836 + TCP TIME-WAIT timeout in seconds + + + + + + 120 + + + + + + UDP timeout options + + + + + UDP generic timeout in seconds + + u32:1-21474836 + UDP generic timeout in seconds + + + + + + 30 + + + + UDP stream timeout in seconds + + u32:1-21474836 + UDP stream timeout in seconds + + + + + + 180 + + + diff --git a/interface-definitions/include/version/firewall-version.xml.i b/interface-definitions/include/version/firewall-version.xml.i index fa8e26f78..560ed9e5f 100644 --- a/interface-definitions/include/version/firewall-version.xml.i +++ b/interface-definitions/include/version/firewall-version.xml.i @@ -1,3 +1,3 @@ - + diff --git a/interface-definitions/system_conntrack.xml.in b/interface-definitions/system_conntrack.xml.in index 219c6e28e..33aa832a8 100644 --- a/interface-definitions/system_conntrack.xml.in +++ b/interface-definitions/system_conntrack.xml.in @@ -509,7 +509,6 @@ - #include diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index 5cf2b2146..0943d8e24 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -23,6 +23,7 @@ from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError from vyos.utils.process import run +from vyos.utils.file import read_file sysfs_config = { 'all_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_all', 'default': '0', 'test_value': 'disable'}, @@ -38,6 +39,10 @@ sysfs_config = { 'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337', 'default': '0', 'test_value': 'enable'} } +def get_sysctl(parameter): + tmp = parameter.replace(r'.', r'/') + return read_file(f'/proc/sys/{tmp}') + class TestFirewall(VyOSUnitTestSHIM.TestCase): @classmethod def setUpClass(cls): @@ -240,7 +245,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv4', 'output', 'raw', 'rule', '1', 'action', 'accept']) self.cli_set(['firewall', 'ipv4', 'output', 'raw', 'rule', '1', 'protocol', 'udp']) - self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'action', 'drop']) + self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'action', 'notrack']) self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'protocol', 'tcp']) self.cli_set(['firewall', 'ipv4', 'prerouting', 'raw', 'rule', '1', 'destination', 'port', '23']) @@ -270,7 +275,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['OUT-raw default-action drop', 'drop'], ['chain VYOS_PREROUTING_raw'], ['type filter hook prerouting priority raw; policy accept;'], - ['tcp dport 23', 'drop'], + ['tcp dport 23', 'notrack'], ['PRE-raw default-action accept', 'accept'], ['chain NAME_smoketest'], ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[ipv4-NAM-smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'], @@ -474,7 +479,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.cli_set(['firewall', 'ipv6', 'output', 'filter', 'rule', '3', 'outbound-interface', 'name', interface]) self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'default-action', 'drop']) - self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'rule', '1', 'action', 'notrack']) self.cli_set(['firewall', 'ipv6', 'output', 'raw', 'rule', '1', 'protocol', 'udp']) self.cli_set(['firewall', 'ipv6', 'prerouting', 'raw', 'rule', '1', 'action', 'drop']) @@ -498,7 +503,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['log prefix "[ipv6-OUT-filter-default-D]"','OUT-filter default-action drop', 'drop'], ['chain VYOS_IPV6_OUTPUT_raw'], ['type filter hook output priority raw; policy accept;'], - ['udp', 'accept'], + ['udp', 'notrack'], ['OUT-raw default-action drop', 'drop'], ['chain VYOS_IPV6_PREROUTING_raw'], ['type filter hook prerouting priority raw; policy accept;'], @@ -770,6 +775,89 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): with open(path, 'r') as f: self.assertNotEqual(f.read().strip(), conf['default'], msg=path) + def test_timeout_sysctl(self): + timeout_config = { + 'net.netfilter.nf_conntrack_icmp_timeout' :{ + 'cli' : ['global-options', 'timeout', 'icmp'], + 'test_value' : '180', + 'default_value' : '30', + }, + 'net.netfilter.nf_conntrack_generic_timeout' :{ + 'cli' : ['global-options', 'timeout', 'other'], + 'test_value' : '1200', + 'default_value' : '600', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_close_wait' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'close-wait'], + 'test_value' : '30', + 'default_value' : '60', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_close' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'close'], + 'test_value' : '20', + 'default_value' : '10', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_established' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'established'], + 'test_value' : '1000', + 'default_value' : '432000', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_fin_wait' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'fin-wait'], + 'test_value' : '240', + 'default_value' : '120', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_last_ack' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'last-ack'], + 'test_value' : '300', + 'default_value' : '30', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_syn_recv' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'syn-recv'], + 'test_value' : '100', + 'default_value' : '60', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_syn_sent' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'syn-sent'], + 'test_value' : '300', + 'default_value' : '120', + }, + 'net.netfilter.nf_conntrack_tcp_timeout_time_wait' :{ + 'cli' : ['global-options', 'timeout', 'tcp', 'time-wait'], + 'test_value' : '303', + 'default_value' : '120', + }, + 'net.netfilter.nf_conntrack_udp_timeout' :{ + 'cli' : ['global-options', 'timeout', 'udp', 'other'], + 'test_value' : '90', + 'default_value' : '30', + }, + 'net.netfilter.nf_conntrack_udp_timeout_stream' :{ + 'cli' : ['global-options', 'timeout', 'udp', 'stream'], + 'test_value' : '200', + 'default_value' : '180', + }, + } + + for parameter, parameter_config in timeout_config.items(): + self.cli_set(['firewall'] + parameter_config['cli'] + [parameter_config['test_value']]) + + # commit changes + self.cli_commit() + + # validate configuration + for parameter, parameter_config in timeout_config.items(): + tmp = parameter_config['test_value'] + self.assertEqual(get_sysctl(f'{parameter}'), tmp) + + # delete all configuration options and revert back to defaults + self.cli_delete(['firewall', 'global-options', 'timeout']) + self.cli_commit() + + # validate configuration + for parameter, parameter_config in timeout_config.items(): + self.assertEqual(get_sysctl(f'{parameter}'), parameter_config['default_value']) + ### Zone def test_zone_basic(self): self.cli_set(['firewall', 'ipv4', 'name', 'smoketest', 'default-action', 'drop']) diff --git a/smoketest/scripts/cli/test_system_conntrack.py b/smoketest/scripts/cli/test_system_conntrack.py index c6d8a5436..3ae7b6217 100755 --- a/smoketest/scripts/cli/test_system_conntrack.py +++ b/smoketest/scripts/cli/test_system_conntrack.py @@ -68,66 +68,6 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase): 'test_value' : '128', 'default_value' : '3', }, - 'net.netfilter.nf_conntrack_icmp_timeout' :{ - 'cli' : ['timeout', 'icmp'], - 'test_value' : '180', - 'default_value' : '30', - }, - 'net.netfilter.nf_conntrack_generic_timeout' :{ - 'cli' : ['timeout', 'other'], - 'test_value' : '1200', - 'default_value' : '600', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_close_wait' :{ - 'cli' : ['timeout', 'tcp', 'close-wait'], - 'test_value' : '30', - 'default_value' : '60', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_close' :{ - 'cli' : ['timeout', 'tcp', 'close'], - 'test_value' : '20', - 'default_value' : '10', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_established' :{ - 'cli' : ['timeout', 'tcp', 'established'], - 'test_value' : '1000', - 'default_value' : '432000', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_fin_wait' :{ - 'cli' : ['timeout', 'tcp', 'fin-wait'], - 'test_value' : '240', - 'default_value' : '120', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_last_ack' :{ - 'cli' : ['timeout', 'tcp', 'last-ack'], - 'test_value' : '300', - 'default_value' : '30', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_syn_recv' :{ - 'cli' : ['timeout', 'tcp', 'syn-recv'], - 'test_value' : '100', - 'default_value' : '60', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_syn_sent' :{ - 'cli' : ['timeout', 'tcp', 'syn-sent'], - 'test_value' : '300', - 'default_value' : '120', - }, - 'net.netfilter.nf_conntrack_tcp_timeout_time_wait' :{ - 'cli' : ['timeout', 'tcp', 'time-wait'], - 'test_value' : '303', - 'default_value' : '120', - }, - 'net.netfilter.nf_conntrack_udp_timeout' :{ - 'cli' : ['timeout', 'udp', 'other'], - 'test_value' : '90', - 'default_value' : '30', - }, - 'net.netfilter.nf_conntrack_udp_timeout_stream' :{ - 'cli' : ['timeout', 'udp', 'stream'], - 'test_value' : '200', - 'default_value' : '180', - }, } for parameter, parameter_config in conntrack_config.items(): diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index acf3805d2..4c289b921 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -33,6 +33,7 @@ from vyos.template import render from vyos.utils.dict import dict_search_args from vyos.utils.dict import dict_search_recursive from vyos.utils.process import call +from vyos.utils.process import cmd from vyos.utils.process import rc_cmd from vyos import ConfigError from vyos import airbag @@ -40,20 +41,7 @@ from vyos import airbag airbag.enable() nftables_conf = '/run/nftables.conf' - -sysfs_config = { - 'all_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_all', 'enable': '0', 'disable': '1'}, - 'broadcast_ping': {'sysfs': '/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts', 'enable': '0', 'disable': '1'}, - 'directed_broadcast' : {'sysfs': '/proc/sys/net/ipv4/conf/all/bc_forwarding', 'enable': '1', 'disable': '0'}, - 'ip_src_route': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_source_route'}, - 'ipv6_receive_redirects': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_redirects'}, - 'ipv6_src_route': {'sysfs': '/proc/sys/net/ipv6/conf/*/accept_source_route', 'enable': '0', 'disable': '-1'}, - 'log_martians': {'sysfs': '/proc/sys/net/ipv4/conf/all/log_martians'}, - 'receive_redirects': {'sysfs': '/proc/sys/net/ipv4/conf/*/accept_redirects'}, - 'send_redirects': {'sysfs': '/proc/sys/net/ipv4/conf/*/send_redirects'}, - 'syn_cookies': {'sysfs': '/proc/sys/net/ipv4/tcp_syncookies'}, - 'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337'} -} +sysctl_file = r'/run/sysctl/10-vyos-firewall.conf' valid_groups = [ 'address_group', @@ -467,33 +455,16 @@ def generate(firewall): local_zone_conf['from_local'][zone] = zone_conf['from'][local_zone] render(nftables_conf, 'firewall/nftables.j2', firewall) + render(sysctl_file, 'firewall/sysctl-firewall.conf.j2', firewall) return None -def apply_sysfs(firewall): - for name, conf in sysfs_config.items(): - paths = glob(conf['sysfs']) - value = None - - 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': - value = '1' - elif conf_value == 'disable': - value = '0' - - if value: - for path in paths: - with open(path, 'w') as f: - f.write(value) - def apply(firewall): install_result, output = rc_cmd(f'nft --file {nftables_conf}') if install_result == 1: raise ConfigError(f'Failed to apply firewall: {output}') - apply_sysfs(firewall) + # Apply firewall global-options sysctl settings + cmd(f'sysctl -f {sysctl_file}') call_dependents() diff --git a/src/conf_mode/system_conntrack.py b/src/conf_mode/system_conntrack.py index d9c38fd95..aa290788c 100755 --- a/src/conf_mode/system_conntrack.py +++ b/src/conf_mode/system_conntrack.py @@ -166,7 +166,7 @@ def verify(conntrack): if not group_obj: Warning(f'{error_group} "{group_name}" has no members!') - Warning(f'It is prefered to defined {inet} conntrack ignore rules in the section') + Warning(f'It is prefered to define {inet} conntrack ignore rules in section') if dict_search_args(conntrack, 'timeout', 'custom', inet, 'rule') != None: for rule, rule_config in conntrack['timeout']['custom'][inet]['rule'].items(): diff --git a/src/migration-scripts/firewall/15-to-16 b/src/migration-scripts/firewall/15-to-16 new file mode 100755 index 000000000..7c8d38fe6 --- /dev/null +++ b/src/migration-scripts/firewall/15-to-16 @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022-2024 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# T6394: Migrate conntrack timeout options to firewall global-options + # from: set system conntrack timeout .. + # to: set firewall global-options timeout ... + +from sys import argv +from sys import exit + +from vyos.configtree import ConfigTree + +if len(argv) < 2: + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +firewall_base = ['firewall', 'global-options'] +conntrack_base = ['system', 'conntrack', 'timeout'] +config = ConfigTree(config_file) + +if not config.exists(conntrack_base): + # Nothing to do + exit(0) + +for protocol in ['icmp', 'tcp', 'udp', 'other']: + if config.exists(conntrack_base + [protocol]): + if not config.exists(firewall_base): + config.set(firewall_base + ['timeout']) + config.copy(conntrack_base + [protocol], firewall_base + ['timeout', protocol]) + config.delete(conntrack_base + [protocol]) + +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