diff --git a/states/nftables/config.sls b/states/nftables/config.sls new file mode 100644 index 0000000..35d443c --- /dev/null +++ b/states/nftables/config.sls @@ -0,0 +1,38 @@ +--- +{%- from "nftables/map.jinja" import nftables with context %} +nftables-config-dir: + file.directory: + - name: {{ nftables.config_dir }} + +{%- if not salt['file.file_exists'](nftables.config_dir + "/blacklist.nft") %} +nftables-blacklist-config: + file.managed: + - name: {{ nftables.config_dir }}/blacklist.nft + - watch_in: + - service: nftables-service + - require: + - pkg: nftables-pkg + - file: nftables-config-dir +{%- endif %} + +nftables-rules-config: + file.managed: + - name: {{ nftables.config_dir }}/rules.nft + - source: salt://nftables/rules.nft.j2 + - template: jinja + - watch_in: + - service: nftables-service + - require: + - pkg: nftables-pkg + - file: nftables-config-dir + +nftables-main-config: + file.managed: + - name: /etc/nftables.conf + - source: salt://nftables/nftables.conf.j2 + - template: jinja + - watch_in: + - service: nftables-service + - require: + - file: nftables-rules-config + - pkg: nftables-pkg diff --git a/states/nftables/defaults.yaml b/states/nftables/defaults.yaml index 9dd24b7..4fb5030 100644 --- a/states/nftables/defaults.yaml +++ b/states/nftables/defaults.yaml @@ -1,4 +1,5 @@ --- nftables: enabled: true + config_dir: /etc/nftables networks: {} diff --git a/states/nftables/init.sls b/states/nftables/init.sls index a64ed78..383c46b 100644 --- a/states/nftables/init.sls +++ b/states/nftables/init.sls @@ -1,22 +1,5 @@ --- -{%- from "nftables/map.jinja" import nftables with context %} -nftables-pkg: - pkg.latest: - - name: nftables - -nftables-main-config: - file.managed: - - name: /etc/nftables.conf - - source: salt://nftables/nftables.conf.j2 - - template: jinja - - watch_in: - - service: nftables-service - - require: - - pkg: nftables-pkg - -nftables-service: - service.running: - - name: nftables - - enable: true - - require: - - pkg: nftables-pkg +include: + - .install + - .config + - .service diff --git a/states/nftables/install.sls b/states/nftables/install.sls new file mode 100644 index 0000000..9f6d8fe --- /dev/null +++ b/states/nftables/install.sls @@ -0,0 +1,5 @@ +--- +{%- from "nftables/map.jinja" import nftables with context %} +nftables-pkg: + pkg.latest: + - name: nftables diff --git a/states/nftables/nftables.conf.j2 b/states/nftables/nftables.conf.j2 index bc1ac44..7439274 100644 --- a/states/nftables/nftables.conf.j2 +++ b/states/nftables/nftables.conf.j2 @@ -1,50 +1,5 @@ ## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} -{%- from "nftables/map.jinja" import nftables with context %} -{%- from "nftables/map.jinja" import net with context %} - -## IPv4 filtering -add table ip filter -add chain ip filter input { type filter hook input priority 0; policy drop; } -add chain ip filter forward { type filter hook forward priority 0; policy accept; } -add chain ip filter output { type filter hook output priority 0; policy accept; } -add rule ip filter input iifname lo counter accept -add rule ip filter input iifname tun* counter accept -add rule ip filter input ct state related,established counter accept -add rule ip filter input ip protocol icmp counter accept -{%- for key, value in net.ipv4_networks.items() %} -add rule ip filter input ip saddr {{ value.ip }}/{{ value.mask }} ct state established,new counter accept -{%- endfor %} -{%- for key, value in net.public_ports.items() %} -add rule ip filter input {{ value.proto }} dport {{ value.port }} ct state established,new counter accept -{%- endfor %} -#add rule ip filter input counter log - -## IPv4 NAT -add table ip nat -add chain ip nat prerouting { type nat hook prerouting priority 0; policy accept; } -add chain ip nat input { type nat hook input priority 0; policy accept; } -add chain ip nat output { type nat hook output priority 0; policy accept; } -add chain ip nat postrouting { type nat hook postrouting priority 0; policy accept; } -{%- for key, value in net.nats.items() %} -add rule ip nat postrouting ip saddr {{ value.ip }}/{{ value.mask }} counter masquerade -{%- endfor %} - -## IPv6 filtering -add table ip6 filter6 -add chain ip6 filter6 input { type filter hook input priority 0; policy drop; } -add chain ip6 filter6 forward { type filter hook forward priority 0; policy accept; } -add chain ip6 filter6 output { type filter hook output priority 0; policy accept; } -add rule ip6 filter6 input iifname lo counter accept -add rule ip6 filter6 input iifname tun* counter accept -add rule ip6 filter6 input ct state related,established counter accept -add rule ip6 filter6 input icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect, parameter-problem, router-renumbering} accept -{%- for key, value in net.ipv6_networks.items() %} -add rule ip6 filter6 input ip6 saddr {{ value.ip }}/{{ value.mask }} ct state established,new counter accept -{%- endfor %} -{%- for key, value in net.public_ports.items() %} -add rule ip6 filter6 input {{ value.proto }} dport {{ value.port }} ct state established,new counter accept -{%- endfor %} -#add rule ip6 filter6 input counter log +include "/etc/nftables/*.nft" ## Endline is mandatory diff --git a/states/nftables/rules.nft.j2 b/states/nftables/rules.nft.j2 new file mode 100644 index 0000000..b5cbfcb --- /dev/null +++ b/states/nftables/rules.nft.j2 @@ -0,0 +1,51 @@ +## {{ salt['pillar.get']('salt_managed', default='Salt Managed') }} + +{%- from "nftables/map.jinja" import nftables with context %} +{%- from "nftables/map.jinja" import net with context %} + +## IPv4 filtering +add table ip filter +add chain ip filter input { type filter hook input priority 0; policy drop; } +add chain ip filter forward { type filter hook forward priority 0; policy accept; } +add chain ip filter output { type filter hook output priority 0; policy accept; } +add rule ip filter input iifname lo counter accept +add rule ip filter input iifname tun* counter accept +add rule ip filter input ct state related,established counter accept +add rule ip filter input ip protocol icmp counter accept +add rule ip filter input ip saddr $blacklist drop +{%- for key, value in net.ipv4_networks.items() %} +add rule ip filter input ip saddr {{ value.ip }}/{{ value.mask }} ct state established,new counter accept +{%- endfor %} +{%- for key, value in net.public_ports.items() %} +add rule ip filter input {{ value.proto }} dport {{ value.port }} ct state established,new counter accept +{%- endfor %} +#add rule ip filter input counter log + +## IPv4 NAT +add table ip nat +add chain ip nat prerouting { type nat hook prerouting priority 0; policy accept; } +add chain ip nat input { type nat hook input priority 0; policy accept; } +add chain ip nat output { type nat hook output priority 0; policy accept; } +add chain ip nat postrouting { type nat hook postrouting priority 0; policy accept; } +{%- for key, value in net.nats.items() %} +add rule ip nat postrouting ip saddr {{ value.ip }}/{{ value.mask }} counter masquerade +{%- endfor %} + +## IPv6 filtering +add table ip6 filter6 +add chain ip6 filter6 input { type filter hook input priority 0; policy drop; } +add chain ip6 filter6 forward { type filter hook forward priority 0; policy accept; } +add chain ip6 filter6 output { type filter hook output priority 0; policy accept; } +add rule ip6 filter6 input iifname lo counter accept +add rule ip6 filter6 input iifname tun* counter accept +add rule ip6 filter6 input ct state related,established counter accept +add rule ip6 filter6 input icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect, parameter-problem, router-renumbering} accept +{%- for key, value in net.ipv6_networks.items() %} +add rule ip6 filter6 input ip6 saddr {{ value.ip }}/{{ value.mask }} ct state established,new counter accept +{%- endfor %} +{%- for key, value in net.public_ports.items() %} +add rule ip6 filter6 input {{ value.proto }} dport {{ value.port }} ct state established,new counter accept +{%- endfor %} +#add rule ip6 filter6 input counter log + +## Endline is mandatory diff --git a/states/nftables/service.sls b/states/nftables/service.sls new file mode 100644 index 0000000..c0b3633 --- /dev/null +++ b/states/nftables/service.sls @@ -0,0 +1,8 @@ +--- +{%- from "nftables/map.jinja" import nftables with context %} +nftables-service: + service.running: + - name: nftables + - enable: true + - require: + - pkg: nftables-pkg