networking
Networking: Configuration, Troubleshooting, and Optimization
Configure, troubleshoot, and optimize Linux networking infrastructure. Covers DNS, reverse proxies, VPNs, firewalls (nftables), VLANs, subnetting, high availability, dynamic routing, and network performance tuning.
Target versions (May 2026):
| Tool | Version | Notes |
|---|---|---|
| Caddy | 2.11.2 | Auto-HTTPS, Caddyfile + JSON API |
| Nginx | 1.30.0 stable / 1.29.8 mainline | New stable branch released Apr 2026; verify current advisories |
| Traefik | 3.6.14 | Gateway API native, v2 EOL approaching |
| HAProxy | 3.3.7 stable / 3.2.16 LTS | LTS EOL 2030-Q2 |
| WireGuard tools | 1.0.20260223 | Kernel module + userspace tools |
| strongSwan | 6.0.6 | swanctl config (legacy ipsec.conf deprecated) |
| nftables | 1.1.6 | iptables successor, default on modern distros |
| keepalived | 2.3.4 | VRRP + health checks |
| Unbound | 1.24.2 | CVE-2025-11411 fix (unsolicited NS RRSets) |
| CoreDNS | 1.14.2 | K8s default DNS, plugin-based |
| FRRouting | 10.6.0 | BGP, OSPF, IS-IS, PIM |
| Tailscale / Headscale | Headscale 0.28.0 | Self-hosted control server |
| cloudflared | 2026.3.0 | Cloudflare Tunnel (outbound-only) |
| OpenVPN | 2.7.2 / 2.6.20 LTS | 2.7.x: multi-socket, DCO; 2.6 is the LTS branch |
When to use
- Configuring DNS servers (Unbound, CoreDNS, dnsmasq, BIND9, Pi-hole, AdGuard Home)
- Setting up or troubleshooting reverse proxies and load balancers
- VPN configuration (WireGuard, OpenVPN, IPsec) and overlay networks
- Linux firewall rules (nftables, legacy iptables)
- VLAN configuration, subnetting, network segmentation
- High availability with keepalived/VRRP, floating IPs
- Network diagnostics (tcpdump, mtr, ss, dig, iperf3, Wireshark/tshark)
- TCP/network performance tuning (MTU, buffers, congestion control, bufferbloat)
- Dynamic routing with FRRouting (BGP, OSPF)
- TLS/certificate management for network services
- Split-horizon DNS, DNS-over-HTTPS/TLS, DNSSEC
When NOT to use
- OPNsense/pfSense firewall appliance management (use firewall-appliance)
- Web browsing, scraping, or headless page interaction - use browse
- Kubernetes networking: NetworkPolicy, Gateway API, service mesh, CNI (use kubernetes)
- Broad Kubernetes cluster health checks, node status, and post-maintenance diagnostics (use cluster-health)
- Docker/container networking: bridge, overlay, Compose networks (use docker)
- Cloud VPCs, security groups, managed load balancers (use terraform)
- Network config management at scale via playbooks (use ansible)
- Offensive pentesting, exploitation, lateral movement (use lockpick)
- Application-level security review, SSRF, header injection (use security-audit)
AI Self-Check
Before returning any generated network configuration, verify:
- No hardcoded secrets: passwords, PSKs, API keys use placeholders or env vars
- Correct interface names: didn't assume
eth0- modern Linux uses predictable names (enp0s3,ens18, etc.). Ask or checkip linkoutput - MTU considered: VPN tunnels need reduced MTU (WireGuard: 1420, OpenVPN: ~1400, VXLAN: 1450). Mismatched MTU causes silent packet drops
- DNS resolver order: systemd-resolved vs /etc/resolv.conf vs NetworkManager - check which DNS manager is active before modifying
- Firewall persistence: nftables rules need
nft list ruleset > /etc/nftables.confor a service to persist across reboots. Rawnft addcommands are ephemeral - Port conflicts checked: reverse proxy ports (80, 443) may conflict with existing
services. Verify with
ss -tlnp - TLS versions: minimum TLS 1.2 for all services. TLS 1.3 preferred where supported
- Private IP ranges correct: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (not /24)
- Subnet overlap: VPN address ranges must not overlap with LAN or other VPN ranges
- IPv6 considered: dual-stack config or explicit disable. Half-configured IPv6 leaks traffic around IPv4-only VPNs
- Backup before modifying: save current config before changes (
nft list ruleset > backup.nft,cp nginx.conf nginx.conf.bak). Network misconfigs can lock out remote access - Service reload vs restart: prefer graceful reload (
nginx -s reload,systemctl reload) over restart to avoid dropping active connections - IP forwarding enabled: any config involving routing, VPN, or inter-VLAN traffic
needs
net.ipv4.ip_forward = 1(andnet.ipv6.conf.all.forwarding = 1for dual-stack). Without it, the kernel silently drops forwarded packets - systemd-resolved conflict: if deploying a local DNS server (Unbound, CoreDNS,
dnsmasq), check whether systemd-resolved is binding port 53. Disable its stub listener
(
DNSStubListener=no) or bind your server to a different port
- Current source checked: dated versions, CLI flags, API names, and support windows are verified against primary docs before repeating them
- Hidden state identified: local config, credentials, caches, contexts, branches, cluster targets, or previous runs are made explicit before acting
- Verification is real: final checks exercise the actual runtime, parser, service, or integration point instead of only linting prose or happy paths
- Topology verified: interface names, routes, DNS resolvers, namespaces, VPN state, and firewall backend are observed before changes
- Rollback path preserved: remote network changes include timed rollback, console access, or an alternate path
Performance
- Measure path, DNS, TLS, and application latency separately before tuning.
- Use packet captures with narrow filters and time windows to avoid huge captures and privacy spill.
- Prefer persistent nftables sets, DNS caches, and proxy connection reuse where appropriate.
Best Practices
- Diagnose before changing: capture current routes, rules, addresses, and resolver state.
- Change one layer at a time: DNS, routing, firewall, proxy, VPN, or application.
- Keep emergency access open when editing firewall, VPN, or default-route configuration remotely.
Workflow
Step 1: Identify the task type
| Task type | Start with | Reference |
|---|---|---|
| Troubleshoot | Symptoms, recent changes, affected scope | references/troubleshooting.md |
| Configure DNS | Current resolver, authoritative vs recursive, split-horizon needs | references/dns.md |
| Set up reverse proxy | Which proxy, upstream services, TLS requirements | references/reverse-proxies.md |
| Configure VPN | Topology (p2p, hub-spoke, mesh), protocol choice | references/vpn.md |
| Network segmentation | VLANs, subnets, nftables zones, namespaces | references/segmentation.md |
| High availability | keepalived/VRRP, floating IPs, health checks | references/ha.md |
Step 2: Gather context
Before writing config or running commands:
- What distro and init system? (systemd vs OpenRC - affects service management)
- What's the current network state? (
ip addr,ip route,ss -tlnp,resolvectl status) - Is there an existing firewall? (
nft list ruleset,iptables-save) - Who manages DNS? (
resolvectl statusorcat /etc/resolv.conf- check for systemd-resolved stub) - Any existing VPN/overlay? (
wg show,tailscale status,ip linkfor tun/wg/vxlan devices) - Is this behind NAT? (affects VPN, reverse proxy, and HA design)
Step 3: Implement
Read the appropriate reference file for detailed patterns. Key principles:
- Test before persisting. Add nftables rules, verify connectivity, then save. Apply reverse
proxy config changes with
--dry-runor syntax check first (caddy validate,nginx -t,haproxy -c). - One change at a time. Network misconfigs can lock you out. If working over SSH, set a
revert timer (
at now + 5 minutes <<< 'systemctl restart networking'). - Log what you changed. Network debugging is 10x harder when you don't know what changed.
Step 4: Validate
| What to validate | How |
|---|---|
| DNS resolution | dig @server domain A +short, dig domain AAAA +short |
| Reverse proxy | curl -vk https://domain (check cert, headers, upstream response) |
| VPN tunnel | wg show (WireGuard), ping across tunnel, check ip route |
| Firewall rules | nft list ruleset, test both allowed and blocked traffic |
| VLAN tagging | ip -d link show, tcpdump -e -i interface (check 802.1Q tags) |
| HA failover | Stop primary, verify VIP migrates, check journalctl -u keepalived |
| Performance | iperf3 -c server, mtr target, check for packet loss and jitter |
Quick Reference: Diagnostic Tools
| Tool | Purpose | Key usage |
|---|---|---|
ip |
Interface, route, neighbor, rule management | ip addr, ip route, ip neigh, ip link |
ss |
Socket statistics (replaces netstat) | ss -tlnp (TCP listeners), ss -ulnp (UDP) |
dig |
DNS queries | dig @8.8.8.8 example.com A +short |
mtr |
Combined traceroute + ping | mtr -n --report target (non-interactive) |
tcpdump |
Packet capture | tcpdump -i any -nn port 53 (DNS traffic) |
tshark |
Wireshark CLI | tshark -i any -f 'port 443' -Y 'tls.handshake' |
curl |
HTTP testing | curl -vk -o /dev/null https://target (verbose TLS info) |
iperf3 |
Bandwidth testing | Server: iperf3 -s / Client: iperf3 -c server |
nft |
nftables rule management | nft list ruleset, nft monitor trace |
wg |
WireGuard status | wg show, wg showconf wg0 |
resolvectl |
systemd-resolved status | resolvectl status, resolvectl query domain |
doggo |
Modern dig alternative | doggo example.com A @8.8.8.8 --json |
nmap |
Port scanning, service detection | nmap -sV -p 1-1024 target |
socat |
Multipurpose relay | socat TCP-LISTEN:8080,fork TCP:backend:80 |
Quick Reference: CIDR Cheat Sheet
| CIDR | Netmask | Hosts | Common use |
|---|---|---|---|
| /32 | 255.255.255.255 | 1 | Host route, loopback |
| /31 | 255.255.255.254 | 2 | Point-to-point link (RFC 3021) |
| /30 | 255.255.255.252 | 2 | Legacy point-to-point |
| /29 | 255.255.255.248 | 6 | Small service subnet |
| /28 | 255.255.255.240 | 14 | DMZ, management |
| /27 | 255.255.255.224 | 30 | Small office |
| /26 | 255.255.255.192 | 62 | Department |
| /25 | 255.255.255.128 | 126 | Floor / building wing |
| /24 | 255.255.255.0 | 254 | Standard LAN segment |
| /16 | 255.255.0.0 | 65534 | Large campus / datacenter |
| /8 | 255.0.0.0 | 16M+ | Class A (10.0.0.0/8) |
Private ranges (RFC 1918): 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
CGNAT (RFC 6598): 100.64.0.0/10 (used by Tailscale, carrier NAT)
Link-local: 169.254.0.0/16 (IPv4), fe80::/10 (IPv6)
ULA (IPv6): fd00::/8 (private, like RFC 1918 for IPv6)
Quick Reference: DNS Record Types
| Type | Purpose | Example |
|---|---|---|
| A | IPv4 address | example.com. 300 IN A 93.184.216.34 |
| AAAA | IPv6 address | example.com. 300 IN AAAA 2606:2800:220:1:: |
| CNAME | Alias to another name | www.example.com. IN CNAME example.com. |
| MX | Mail server | example.com. IN MX 10 mail.example.com. |
| TXT | Arbitrary text (SPF, DKIM, verification) | example.com. IN TXT "v=spf1 ..." |
| SRV | Service location | _sip._tcp.example.com. IN SRV 10 5 5060 sip.example.com. |
| NS | Nameserver delegation | example.com. IN NS ns1.example.com. |
| CAA | Certificate authority authorization | example.com. IN CAA 0 issue "letsencrypt.org" |
| SVCB/HTTPS | Service binding (newer) | example.com. IN HTTPS 1 . alpn="h2,h3" |
| PTR | Reverse DNS | 34.216.184.93.in-addr.arpa. IN PTR example.com. |
Quick Reference: Reverse Proxy Selection
| Proxy | Best for | TLS | Config style | L4 support |
|---|---|---|---|---|
| Caddy | Simple setups, auto-HTTPS | Automatic (ACME) | Caddyfile / JSON API | Yes (experimental) |
| Nginx | High traffic, static files | Manual or certbot | nginx.conf | Yes (stream module) |
| Traefik | Docker/K8s, dynamic backends | Automatic (ACME) | Labels / file / K8s CRDs | Yes (TCP/UDP) |
| HAProxy | Pure load balancing, L4/L7 | Manual | haproxy.cfg | Yes (native) |
Caddy reverse proxy quick start
# /etc/caddy/Caddyfile - three subdomains, auto-HTTPS
app.example.com {
reverse_proxy localhost:3000
}
api.example.com {
reverse_proxy localhost:8080
}
grafana.example.com {
reverse_proxy localhost:3001
}
Caddy handles TLS certificate provisioning automatically via ACME (Let's Encrypt). DNS A/AAAA
records for all three subdomains must point to the host. Validate: caddy validate --config /etc/caddy/Caddyfile.
Read references/reverse-proxies.md for configuration patterns, TLS setup,
health checks, rate limiting, and WebSocket/gRPC proxying.
Quick Reference: VPN Protocol Selection
| Protocol | Speed | Complexity | Key exchange | Best for |
|---|---|---|---|---|
| WireGuard | Fastest | Minimal config | Noise (Curve25519) | P2P, hub-spoke, general use |
| OpenVPN | Good | Complex PKI | TLS/x509 | Legacy, tap mode (L2) |
| IPsec (strongSwan) | Good | Most complex | IKEv2 | Site-to-site, standards compliance |
| Tailscale/Headscale | Fast (WG underneath) | Zero config | WG + DERP relays | Overlay mesh, remote access |
| Nebula | Fast | Low | Certificate-based | Large mesh, Slack-scale |
WireGuard site-to-site quick start
# Site A (/etc/wireguard/wg0.conf) - 10.0.1.0/24
[Interface]
PrivateKey = <SITE_A_PRIVATE_KEY>
Address = 10.100.0.1/30
ListenPort = 51820
# MTU = 1420 for most setups; subtract 80 more if over PPPoE
[Peer]
PublicKey = <SITE_B_PUBLIC_KEY>
Endpoint = site-b.example.com:51820
AllowedIPs = 10.0.2.0/24, 10.100.0.2/32
PersistentKeepalive = 25
# Site B (/etc/wireguard/wg0.conf) - 10.0.2.0/24
[Interface]
PrivateKey = <SITE_B_PRIVATE_KEY>
Address = 10.100.0.2/30
ListenPort = 51820
[Peer]
PublicKey = <SITE_A_PUBLIC_KEY>
Endpoint = site-a.example.com:51820
AllowedIPs = 10.0.1.0/24, 10.100.0.1/32
PersistentKeepalive = 25
Both sides need net.ipv4.ip_forward = 1 in /etc/sysctl.d/. AllowedIPs is the remote
subnet (not 0.0.0.0/0 - that's full-tunnel, not site-to-site). Key generation:
wg genkey | tee privatekey | wg pubkey > publickey.
Read references/vpn.md for setup patterns, key management, MTU tuning,
NAT traversal, and overlay network comparison.
Quick Reference: nftables vs iptables
iptables is legacy. nftables is the default on Debian 11+, RHEL 9+, Arch, and most modern distros.
# Minimal nftables ruleset - stateful firewall with SSH
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif lo accept
tcp dport 22 accept
icmp type echo-request accept
icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert } accept
}
chain forward { type filter hook forward priority 0; policy drop; }
chain output { type filter hook output priority 0; policy accept; }
}
Read references/segmentation.md for VLAN setup, nftables zones, network
namespaces, and inter-VLAN routing patterns.
PCI-DSS 4.0 Relevance
Network configuration touches several PCI-DSS requirements:
| Req | Area | What to check |
|---|---|---|
| 1.2 | Network security controls | Firewall rules restrict inbound/outbound to minimum necessary |
| 1.3 | CDE segmentation | VLANs, nftables, or physical separation between CDE and other networks |
| 1.4 | Trusted/untrusted boundaries | Reverse proxy TLS termination, WAF placement |
| 2.2 | Hardening | Disable unnecessary services, unused ports closed |
| 4.1 | Encryption in transit | TLS 1.2+ everywhere, no plaintext on untrusted segments |
| 11.3 | Network monitoring | IDS/IPS (Suricata), log aggregation, flow analysis |
Reference Files
references/dns.md- DNS server comparison, DNSSEC, split-horizon, DoH/DoT, Pi-hole/AdGuard, troubleshootingreferences/reverse-proxies.md- Caddy, Nginx, Traefik, HAProxy configuration patterns, TLS, WebSocket, gRPC, rate limitingreferences/vpn.md- WireGuard, OpenVPN, IPsec/strongSwan setup, overlay networks (Tailscale, Headscale, Nebula, ZeroTier), key managementreferences/segmentation.md- VLANs, subnetting, nftables firewall patterns, network namespaces, IPv6references/troubleshooting.md- Diagnostic methodology, tool deep-dives, common issues, performance tuningreferences/ha.md- keepalived/VRRP, floating IPs, HAProxy + keepalived HA, health check patterns
Output Contract
See skills/_shared/output-contract.md for the full contract.
- Skill name: NETWORKING
- Deliverable bucket:
audits - Mode: conditional. When invoked to analyze, review, audit, or improve existing repo content, emit the full contract -- boxed inline header, body summary inline plus per-finding detail in the deliverable file, boxed conclusion, conclusion table -- and write the deliverable to
docs/local/audits/networking/<YYYY-MM-DD>-<slug>.md. When invoked to answer a question, teach a concept, build a new artifact, or generate content, respond freely without the contract. - Severity scale:
P0 | P1 | P2 | P3 | info(see shared contract; only used in audit/review mode).
Related Skills
- firewall-appliance - manages BSD-based firewall appliances (OPNsense, pfSense). This skill handles Linux networking; firewall-appliance handles FreeBSD appliance firewalls. If the user mentions pfctl, CARP, or OPNsense/pfSense hostnames, route to firewall-appliance.
- kubernetes - owns K8s networking (NetworkPolicy, Gateway API, service mesh, CNI). This skill covers general DNS and proxy config; K8s-specific networking goes to kubernetes.
- cluster-health - owns read-only Kubernetes cluster diagnostics. If the request is "is the cluster healthy?" rather than "configure DNS/proxy/routing", route there.
- docker - owns container networking (bridge, Compose networks, port mapping). This skill covers host-level Linux networking.
- terraform - owns cloud infrastructure (VPCs, security groups, cloud LBs, Route53). This skill covers bare-metal/VM networking.
- ansible - manages config at scale via playbooks. This skill provides the networking knowledge; ansible handles the automation wrapper.
- lockpick - offensive network testing, exploitation, lateral movement. This skill covers defensive configuration and hardening.
- security-audit - application-level security review (SSRF, header injection). This skill covers network-layer security (firewalls, TLS, segmentation).
- browse - web browsing, scraping, headless page interaction. This skill covers network infrastructure, not web content retrieval.
Rules
- Ask which interface. Never assume
eth0. Modern Linux uses predictable interface names. Check withip linkor ask the user. - Test before persisting. Network misconfigs can lock you out of remote machines. Apply changes temporarily, verify connectivity (especially SSH), then persist.
- MTU matters. VPN tunnels, VXLAN, and PPPoE all reduce effective MTU. Mismatched MTU causes silent packet drops that are painful to debug. Always calculate and set explicitly.
- Check who manages DNS. systemd-resolved, NetworkManager, and manual /etc/resolv.conf fight each other. Identify the active manager before making DNS changes.
- Verify the existing firewall. Check
nft list rulesetandiptables-savebefore adding rules. Mixing nftables and iptables on the same system causes unpredictable behavior. - No plaintext on untrusted segments. TLS 1.2+ for all services. If something needs to cross an untrusted network without TLS, tunnel it through a VPN.
- Subnet overlap kills VPNs. Before assigning VPN address ranges, inventory all LAN subnets and existing VPN ranges. Overlapping ranges cause routing black holes.
- Defer to specialized skills. OPNsense/pfSense -> firewall-appliance. K8s networking -> kubernetes. Container networking -> docker. Cloud infra -> terraform. Pentesting -> lockpick.