From 69bcdb9a680b33422d041fd03e70c25094bfa6a2 Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Sat, 13 Aug 2022 00:07:41 +0000 Subject: 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 --- src/conf_mode/nat.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py index 85819a77e..b76ea9f9e 100755 --- a/src/conf_mode/nat.py +++ b/src/conf_mode/nat.py @@ -45,6 +45,7 @@ else: k_mod = ['nft_nat', 'nft_chain_nat_ipv4'] nftables_nat_config = '/tmp/vyos-nat-rules.nft' +nftables_static_nat_conf = '/tmp/vyos-static-nat-rules.nft' def get_handler(json, chain, target): """ Get nftable rule handler number of given chain/target combination. @@ -88,7 +89,7 @@ def get_config(config=None): # T2665: we must add the tagNode defaults individually until this is # moved to the base class - for direction in ['source', 'destination']: + for direction in ['source', 'destination', 'static']: if direction in nat: default_values = defaults(base + [direction, 'rule']) for rule in dict_search(f'{direction}.rule', nat) or []: @@ -178,10 +179,22 @@ def verify(nat): # common rule verification verify_rule(config, err_msg) + if dict_search('static.rule', nat): + for rule, config in dict_search('static.rule', nat).items(): + err_msg = f'Static NAT configuration error in rule {rule}:' + + if 'inbound_interface' not in config: + raise ConfigError(f'{err_msg}\n' \ + 'inbound-interface not specified') + + # common rule verification + verify_rule(config, err_msg) + return None def generate(nat): render(nftables_nat_config, 'firewall/nftables-nat.j2', nat) + render(nftables_static_nat_conf, 'firewall/nftables-static-nat.j2', nat) # dry-run newly generated configuration tmp = run(f'nft -c -f {nftables_nat_config}') @@ -190,10 +203,13 @@ def generate(nat): os.unlink(nftables_nat_config) raise ConfigError('Configuration file errors encountered!') + tmp = run(f'nft -c -f {nftables_nat_config}') + return None def apply(nat): cmd(f'nft -f {nftables_nat_config}') + cmd(f'nft -f {nftables_static_nat_conf}') if os.path.isfile(nftables_nat_config): os.unlink(nftables_nat_config) -- cgit v1.2.3