VM: OPNSense Firewall
VM-Informationen
Typ: Virtual Machine (KVM/QEMU)
OS: OPNSense 25.x (FreeBSD 14.x)
Hostname: opnsense (anpassbar)
Status: running
Ressourcen:
vCPUs: 4
RAM: 4 GB
Disk: 25 GB (dynamisch erweiterbar)Installierte Software
OPNSense Firewall
Version: 25.x (aktuelle Stable)
Base: FreeBSD 14.x
Firewall Engine: pf (Packet Filter)
Web-Interface: Lighttpd + PHPCaddy Reverse Proxy
Version: 2.x (aktuelle Stable)
Installation: FreeBSD Package
Service: caddy.service (systemd)
TLS: Let's Encrypt (automatisch)DNS Resolver
Service: Unbound
Upstream: Cloudflare, Quad9
DNSSEC: Enabled
Query-Logging: OptionalNetzwerk-Konfiguration
Network Interfaces
WAN Interface:
- Typ: Virtuell (vmbr0 Bridge)
- IP: DHCP oder statisch (ISP-abhängig)
- Firewall: Default DENY (Whitelist)
LAN Interface:
- Typ: Virtuell (vmbr1 Bridge)
- IP: RFC1918 Private Network
- Gateway: Für interne Services
- DHCP: Aktiviert für interne ClientsBridge-Konfiguration (Proxmox)
vmbr0 (WAN):
- Verbindung zu Internet-Uplink
- Nur OPNSense WAN-Interface
vmbr1 (LAN):
- Private Netzwerk für p2d2-Services
- Alle LXC-Container und interne VMsFirewall-Regeln
Firewall-Philosophie
Default Policy: DROP (alle Pakete verwerfen)
Ansatz: Whitelist (nur explizit erlaubte Verbindungen)
Stateful: Ja (etablierte Verbindungen tracken)
Logging: Wichtige Events loggenRegel-Kategorien
WAN → LAN (Eingehend)
1. HTTPS (443) → Caddy Reverse Proxy: ALLOW
2. HTTP (80) → Caddy (Redirect zu HTTPS): ALLOW
3. WireGuard (<VPN_PORT>) → VPN Server: ALLOW
4. Alle anderen Ports: DENYLAN → Internet (Ausgehend)
1. HTTP/HTTPS (80/443): ALLOW (Updates, Let's Encrypt)
2. DNS (53): ALLOW (Upstream-Resolver)
3. NTP (123): ALLOW (Zeit-Synchronisation)
4. SMTP (25/587): ALLOW (nur für Ory Email-Versand)
5. Andere: DENY (nur explizit benötigte Ports)LAN → LAN (Service-zu-Service)
Siehe Service-Matrix in Netzwerk-Dokumentation.
Caddy Reverse Proxy
Hauptkonfiguration (Caddyfile)
# /usr/local/etc/caddy/Caddyfile
# Global Settings
{
email admin@data-dna.eu
acme_ca https://acme-v02.api.letsencrypt.org/directory
}
# Auto-HTTPS für alle Domains
*.data-dna.eu {
tls {
dns cloudflare <CF_API_TOKEN>
}
@main host www.data-dna.eu
handle @main {
reverse_proxy http://frontend.lan:3000
}
@dev host dev.data-dna.eu
handle @dev {
reverse_proxy http://frontend.lan:3001
}
@feature1 host f-de1.data-dna.eu
handle @feature1 {
reverse_proxy http://frontend.lan:3002
}
@feature2 host f-de2.data-dna.eu
handle @feature2 {
reverse_proxy http://frontend.lan:3003
}
@feature3 host f-fv.data-dna.eu
handle @feature3 {
reverse_proxy http://frontend.lan:3004
}
@doc host doc.data-dna.eu
handle @doc {
reverse_proxy http://frontend.lan:4173
}
@ows host ows.data-dna.eu
handle @ows {
reverse_proxy http://geoserver.lan:8080
}
@wfs host wfs.data-dna.eu
handle @wfs {
reverse_proxy http://geoserver.lan:8080
}
@tiles host tiles.data-dna.eu
handle @tiles {
reverse_proxy http://mapproxy.lan:8080
}
@proxy host proxy.data-dna.eu
handle @proxy {
reverse_proxy http://mapproxy.lan:8080
}
}
# HTTP to HTTPS Redirect
http://*data-dna.eu {
redir https://{host}{uri} permanent
}Custom Konfigurationen
# /usr/local/etc/caddy/caddy.d/geo-services.conf
# GeoServer WMS Optimierungen
ows.data-dna.eu {
reverse_proxy http://geoserver.lan:8080 {
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Proto {scheme}
}
# Rate Limiting für WMS
@wms {
path /geoserver/wms*
}
handle @wms {
rate_limit {
zone wms_zone 10r/s
key {remote_host}
}
reverse_proxy http://geoserver.lan:8080
}
}
# MapProxy Tile-Service
tiles.data-dna.eu {
reverse_proxy http://mapproxy.lan:8080
# Caching für Tiles
header Cache-Control "public, max-age=86400"
# CORS für Web-Apps
header Access-Control-Allow-Origin *
}DNS-Konfiguration (Unbound)
Lokale DNS-Records
# /var/unbound/host_entries.conf
local-data: "postgresql.lan A <DB_CONTAINER_IP>"
local-data: "geoserver.lan A <GEOSERVER_CONTAINER_IP>"
local-data: "mapproxy.lan A <MAPPROXY_CONTAINER_IP>"
local-data: "frontend.lan A <FRONTEND_CONTAINER_IP>"
local-data: "osm-tiler.lan A <TILER_VM_IP>"
local-data-ptr: "<DB_CONTAINER_IP> postgresql.lan"Upstream-Resolver
# /var/unbound/forwarding.conf
forward-zone:
name: "."
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 9.9.9.9@853#dns.quad9.net
forward-tls-upstream: yesVPN-Zugang (WireGuard)
Server-Konfiguration
# /usr/local/etc/wireguard/wg0.conf
[Interface]
Address = <VPN_INTERNAL_IP>/24
PrivateKey = <SERVER_PRIVATE_KEY>
ListenPort = <VPN_PORT>
[Peer]
# Admin Client 1
PublicKey = <CLIENT_1_PUBLIC_KEY>
AllowedIPs = <CLIENT_1_VPN_IP>/32
PersistentKeepalive = 25
[Peer]
# Admin Client 2
PublicKey = <CLIENT_2_PUBLIC_KEY>
AllowedIPs = <CLIENT_2_VPN_IP>/32
PersistentKeepalive = 25Firewall-Regeln für VPN
VPN → LAN: ALLOW (für Admin-Zugriff)
VPN → WAN: DENY (nur über NAT)
VPN Clients können auf interne Services zugreifenBackup-Strategie
PBS-Snapshot (VM-Level)
- Zeitplan: Täglich
- Retention: 7 Tage
- Typ: QEMU Snapshot
Konfigurations-Backup
# OPNSense Config Export
System → Configuration → Backups → Download
# Caddy Konfiguration
tar -czf /backup/caddy-config_$(date +%Y%m%d).tar.gz \
/usr/local/etc/caddy/
# Automatisierung via Cron
# /etc/cron.daily/opnsense-backup
#!/bin/sh
/usr/local/etc/rc.backup_running
tar -czf /backup/caddy-config_$(date +%Y%m%d).tar.gz \
/usr/local/etc/caddy/Monitoring
Health-Checks
# Service-Status
service -e | grep -E "(caddy|unbound|wireguard)"
# Caddy-Status
curl -I https://www.data-dna.eu
# DNS-Resolution
nslookup www.data-dna.eu 127.0.0.1
# Firewall-Stats
pfctl -si | grep -E "(states|searches)"Log-Analyse
# Firewall-Logs
tail -f /var/log/filter.log
# Caddy-Logs
tail -f /var/log/caddy/access.log
tail -f /var/log/caddy/error.log
# System-Logs
tail -f /var/log/system.logTroubleshooting
Netzwerk-Probleme
# Interface-Status
ifconfig -a
# Routing-Tabelle
netstat -rn
# Firewall-Regeln
pfctl -sr
# Packet Capture
tcpdump -i <INTERFACE> -nCaddy-Probleme
# Service-Status
service caddy status
# Konfigurations-Validierung
caddy validate --config /usr/local/etc/caddy/Caddyfile
# Log-Analyse
journalctl -u caddy --no-pager -n 100DNS-Probleme
# Unbound-Status
service unbound status
# DNS-Resolution testen
dig @127.0.0.1 www.data-dna.eu
# Query-Logs
tail -f /var/log/unbound.logSicherheits-Konfiguration
OPNSense Hardening
Web-Interface:
- HTTPS-only
- Strong Admin Password
- 2FA optional aktivierbar
SSH-Zugang:
- Nur über VPN oder Management-VLAN
- Key-based Authentication
- Password Authentication deaktiviert
Firewall:
- Default DENY Policy
- Stateful Packet Inspection
- Geo-Blocking optionalCaddy Security
TLS-Konfiguration:
- TLS 1.2 minimum, TLS 1.3 preferred
- Modern Cipher Suites
- HSTS Header
- OCSP Stapling
Rate-Limiting:
- Für alle öffentlichen Endpoints
- IP-basierte Limits
- Burst-ProtectionBest Practices
✅ Do:
- Regelmäßige OPNSense Updates (Security-Patches)
- Firewall-Regeln regelmäßig reviewen
- VPN für alle Admin-Zugriffe verwenden
- Monitoring der System-Logs
- Backup der Konfiguration
❌ Don't:
- Standard-Passwörter verwenden
- Unnötige Ports öffnen
- Ohne Rate-Limiting laufen lassen
- Firewall-Logs ignorieren
- Direkten SSH-Zugang aus dem Internet