summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/firewall/nftables-nat.tmpl38
-rwxr-xr-xsrc/conf_mode/nat.py2
2 files changed, 26 insertions, 14 deletions
diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl
index 928f4ecfe..9bab8b363 100644
--- a/data/templates/firewall/nftables-nat.tmpl
+++ b/data/templates/firewall/nftables-nat.tmpl
@@ -23,8 +23,11 @@ add rule ip raw OUTPUT position {{ out_ct_ignore }} counter jump VYATTA_CT_HELPE
add rule ip raw OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK
{% endif %}
+
{% for r in destination if not r.disabled -%}
{% set chain = "PREROUTING" %}
+{% set src_addr = "ip saddr " + r.source_address if r.source_address %}
+{% set src_port = "sport { " + r.source_port +" }" if r.source_port %}
{% set dst_addr = "ip daddr " + r.dest_address if r.dest_address %}
{% set dst_port = "dport { " + r.dest_port +" }" if r.dest_port %}
{% set trns_addr = "dnat to " + r.translation_address %}
@@ -56,29 +59,33 @@ add rule ip raw OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRAC
{% set tcp_dst_port = "tcp " + dst_port if dst_port else "ip protocol tcp" %}
{% set udp_dst_port = "udp " + dst_port if dst_port else "ip protocol udp" %}
-add rule ip nat {{ chain }} iifname "{{ iface }}" {{ tcp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
+add rule ip nat {{ chain }} iifname "{{ iface }}" {{ src_addr }} {{ src_port }} {{ tcp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
{% endif %}
-add rule ip nat {{ chain }} iifname "{{ iface }}" {{ tcp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
+add rule ip nat {{ chain }} iifname "{{ iface }}" {{ src_addr }} {{ src_port }} {{ tcp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
{% if log %}
-add rule ip nat {{ chain }} iifname "{{ iface }}" {{ udp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
+add rule ip nat {{ chain }} iifname "{{ iface }}" {{ src_addr }} {{ src_port }} {{ udp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
{% endif %}
-add rule ip nat {{ chain }} iifname "{{ iface }}" {{ udp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
+add rule ip nat {{ chain }} iifname "{{ iface }}" {{ src_addr }} {{ src_port }} {{ udp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
{% else %}
{% set proto_dst_port = dst_port if dst_port else "ip protocol " + r.protocol %}
+{% set proto_dst_port = "" if r.protocol == "all" %}
+
{% if log %}
-add rule ip nat {{ chain }} iifname "{{ iface }}" {{ proto_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
+add rule ip nat {{ chain }} iifname "{{ iface }}" {{ src_addr }} {{ src_port }} {{ proto_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
{% endif %}
-add rule ip nat {{ chain }} iifname "{{ iface }}" {{ proto_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
+add rule ip nat {{ chain }} iifname "{{ iface }}" {{ src_addr }} {{ src_port }} {{ proto_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
{% endif %}
{% endfor %}
{% for r in source if not r.disabled -%}
{% set chain = "POSTROUTING" %}
+{% set src_addr = "ip saddr " + r.source_address if r.source_address %}
+{% set src_port = "sport { " + r.source_port +" }" if r.source_port %}
{% set dst_addr = "ip daddr " + r.dest_address if r.dest_address %}
{% set dst_port = "dport { " + r.dest_port +" }" if r.dest_port %}
-{% set trns_addr = "snat to " + r.translation_address %}
+{% set trns_addr = "snat to " + r.translation_address if r.translation_address != "masquerade" else "masquerade" %}
{% set trns_port = ":" + r.translation_port if r.translation_port %}
{% set comment = "SRC-NAT-" + r.number %}
{% set iface = r.interface_out %}
@@ -106,20 +113,25 @@ add rule ip nat {{ chain }} iifname "{{ iface }}" {{ proto_dst_port }} {{ dst_ad
{% set tcp_dst_port = "tcp " + dst_port if dst_port else "ip protocol tcp" %}
{% set udp_dst_port = "udp " + dst_port if dst_port else "ip protocol udp" %}
+{% set tcp_src_port = "tcp " + src_port if src_port %}
+{% set udp_src_port = "udp " + src_port if src_port %}
-add rule ip nat {{ chain }} oifname "{{ iface }}" {{ tcp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
+add rule ip nat {{ chain }} oifname "{{ iface }}" {{ tcp_src_port }} {{ src_port }} {{ tcp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
{% endif %}
-add rule ip nat {{ chain }} oifname "{{ iface }}" {{ tcp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
+add rule ip nat {{ chain }} oifname "{{ iface }}" {{ tcp_src_port }} {{ src_port }} {{ tcp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
{% if log %}
-add rule ip nat {{ chain }} oifname "{{ iface }}" {{ udp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
+add rule ip nat {{ chain }} oifname "{{ iface }}" {{ udp_src_port }} {{ src_port }} {{ udp_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
{% endif %}
-add rule ip nat {{ chain }} oifname "{{ iface }}" {{ udp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
+add rule ip nat {{ chain }} oifname "{{ iface }}" {{ udp_src_port }} {{ src_port }} {{ udp_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
{% else %}
{% set proto_dst_port = dst_port if dst_port else "ip protocol " + r.protocol %}
+{% set proto_dst_port = proto_dst_port if r.protocol != "all" %}
+{% set proto_src_port = r.protocol + " " + src_port if r.protocol != "all" else src_port %}
+
{% if log %}
-add rule ip nat {{ chain }} oifname "{{ iface }}" {{ proto_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
+add rule ip nat {{ chain }} oifname "{{ iface }}" {{ src_addr }} {{ proto_src_port }} {{ proto_dst_port }} {{ dst_addr }} counter log prefix "{{ log }}" comment "{{ comment }}"
{% endif %}
-add rule ip nat {{ chain }} oifname "{{ iface }}" {{ proto_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
+add rule ip nat {{ chain }} oifname "{{ iface }}" {{ src_addr }} {{ proto_src_port }} {{ proto_dst_port }} {{ dst_addr }} counter {{ trns_addr }}{{ trns_port }} comment "{{ comment }}"
{% endif %}
{% endfor %}
diff --git a/src/conf_mode/nat.py b/src/conf_mode/nat.py
index ebac6bfc0..5cb1af1f1 100755
--- a/src/conf_mode/nat.py
+++ b/src/conf_mode/nat.py
@@ -65,7 +65,7 @@ def get_handler(json, chain, target):
def verify_rule(rule, err_msg):
""" Common verify steps used for both source and destination NAT """
- if rule['translation_port'] or rule['dest_port']:
+ if rule['translation_port'] or rule['dest_port'] or rule['source_port']:
if rule['protocol'] not in ['tcp', 'udp', 'tcp_udp']:
proto = rule['protocol']
raise ConfigError(f'{err_msg} ports can only be specified when protocol is "tcp", "udp" or "tcp_udp" (currently "{proto}")')