Vanguard media stack: ingest, copyparty, Syncthing, normalize sweep, Authentik, Jellyfin + Vanguard Metadata plugin, MariaDB, Gitea, bot runtime
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
22
firewall/firewall.sh
Executable file
22
firewall/firewall.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
# Install + enable the host firewall. Run with sudo from the bundle dir.
|
||||
# Keep your current SSH session open and test a NEW connection before closing it.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")"
|
||||
[[ $EUID -eq 0 ]] || { echo "run with sudo"; exit 1; }
|
||||
|
||||
apt-get install -y -q nftables >/dev/null
|
||||
install -m 0644 nftables.conf /etc/nftables.conf
|
||||
|
||||
echo "== syntax check"; nft -c -f /etc/nftables.conf
|
||||
echo "== apply"; nft -f /etc/nftables.conf
|
||||
systemctl enable nftables >/dev/null 2>&1 || true # loads /etc/nftables.conf at boot, before docker
|
||||
|
||||
echo "== active ruleset (vanguard table)"
|
||||
nft list table inet vanguard | sed 's/^/ /'
|
||||
echo
|
||||
echo "== listening on public interfaces (should be 22 80 443 1935 2222 3306 8890 22000 only)"
|
||||
ss -tulpnH | awk '$5 !~ /^(127\.|\[::1\])/ {print " "$1, $5}' | sort -u
|
||||
echo
|
||||
echo "Now open a SECOND terminal and confirm: ssh debian@$(hostname -f 2>/dev/null || hostname)"
|
||||
echo "To restrict SSH to your IPs, edit the ssh_allow set in /etc/nftables.conf and re-run: sudo nft -f /etc/nftables.conf"
|
||||
63
firewall/nftables.conf
Normal file
63
firewall/nftables.conf
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/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 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user