|
- #!/usr/bin/env nft -f
- # The home-server project produces a multi-purpose setup using Ansible.
- # Copyright © 2018 Y. Gablin, under the GPL-3.0-or-later license.
- # Full licensing information in the LICENSE file, or gnu.org/licences/gpl-3.0.txt if the file is missing.
-
- flush ruleset
-
- {% for V in ['4', '6'] %}
- {% set v = V | replace('4', '') %}
- {% macro trust(list) %}
- {% for net in list.split(' ') %}
- {% if not net is match('127(?:\.\d{1,3}){3}(?:/\d+)?|::1|^$') %}
- {% if (net is match('\d{1,3}(?:\.\d{1,3}){3}(?:/\d+)?')
- and V == '4') or (net is search(':') and V == '6') %}
- {{caller(net)}}
- {% endif %}
- {% endif %}
- {% endfor %}
- {% endmacro %}
-
- table ip{{v}} Inet{{V}} {
- set https_ban {
- type ipv{{V}}_addr
- flags timeout
- }
- set mail_ban {
- type ipv{{V}}_addr
- flags timeout
- }
- set sshd_ban {
- type ipv{{V}}_addr
- flags timeout
- }
-
- {% set seq = fw_portknock_seq.split(' ') %}
- {% for port in seq %}
- set Knocked_{{loop.index}} {
- type ipv{{V}}_addr
- flags timeout
- {% if loop.last %}
- timeout {{fw_knock_timeout_min}}m
- {% else %}
- timeout 10s
- {% endif %}
- gc-interval 4s
- }
- {% endfor %}
-
- chain doBan {
- type filter hook prerouting priority -200; policy accept;
-
- ip{{v}} saddr @https_ban tcp dport {80, 443} drop
- ip{{v}} saddr @mail_ban tcp dport {25, 465, 587, 993} drop
- ip{{v}} saddr @sshd_ban tcp dport {22, 2222, 22000} drop
- }
-
- chain NAT_in {
- type nat hook prerouting priority -100
- {% call(net) trust(SafeZone_IP) %}
-
- # Git SSH
- tcp dport 2222 log prefix "DNAT/git: " dnat to {{net}}
- {% endcall %}
-
- # Trusted hosts
- tcp dport 443 ip{{v}} saddr @Knocked_{{seq | length}} log prefix "DNAT/HTTPS after Port-Knock: " redirect to 444
- {% call(net) trust(net_trusted_ranges) %}
- tcp dport 443 ip{{v}} saddr {{net}} redirect to 444
- {% endcall %}
- tcp dport 22 ip{{v}} saddr @Knocked_{{seq | length}} log prefix "DNAT/SSH after Port-Knock: " redirect to 23
- {% call(net) trust(net_trusted_ranges) %}
- tcp dport 22 ip{{v}} saddr {{net}} redirect to 23
- {% endcall %}
- }
- chain NAT_out {
- type nat hook postrouting priority 100
- ct status dnat masquerade
- }
-
- {% for port in seq %}
- chain Knock_{{loop.index}} {
- {% if not loop.first %}
- set update ip{{v}} saddr timeout 0s @Knocked_{{loop.index-1}}
- {% endif %}
- set add ip{{v}} saddr @Knocked_{{loop.index}}{% if loop.last %} log prefix "Port-Knock accepted: "{% endif %}
-
- }
- {% if not loop.last %}
- chain Unknock_{{loop.index}} {
- set update ip{{v}} saddr timeout 0s @Knocked_{{loop.index}}
- }
- {% endif %}
- {% endfor %}
-
- chain RefreshKnock {
- set update ip{{v}} saddr timeout {{fw_knock_timeout_min}}m @Knocked_{{seq | length}}
- }
-
- chain PortKnock {
- {% for port in seq | reverse %}
- {% if loop.first %}
- ct state new ip{{v}} saddr @Knocked_{{loop.revindex}} goto RefreshKnock
- {% else %}
- tcp dport {{seq[loop.revindex]}} ct state new ip{{v}} saddr @Knocked_{{loop.revindex}} goto Knock_{{loop.revindex+1}}
- tcp dport {{port}} ct state new ip{{v}} saddr @Knocked_{{loop.revindex}} return
- ip{{v}} saddr @Knocked_{{loop.revindex}} ct state new goto Unknock_{{loop.revindex}}
- {% endif %}
- {% if loop.last %}
- tcp dport {{port}} ct state new goto Knock_{{loop.revindex}}
- {% endif %}
- {% endfor %}
- }
-
- chain FilterIn {
- type filter hook input priority 0
- policy drop
-
- # allow established/related connections
- ct state {established, related} accept
-
- # early drop of invalid connections
- ct state invalid drop
-
- # allow from loopback
- meta iif lo accept
-
- # allow icmp
- {% if V == '4' %}
- ip protocol icmp accept
- {% else %}
- ip6 nexthdr icmpv6 accept
- {% endif %}
-
- # allow iodine
- meta iifname dns0 accept
-
- # port-knocking
- jump PortKnock
-
- # trusted ssh and https
- ct status dnat accept
-
- # smtp
- tcp dport 25 accept
-
- # iodine
- tcp dport 53 accept
- udp dport 53 accept
-
- # http
- tcp dport 80 accept
-
- # https
- tcp dport 443 accept
-
- # smtps
- tcp dport 465 accept
-
- # submission (smtp)
- tcp dport 587 accept
-
- # ipp
- {% call(net) trust(net_trusted_ranges) %}
- tcp dport 631 ip{{v}} saddr {{net}} accept
- udp dport 631 ip{{v}} saddr {{net}} accept
- {% endcall %}
-
- # imaps
- tcp dport 993 accept
-
- # xmpp client
- tcp dport 5222 accept
-
- # xmpp server
- tcp dport 5269 accept
-
- # xmpp components
- tcp dport 5347 accept
-
- # zeroconf
- {% call(net) trust(net_trusted_ranges) %}
- udp dport 5353 ip{{v}} saddr {{net}} accept
- {% endcall %}
-
- # remote-help ssh
- tcp dport 22000 accept
- {% call(net) trust(net_trusted_ranges) %}
- tcp dport 22001-22009 ip{{v}} saddr {{net}} accept
- {% endcall %}
-
- # transmission
- tcp dport {{transmission_bt_port}} accept
- udp dport {{transmission_bt_port}} accept
- }
-
- chain FilterOut {
- type filter hook output priority 0
- policy drop
- ct state {established, related} accept
- meta oif lo accept
- {% call(net) trust(SafeZone_IP + ' ' + dns_hosts + ' ' + allowed_domains_ip + ' ' + ntp_hosts) %}
- ip{{v}} daddr {{net}} accept
- {% endcall %}
- meta skuid {{aur_user}} accept
- meta skuid exim tcp dport 25 accept
- meta skuid prosody accept
- meta skgid spamd accept
- meta skuid transmission tcp dport 443 accept
- meta skuid transmission udp dport 443 accept
- meta skuid transmission tcp dport > 1024 accept
- meta skuid transmission udp dport > 1024 accept
- }
- }
- {% endfor %}
|