75 lines
3.3 KiB
Plaintext
75 lines
3.3 KiB
Plaintext
# iptables ruleset for the RackNerd VPN hub.
|
|
# ${PUBIF} is substituted by host/setup.sh with the detected public interface.
|
|
# Installed to /etc/iptables/rules.v4 (iptables-persistent).
|
|
#
|
|
# NOTE: after any manual `netfilter-persistent reload`, run
|
|
# `systemctl restart docker` — the reload flushes Docker's chains.
|
|
|
|
*filter
|
|
:INPUT DROP [0:0]
|
|
:FORWARD DROP [0:0]
|
|
:OUTPUT ACCEPT [0:0]
|
|
:DOCKER-USER - [0:0]
|
|
|
|
# ── INPUT ──────────────────────────────────────────────────────────────
|
|
-A INPUT -i lo -j ACCEPT
|
|
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
|
-A INPUT -m conntrack --ctstate INVALID -j DROP
|
|
-A INPUT -p icmp -j ACCEPT
|
|
|
|
# Public interface: SSH (key-only!), WireGuard, OpenVPN — nothing else.
|
|
-A INPUT -i ${PUBIF} -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
|
-A INPUT -i ${PUBIF} -p udp --dport 51820 -j ACCEPT
|
|
-A INPUT -i ${PUBIF} -p udp --dport 1194 -j ACCEPT
|
|
|
|
# OpenVPN clients: DNS to Technitium only (no SSH, no mgmt from clients)
|
|
-A INPUT -i tun0 -d 172.31.8.1/32 -p udp --dport 53 -j ACCEPT
|
|
-A INPUT -i tun0 -d 172.31.8.1/32 -p tcp --dport 53 -j ACCEPT
|
|
|
|
# Site tunnels: allow DNS in case site hosts want to use Technitium
|
|
-A INPUT -i wg0 -p udp --dport 53 -j ACCEPT
|
|
-A INPUT -i wg0 -p tcp --dport 53 -j ACCEPT
|
|
|
|
# Technitium web console — VPN clients and site tunnels only, never public
|
|
-A INPUT -i tun0 -p tcp --dport 5380 -j ACCEPT
|
|
-A INPUT -i wg0 -p tcp --dport 5380 -j ACCEPT
|
|
|
|
# ── FORWARD (routed, no NAT — DCs see real client IPs) ────────────────
|
|
-A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
|
|
-A FORWARD -m conntrack --ctstate INVALID -j DROP
|
|
|
|
# Roaming clients -> both sites + WG transfer net
|
|
-A FORWARD -i tun0 -o wg0 -s 172.31.8.0/24 -d 192.168.20.0/24 -j ACCEPT
|
|
-A FORWARD -i tun0 -o wg0 -s 172.31.8.0/24 -d 192.168.7.0/24 -j ACCEPT
|
|
-A FORWARD -i tun0 -o wg0 -s 172.31.8.0/24 -d 172.31.255.0/24 -j ACCEPT
|
|
|
|
# Travel routers (roaming WG peers, wg0 -> wg0) -> both sites
|
|
-A FORWARD -i wg0 -o wg0 -s 172.31.9.0/24 -d 192.168.20.0/24 -j ACCEPT
|
|
-A FORWARD -i wg0 -o wg0 -s 172.31.9.0/24 -d 192.168.7.0/24 -j ACCEPT
|
|
|
|
# Travel routers in FULL-TUNNEL mode (AllowedIPs 0.0.0.0/0, the GL.iNet
|
|
# default): internet egress via this box, masqueraded below in *nat.
|
|
-A FORWARD -i wg0 -o ${PUBIF} -s 172.31.9.0/24 -j ACCEPT
|
|
|
|
# Site -> client NEW connections (e.g. RDP/RSAT from a DC to a roaming
|
|
# laptop). Off by default; uncomment if you need it.
|
|
#-A FORWARD -i wg0 -o tun0 -d 172.31.8.0/24 -j ACCEPT
|
|
|
|
COMMIT
|
|
|
|
# Internet egress NAT for full-tunnel travel routers ONLY — site-bound
|
|
# traffic (192.168.x, 172.31.x) never matches this because it leaves via
|
|
# wg0, not ${PUBIF}. OpenVPN clients stay split-tunnel/unNATed.
|
|
*nat
|
|
:POSTROUTING ACCEPT [0:0]
|
|
-A POSTROUTING -s 172.31.9.0/24 -o ${PUBIF} -j MASQUERADE
|
|
COMMIT
|
|
|
|
# ── Fallback per project brief ─────────────────────────────────────────
|
|
# If site-side return routing for 172.31.8.0/24 becomes a pain, NAT the
|
|
# clients behind the wg0 address instead (DCs then see 172.31.255.1):
|
|
#*nat
|
|
#:POSTROUTING ACCEPT [0:0]
|
|
#-A POSTROUTING -s 172.31.8.0/24 -o wg0 -j MASQUERADE
|
|
#COMMIT
|