Files
Media-Server-Setup/firewall/nftables.conf
Brandyn / Techy 463d9b2385 Live portal: React + dockview multi-stream viewer behind Authentik; MediaMTX HLS/WebRTC/API re-enabled; is-live Discord hook
live/: every active stream opens as a dockable window (WHEP, HLS fallback), audio follows the
focused window, per-window mute/volume, pinning. Caddy live.HOST block with forward-auth proxies
/api /webrtc /hls to MediaMTX on loopback and serves /srv/live. WebRTC media on 8189 (firewall).
configure.py asks the live hostname and an optional Discord webhook; MediaMTX -ffmpeg image runs
the runOnReady hook. deployLive.sh builds and ships dist/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-30 23:01:11 -05:00

66 lines
2.7 KiB
Plaintext

#!/usr/sbin/nft -f
# vanguard-stream host firewall. Own table so (re)applying never disturbs Docker's rules.
# Input only: Docker-published ports (1935, 8890, 22000) arrive via Docker's forward chain and are
# listed here for the host-network case (Caddy) and clarity. Nothing else should listen publicly.
destroy table inet vanguard
table inet vanguard {
set ssh_allow {
type ipv4_addr
flags interval
# leave empty to allow SSH from anywhere (key auth, rate limited); or list CIDRs:
# elements = { 203.0.113.0/24, 198.51.100.7 }
}
set db_allow {
type ipv4_addr
flags interval
# MariaDB clients. Leave empty = anywhere (rate limited); or list the bot dev's IPs and then
# delete the "tcp dport 3306 ct state new accept" line below to restrict to this set.
# elements = { 203.0.113.7 }
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
ct state invalid drop
# icmp (ping, pmtu) and all icmpv6 (neighbor discovery is mandatory)
ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded, parameter-problem } accept
ip6 nexthdr icmpv6 accept
# dhcp client replies (OVH may hand out the address by DHCP)
udp sport 67 udp dport 68 accept
# ssh: restricted to ssh_allow if it has entries, otherwise anywhere, rate limited
tcp dport 22 ct state new ip saddr @ssh_allow accept
tcp dport 22 ct state new limit rate over 15/minute burst 10 packets drop
tcp dport 22 ct state new accept
# public services
tcp dport { 80, 443 } accept # Caddy: copyparty, dock, dump
udp dport 443 accept # Caddy HTTP/3 (QUIC)
tcp dport 1935 accept # RTMP ingest
udp dport 8890 accept # SRT ingest
tcp dport 22000 accept # Syncthing
tcp dport 2222 accept # Gitea ssh (git clone/push)
udp dport 8189 accept # WebRTC media for the live portal
tcp dport 8189 accept # WebRTC ICE-TCP fallback
udp dport 22000 accept # Syncthing QUIC
# mariadb (host network): allowlist first, then anywhere with a brute-force limit
tcp dport 3306 ct state new ip saddr @db_allow accept
tcp dport 3306 ct state new limit rate over 30/minute burst 20 packets drop
tcp dport 3306 ct state new accept
# NOT opened on purpose — these bind to 127.0.0.1 only and are reached via Caddy or an ssh tunnel:
# 9000 authentik · 8096 jellyfin · 3923 copyparty · 8384 syncthing UI · 8080 dumpd
# Docker publishes them on loopback, so its NAT never forwards outside traffic to them either.
# everything else: drop (policy), but log a trickle for diagnosis
limit rate 5/minute log prefix "vg-drop " level info
}
}