diff options
author | Viacheslav Hletenko <v.gletenko@vyos.io> | 2022-08-13 00:07:41 +0000 |
---|---|---|
committer | Viacheslav Hletenko <v.gletenko@vyos.io> | 2022-08-17 10:53:26 +0000 |
commit | 69bcdb9a680b33422d041fd03e70c25094bfa6a2 (patch) | |
tree | 845bd5bce027e72fd9dfba8f713c1e799bbdf9de /data/templates/firewall | |
parent | 466e3b192d15563bc21fc308fa7916eb5aae8664 (diff) | |
download | vyos-1x-69bcdb9a680b33422d041fd03e70c25094bfa6a2.tar.gz vyos-1x-69bcdb9a680b33422d041fd03e70c25094bfa6a2.zip |
nat: T538: Add static NAT one-to-one
Ability to set static NAT (one-to-one) in one rule
set nat static rule 10 destination address '203.0.113.0/24'
set nat static rule 10 inbound-interface 'eth0'
set nat static rule 10 translation address '192.0.2.0/24'
It will be enough for PREROUTING and POSTROUTING rules
Use a separate table 'vyos_static_nat' as SRC/DST rules and
STATIC rules can have the same rule number
Diffstat (limited to 'data/templates/firewall')
-rw-r--r-- | data/templates/firewall/nftables-static-nat.j2 | 115 | ||||
-rw-r--r-- | data/templates/firewall/nftables.j2 | 20 |
2 files changed, 135 insertions, 0 deletions
diff --git a/data/templates/firewall/nftables-static-nat.j2 b/data/templates/firewall/nftables-static-nat.j2 new file mode 100644 index 000000000..d3c43858f --- /dev/null +++ b/data/templates/firewall/nftables-static-nat.j2 @@ -0,0 +1,115 @@ +#!/usr/sbin/nft -f + +{% macro nat_rule(rule, config, chain) %} +{% set comment = '' %} +{% set base_log = '' %} + +{% if chain is vyos_defined('PREROUTING') %} +{% set comment = 'STATIC-NAT-' ~ rule %} +{% set base_log = '[NAT-DST-' ~ rule %} +{% set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address is vyos_defined %} +{# support 1:1 network translation #} +{% if config.translation.address | is_ip_network %} +{% set trns_addr = 'dnat ip prefix to ip daddr map { ' ~ config.destination.address ~ ' : ' ~ config.translation.address ~ ' }' %} +{# we can now clear out the dst_addr part as it's already covered in aboves map #} +{% else %} +{% set dst_addr = 'ip daddr ' ~ config.destination.address if config.destination.address is vyos_defined %} +{% set trns_addr = 'dnat to ' ~ config.translation.address %} +{% endif %} +{% endif %} +{% elif chain is vyos_defined('POSTROUTING') %} +{% set comment = 'STATIC-NAT-' ~ rule %} +{% set base_log = '[NAT-SRC-' ~ rule %} +{% set interface = ' oifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address is vyos_defined %} +{# support 1:1 network translation #} +{% if config.translation.address | is_ip_network %} +{% set trns_addr = 'snat ip prefix to ip saddr map { ' ~ config.translation.address ~ ' : ' ~ config.destination.address ~ ' }' %} +{# we can now clear out the src_addr part as it's already covered in aboves map #} +{% else %} +{% set src_addr = 'ip saddr ' ~ config.translation.address if config.translation.address is vyos_defined %} +{% set trns_addr = 'snat to ' ~ config.destination.address %} +{% endif %} +{% 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 %} + +{% if config.translation.options is vyos_defined %} +{% if config.translation.options.address_mapping is vyos_defined('persistent') %} +{% set trns_opts_addr = 'persistent' %} +{% endif %} +{% if config.translation.options.port_mapping is vyos_defined('random') %} +{% set trns_opts_port = 'random' %} +{% elif config.translation.options.port_mapping is vyos_defined('fully-random') %} +{% set trns_opts_port = 'fully-random' %} +{% endif %} +{% endif %} + +{% if trns_opts_addr is vyos_defined and trns_opts_port is vyos_defined %} +{% set trns_opts = trns_opts_addr ~ ',' ~ trns_opts_port %} +{% elif trns_opts_addr is vyos_defined %} +{% set trns_opts = trns_opts_addr %} +{% elif trns_opts_port is vyos_defined %} +{% set trns_opts = trns_opts_port %} +{% endif %} + +{% set output = 'add rule ip vyos_static_nat ' ~ chain ~ interface %} + +{% if dst_addr is vyos_defined %} +{% set output = output ~ ' ' ~ dst_addr %} +{% endif %} +{% if src_addr is vyos_defined %} +{% set output = output ~ ' ' ~ src_addr %} +{% endif %} + +{# Count packets #} +{% set output = output ~ ' counter' %} +{# Special handling of log option, we must repeat the entire rule before the #} +{# NAT translation options are added, this is essential #} +{% if log is vyos_defined %} +{% set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %} +{% endif %} +{% if trns_addr is vyos_defined %} +{% set output = output ~ ' ' ~ trns_addr %} +{% endif %} + +{% if trns_opts is vyos_defined %} +{% set output = output ~ ' ' ~ trns_opts %} +{% endif %} +{% if comment is vyos_defined %} +{% set output = output ~ ' comment "' ~ comment ~ '"' %} +{% endif %} +{{ log_output if log_output is vyos_defined }} +{{ output }} +{% endmacro %} + +# Start with clean STATIC NAT chains +flush chain ip vyos_static_nat PREROUTING +flush chain ip vyos_static_nat POSTROUTING + +{# NAT if enabled - add targets to nftables #} + +# +# Destination NAT rules build up here +# +add rule ip vyos_static_nat PREROUTING counter jump VYOS_PRE_DNAT_HOOK +{% if static.rule is vyos_defined %} +{% for rule, config in static.rule.items() if config.disable is not vyos_defined %} +{{ nat_rule(rule, config, 'PREROUTING') }} +{% endfor %} +{% endif %} +# +# Source NAT rules build up here +# +add rule ip vyos_static_nat POSTROUTING counter jump VYOS_PRE_SNAT_HOOK +{% if static.rule is vyos_defined %} +{% for rule, config in static.rule.items() if config.disable is not vyos_defined %} +{{ nat_rule(rule, config, 'POSTROUTING') }} +{% endfor %} +{% endif %} diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index b91fed615..5971e1bbc 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -181,6 +181,26 @@ table ip nat { } } +table ip vyos_static_nat { + chain PREROUTING { + type nat hook prerouting priority -100; policy accept; + counter jump VYOS_PRE_DNAT_HOOK + } + + chain POSTROUTING { + type nat hook postrouting priority 100; policy accept; + counter jump VYOS_PRE_SNAT_HOOK + } + + chain VYOS_PRE_DNAT_HOOK { + return + } + + chain VYOS_PRE_SNAT_HOOK { + return + } +} + table ip6 nat { chain PREROUTING { type nat hook prerouting priority -100; policy accept; |