From fd15f9d2ab6a7e5bbc07ff2e8b10c064984492ce Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Thu, 18 Aug 2022 17:09:17 +0000 Subject: firewall: T4622: Add TCP MSS option Ability to drop|accept packets based on TCP MSS size set firewall name rule tcp mss '501-1460' --- interface-definitions/include/firewall/tcp-flags.xml.i | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'interface-definitions/include') diff --git a/interface-definitions/include/firewall/tcp-flags.xml.i b/interface-definitions/include/firewall/tcp-flags.xml.i index b99896687..5a7b5a8d3 100644 --- a/interface-definitions/include/firewall/tcp-flags.xml.i +++ b/interface-definitions/include/firewall/tcp-flags.xml.i @@ -114,6 +114,23 @@ + + + Maximum segment size (MSS) + + u32:1-16384 + Maximum segment size + + + <min>-<max> + TCP MSS range (use '-' as delimiter) + + + + + + + -- cgit v1.2.3 From b752c8779712ec4e1c3b653081768361359c57f7 Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Sat, 20 Aug 2022 16:26:55 +0000 Subject: nat66: T4631: Add port and protocol to nat66 Ability to configure src/dst/translation port and protocol for SNAT and DNAT IPv6 --- data/templates/firewall/nftables-nat66.j2 | 41 ++++++++++++++++++++++++ interface-definitions/include/nat/protocol.xml.i | 34 ++++++++++++++++++++ interface-definitions/nat66.xml.in | 8 +++++ 3 files changed, 83 insertions(+) create mode 100644 interface-definitions/include/nat/protocol.xml.i (limited to 'interface-definitions/include') diff --git a/data/templates/firewall/nftables-nat66.j2 b/data/templates/firewall/nftables-nat66.j2 index 2fe04b4ff..28714c7a7 100644 --- a/data/templates/firewall/nftables-nat66.j2 +++ b/data/templates/firewall/nftables-nat66.j2 @@ -7,6 +7,17 @@ {% set src_prefix = 'ip6 saddr ' ~ config.source.prefix.replace('!','!= ') if config.source.prefix is vyos_defined %} {% set source_address = 'ip6 saddr ' ~ config.source.address.replace('!','!= ') if config.source.address is vyos_defined %} {% set dest_address = 'ip6 daddr ' ~ config.destination.address.replace('!','!= ') if config.destination.address is vyos_defined %} +{# Port #} +{% if config.source.port is vyos_defined and config.source.port.startswith('!') %} +{% set src_port = 'sport != { ' ~ config.source.port.replace('!','') ~ ' }' %} +{% else %} +{% set src_port = 'sport { ' ~ config.source.port ~ ' }' if config.source.port is vyos_defined %} +{% endif %} +{% if config.destination.port is vyos_defined and config.destination.port.startswith('!') %} +{% set dst_port = 'dport != { ' ~ config.destination.port.replace('!','') ~ ' }' %} +{% else %} +{% set dst_port = 'dport { ' ~ config.destination.port ~ ' }' if config.destination.port is vyos_defined %} +{% endif %} {% if chain is vyos_defined('PREROUTING') %} {% set comment = 'DST-NAT66-' ~ rule %} {% set base_log = '[NAT66-DST-' ~ rule %} @@ -36,6 +47,14 @@ {% endif %} {% set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined else '' %} {% endif %} +{% set trns_port = ':' ~ config.translation.port if config.translation.port is vyos_defined %} +{# protocol has a default value thus it is always present #} +{% if config.protocol is vyos_defined('tcp_udp') %} +{% set protocol = 'tcp' %} +{% set comment = comment ~ ' tcp_udp' %} +{% else %} +{% set protocol = config.protocol %} +{% endif %} {% if config.log is vyos_defined %} {% if config.translation.address is vyos_defined('masquerade') %} {% set log = base_log ~ '-MASQ]' %} @@ -43,6 +62,11 @@ {% set log = base_log ~ ']' %} {% endif %} {% endif %} +{% if config.exclude is vyos_defined %} +{# rule has been marked as 'exclude' thus we simply return here #} +{% set trns_addr = 'return' %} +{% set trns_port = '' %} +{% endif %} {% set output = 'add rule ip6 nat ' ~ chain ~ interface %} {# Count packets #} {% set output = output ~ ' counter' %} @@ -54,12 +78,18 @@ {% if src_prefix is vyos_defined %} {% set output = output ~ ' ' ~ src_prefix %} {% endif %} +{% if dst_port is vyos_defined %} +{% set output = output ~ ' ' ~ protocol ~ ' ' ~ dst_port %} +{% endif %} {% if dst_prefix is vyos_defined %} {% set output = output ~ ' ' ~ dst_prefix %} {% endif %} {% if source_address is vyos_defined %} {% set output = output ~ ' ' ~ source_address %} {% endif %} +{% if src_port is vyos_defined %} +{% set output = output ~ ' ' ~ protocol ~ ' ' ~ src_port %} +{% endif %} {% if dest_address is vyos_defined %} {% set output = output ~ ' ' ~ dest_address %} {% endif %} @@ -70,11 +100,22 @@ {% if trns_address is vyos_defined %} {% set output = output ~ ' ' ~ trns_address %} {% endif %} +{% if trns_port is vyos_defined %} +{# Do not add a whitespace here, translation port must be directly added after IP address #} +{# e.g. 2001:db8::1:3389 #} +{% set output = output ~ trns_port %} +{% endif %} {% if comment is vyos_defined %} {% set output = output ~ ' comment "' ~ comment ~ '"' %} {% endif %} {{ log_output if log_output is vyos_defined }} {{ output }} +{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #} +{% if config.protocol is vyos_defined('tcp_udp') %} +{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #} +{{ log_output | replace('tcp ', 'udp ') if log_output is vyos_defined }} +{{ output | replace('tcp ', 'udp ') }} +{% endif %} {% endmacro %} # Start with clean NAT table diff --git a/interface-definitions/include/nat/protocol.xml.i b/interface-definitions/include/nat/protocol.xml.i new file mode 100644 index 000000000..54e7ff00d --- /dev/null +++ b/interface-definitions/include/nat/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 + + + + + + + diff --git a/interface-definitions/nat66.xml.in b/interface-definitions/nat66.xml.in index bde1a6f8d..dab4543e0 100644 --- a/interface-definitions/nat66.xml.in +++ b/interface-definitions/nat66.xml.in @@ -50,6 +50,7 @@ + #include IPv6 destination prefix options @@ -72,6 +73,7 @@ + #include @@ -96,6 +98,7 @@ + #include @@ -128,6 +131,7 @@ + #include @@ -179,6 +183,7 @@ + #include IPv6 destination prefix options @@ -211,6 +216,7 @@ + #include @@ -245,6 +251,7 @@ + #include @@ -269,6 +276,7 @@ + #include -- cgit v1.2.3 From 74994f9b10588fce2cbd1acc9ec09fdbaf5ae8ad Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 30 Aug 2022 17:18:17 +0200 Subject: firewall: T3568: rename XML building blocks to match CLI node name --- interface-definitions/firewall.xml.in | 8 +++---- .../include/firewall/default-action.xml.i | 25 ++++++++++++++++++++++ .../include/firewall/enable-default-log.xml.i | 8 +++++++ .../include/firewall/name-default-action.xml.i | 25 ---------------------- .../include/firewall/name-default-log.xml.i | 8 ------- interface-definitions/policy-route.xml.in | 4 ++-- interface-definitions/zone-policy.xml.in | 2 +- 7 files changed, 40 insertions(+), 40 deletions(-) create mode 100644 interface-definitions/include/firewall/default-action.xml.i create mode 100644 interface-definitions/include/firewall/enable-default-log.xml.i delete mode 100644 interface-definitions/include/firewall/name-default-action.xml.i delete mode 100644 interface-definitions/include/firewall/name-default-log.xml.i (limited to 'interface-definitions/include') diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in index 2e9452dfd..d28abccd6 100644 --- a/interface-definitions/firewall.xml.in +++ b/interface-definitions/firewall.xml.in @@ -342,8 +342,8 @@ - #include - #include + #include + #include #include @@ -530,8 +530,8 @@ - #include - #include + #include + #include #include diff --git a/interface-definitions/include/firewall/default-action.xml.i b/interface-definitions/include/firewall/default-action.xml.i new file mode 100644 index 000000000..b11dfd2e8 --- /dev/null +++ b/interface-definitions/include/firewall/default-action.xml.i @@ -0,0 +1,25 @@ + + + + Default-action for rule-set + + drop reject accept + + + drop + Drop if no prior rules are hit + + + reject + Drop and notify source if no prior rules are hit + + + accept + Accept if no prior rules are hit + + + (drop|reject|accept) + + + + diff --git a/interface-definitions/include/firewall/enable-default-log.xml.i b/interface-definitions/include/firewall/enable-default-log.xml.i new file mode 100644 index 000000000..1e64edc6e --- /dev/null +++ b/interface-definitions/include/firewall/enable-default-log.xml.i @@ -0,0 +1,8 @@ + + + + Option to log packets hitting default-action + + + + \ No newline at end of file diff --git a/interface-definitions/include/firewall/name-default-action.xml.i b/interface-definitions/include/firewall/name-default-action.xml.i deleted file mode 100644 index 512b0296f..000000000 --- a/interface-definitions/include/firewall/name-default-action.xml.i +++ /dev/null @@ -1,25 +0,0 @@ - - - - Default-action for rule-set - - drop reject accept - - - drop - Drop if no prior rules are hit - - - reject - Drop and notify source if no prior rules are hit - - - accept - Accept if no prior rules are hit - - - (drop|reject|accept) - - - - diff --git a/interface-definitions/include/firewall/name-default-log.xml.i b/interface-definitions/include/firewall/name-default-log.xml.i deleted file mode 100644 index 1d0ff9497..000000000 --- a/interface-definitions/include/firewall/name-default-log.xml.i +++ /dev/null @@ -1,8 +0,0 @@ - - - - Option to log packets hitting default-action - - - - \ No newline at end of file diff --git a/interface-definitions/policy-route.xml.in b/interface-definitions/policy-route.xml.in index a10c9b08f..c2a9a8d94 100644 --- a/interface-definitions/policy-route.xml.in +++ b/interface-definitions/policy-route.xml.in @@ -12,7 +12,7 @@ #include - #include + #include Policy rule number @@ -61,7 +61,7 @@ #include - #include + #include Policy rule number diff --git a/interface-definitions/zone-policy.xml.in b/interface-definitions/zone-policy.xml.in index dca4c59d1..dc3408c3d 100644 --- a/interface-definitions/zone-policy.xml.in +++ b/interface-definitions/zone-policy.xml.in @@ -19,7 +19,7 @@ #include - #include + #include Default-action for traffic coming into this zone -- cgit v1.2.3 From 69f79beee2070906b68f2b910296c362e7216278 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 30 Aug 2022 17:36:19 +0200 Subject: firewall: T4655: implement XML defaultValue for name and ipv6-name This extends the implementation of commit 0cc7e0a49094 ("firewall: T4655: Fix default action 'drop' for the firewall") in a way that we can now also use the XML node under "firewall name" and "firewall ipv6-name". This is a much cleaner approach which also adds the default value automatically to the CLIs completion helper ("?"). --- .../include/firewall/default-action.xml.i | 1 + python/vyos/template.py | 2 +- src/conf_mode/firewall.py | 30 +++++++++++++++++++--- 3 files changed, 28 insertions(+), 5 deletions(-) (limited to 'interface-definitions/include') diff --git a/interface-definitions/include/firewall/default-action.xml.i b/interface-definitions/include/firewall/default-action.xml.i index b11dfd2e8..92a2fcaaf 100644 --- a/interface-definitions/include/firewall/default-action.xml.i +++ b/interface-definitions/include/firewall/default-action.xml.i @@ -21,5 +21,6 @@ (drop|reject|accept) + drop diff --git a/python/vyos/template.py b/python/vyos/template.py index 62303bd55..9804308c1 100644 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -550,7 +550,7 @@ def nft_rule(rule_conf, fw_name, rule_id, ip_name='ip'): @register_filter('nft_default_rule') def nft_default_rule(fw_conf, fw_name): output = ['counter'] - default_action = fw_conf.get('default_action', 'drop') + default_action = fw_conf['default_action'] if 'enable_default_log' in fw_conf: action_suffix = default_action[:1].upper() diff --git a/src/conf_mode/firewall.py b/src/conf_mode/firewall.py index 07eca722f..f0ea1a1e5 100755 --- a/src/conf_mode/firewall.py +++ b/src/conf_mode/firewall.py @@ -206,9 +206,31 @@ def get_config(config=None): firewall = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=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 tmp in ['name', 'ipv6_name']: + if tmp in default_values: + del default_values[tmp] + firewall = dict_merge(default_values, firewall) + # Merge in defaults for IPv4 ruleset + if 'name' in firewall: + default_values = defaults(base + ['name']) + for name in firewall['name']: + firewall['name'][name] = dict_merge(default_values, + firewall['name'][name]) + + # Merge in defaults for IPv6 ruleset + if 'ipv6_name' in firewall: + 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]) + firewall['policy_resync'] = bool('group' in firewall or node_changed(conf, base + ['group'])) firewall['interfaces'] = get_firewall_interfaces(conf) firewall['zone_policy'] = get_firewall_zones(conf) @@ -315,7 +337,7 @@ def verify_nested_group(group_name, group, groups, seen): if g in seen: raise ConfigError(f'Group "{group_name}" has a circular reference') - + seen.append(g) if 'include' in groups[g]: @@ -378,7 +400,7 @@ def cleanup_commands(firewall): if firewall['geoip_updated']: geoip_key = 'deleted_ipv6_name' if table == 'ip6 filter' else 'deleted_name' geoip_list = dict_search_args(firewall, 'geoip_updated', geoip_key) or [] - + json_str = cmd(f'nft -t -j list table {table}') obj = loads(json_str) @@ -420,7 +442,7 @@ def cleanup_commands(firewall): if set_name.startswith('GEOIP_CC_') and set_name in geoip_list: commands_sets.append(f'delete set {table} {set_name}') continue - + if set_name.startswith("RECENT_"): commands_sets.append(f'delete set {table} {set_name}') continue @@ -520,7 +542,7 @@ def apply(firewall): if install_result == 1: raise ConfigError('Failed to apply firewall') - # set fireall group domain-group xxx + # set firewall group domain-group xxx if 'group' in firewall: if 'domain_group' in firewall['group']: # T970 Enable a resolver (systemd daemon) that checks -- cgit v1.2.3