summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/firewall/nftables-nat.j218
-rw-r--r--data/templates/firewall/nftables-static-nat.j218
-rwxr-xr-xsmoketest/scripts/cli/test_nat.py6
-rwxr-xr-xsrc/conf_mode/nat.py12
4 files changed, 38 insertions, 16 deletions
diff --git a/data/templates/firewall/nftables-nat.j2 b/data/templates/firewall/nftables-nat.j2
index 55fe6024b..c5c0a2c86 100644
--- a/data/templates/firewall/nftables-nat.j2
+++ b/data/templates/firewall/nftables-nat.j2
@@ -24,6 +24,7 @@ add rule ip raw NAT_CONNTRACK counter accept
{% if first_install is not vyos_defined %}
delete table ip vyos_nat
{% endif %}
+{% if deleted is not vyos_defined %}
table ip vyos_nat {
#
# Destination NAT rules build up here
@@ -31,11 +32,11 @@ table ip vyos_nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
counter jump VYOS_PRE_DNAT_HOOK
-{% if destination.rule is vyos_defined %}
-{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
+{% if destination.rule is vyos_defined %}
+{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %}
{{ config | nat_rule(rule, 'destination') }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
}
#
@@ -44,11 +45,11 @@ table ip vyos_nat {
chain POSTROUTING {
type nat hook postrouting priority 100; policy accept;
counter jump VYOS_PRE_SNAT_HOOK
-{% if source.rule is vyos_defined %}
-{% for rule, config in source.rule.items() if config.disable is not vyos_defined %}
+{% if source.rule is vyos_defined %}
+{% for rule, config in source.rule.items() if config.disable is not vyos_defined %}
{{ config | nat_rule(rule, 'source') }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
}
chain VYOS_PRE_DNAT_HOOK {
@@ -59,3 +60,4 @@ table ip vyos_nat {
return
}
}
+{% endif %}
diff --git a/data/templates/firewall/nftables-static-nat.j2 b/data/templates/firewall/nftables-static-nat.j2
index 790c33ce9..e5e3da867 100644
--- a/data/templates/firewall/nftables-static-nat.j2
+++ b/data/templates/firewall/nftables-static-nat.j2
@@ -3,6 +3,7 @@
{% if first_install is not vyos_defined %}
delete table ip vyos_static_nat
{% endif %}
+{% if deleted is not vyos_defined %}
table ip vyos_static_nat {
#
# Destination NAT rules build up here
@@ -10,11 +11,11 @@ table ip vyos_static_nat {
chain PREROUTING {
type nat hook prerouting priority -100; policy accept;
-{% if static.rule is vyos_defined %}
-{% for rule, config in static.rule.items() if config.disable is not vyos_defined %}
+{% if static.rule is vyos_defined %}
+{% for rule, config in static.rule.items() if config.disable is not vyos_defined %}
{{ config | nat_static_rule(rule, 'destination') }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
}
#
@@ -22,10 +23,11 @@ table ip vyos_static_nat {
#
chain POSTROUTING {
type nat hook postrouting priority 100; policy accept;
-{% if static.rule is vyos_defined %}
-{% for rule, config in static.rule.items() if config.disable is not vyos_defined %}
+{% if static.rule is vyos_defined %}
+{% for rule, config in static.rule.items() if config.disable is not vyos_defined %}
{{ config | nat_static_rule(rule, 'source') }}
-{% endfor %}
-{% endif %}
+{% endfor %}
+{% endif %}
}
}
+{% endif %}
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index f824838c0..2ae90fcaf 100755
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
@@ -16,6 +16,7 @@
import jmespath
import json
+import os
import unittest
from base_vyostest_shim import VyOSUnitTestSHIM
@@ -28,6 +29,9 @@ src_path = base_path + ['source']
dst_path = base_path + ['destination']
static_path = base_path + ['static']
+nftables_nat_config = '/run/nftables_nat.conf'
+nftables_static_nat_conf = '/run/nftables_static-nat-rules.nft'
+
class TestNAT(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
@@ -40,6 +44,8 @@ class TestNAT(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
self.cli_delete(base_path)
self.cli_commit()
+ self.assertFalse(os.path.exists(nftables_nat_config))
+ self.assertFalse(os.path.exists(nftables_static_nat_conf))
def verify_nftables(self, nftables_search, table, inverse=False, args=''):
nftables_output = cmd(f'sudo nft {args} list table {table}')
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index 8b1a5a720..978c043e9 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -146,6 +146,10 @@ def verify(nat):
if config['outbound_interface'] not in 'any' and config['outbound_interface'] not in interfaces():
Warning(f'rule "{rule}" interface "{config["outbound_interface"]}" does not exist on this system')
+ if not dict_search('translation.address', config) and not dict_search('translation.port', config):
+ if 'exclude' not in config:
+ raise ConfigError(f'{err_msg} translation requires address and/or port')
+
addr = dict_search('translation.address', config)
if addr != None and addr != 'masquerade' and not is_ip_network(addr):
for ip in addr.split('-'):
@@ -166,6 +170,10 @@ def verify(nat):
elif config['inbound_interface'] not in 'any' and config['inbound_interface'] not in interfaces():
Warning(f'rule "{rule}" interface "{config["inbound_interface"]}" does not exist on this system')
+ if not dict_search('translation.address', config) and not dict_search('translation.port', config):
+ if 'exclude' not in config:
+ raise ConfigError(f'{err_msg} translation requires address and/or port')
+
# common rule verification
verify_rule(config, err_msg)
@@ -204,6 +212,10 @@ def apply(nat):
cmd(f'nft -f {nftables_nat_config}')
cmd(f'nft -f {nftables_static_nat_conf}')
+ if not nat or 'deleted' in nat:
+ os.unlink(nftables_nat_config)
+ os.unlink(nftables_static_nat_conf)
+
return None
if __name__ == '__main__':