Setup of a multi-purpose home-server using Ansible: systemd, nftables, port-knocking, etckeeper, Let’s Encrypt, dynamic DNS, OpenLDAP, SSO, mail, PostgreSQL, Dotclear, Gitea, Nextcloud, NFS, XMPP, print & scan, DLNA, Transmission, iodine…
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 

214 рядки
6.7 KiB

#!/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 %}