DIY Debian Router - Part 7: System hardening and kernel tuning
Introduction
This is Part 7 of the DIY Debian Router series. See Part 1 for the series introduction and links to all parts.
The Linux kernel exposes hundreds of tunable parameters via sysctl, controlling network stack behavior, security policies, and performance characteristics. This part covers networking, kernel hardening, and optimization for our router.
We'll cover:
- IP forwarding and routing configuration
- Anti-spoofing mechanisms (ARP security, reverse path filtering)
- TCP/IP stack hardening (SYN cookies, RFC 1337 protection)
- Connection tracking optimization
- DoS mitigation (ICMP rate limiting, SYN flood protection)
- Kernel security hardening (ASLR, BPF restrictions, dmesg protection)
- Network performance tuning (buffer sizes, autotuning)
sysctl persistence
Kernel parameters configured via sysctl -w are lost on reboot. For persistence, we'll write parameters to /etc/sysctl.d/99-router.conf, which is automatically loaded at boot by systemd.
The filename prefix 99- ensures this configuration loads after distribution defaults (typically 10- through 50-), allowing overrides of system defaults.
Complete sysctl configuration
/etc/sysctl.d/99-router.conf
Expand to view config
# Sysctl configuration for secure home router
################## ARP Security & Anti-Spoofing ##################
# Only respond to ARP requests for addresses on receiving interface
# Avoid source address not in target subnet when sending ARP requests
# Only reply to ARP requests for IPs configured on incoming interface
################## Per-Interface Settings (WAN) ##################
# IPv4 WAN interface hardening
# IPv6 WAN interface settings
################## Per-Interface Settings (LAN) ##################
# IPv4 LAN interface hardening
# IPv6 LAN interface settings
################## IPv4 Forwarding & Routing ##################
# Enable IPv4 forwarding (REQUIRED for router functionality)
# Disable source routing (security - prevents packet routing manipulation)
# Enable reverse path filtering (anti-spoofing)
# Mode 1 = strict mode (recommended for routers with asymmetric routing awareness)
# Disable redirects (security - prevents MITM attacks)
# Do not send ICMP redirects (we are a router, but this prevents abuse)
# Ignore ICMP echo requests to broadcast/multicast (smurf attack protection)
# Ignore bogus ICMP error responses
# Log martian packets (packets with impossible addresses)
################## IPv6 Forwarding & Routing ##################
# Enable IPv6 forwarding (REQUIRED for IPv6 router functionality)
# Accept Router Advertisements on WAN interface ONLY
# Note: Forwarding enabled disables RA by default, override per-interface
# Disable IPv6 source routing (security)
# Disable IPv6 redirects (security)
# Do not accept Router Preference from RA
# Do not learn Prefix Information in RA
# Do not accept default router from RA (we are the router)
# Don't autoconfigure addresses from RA (except on WAN)
# Number of Router Solicitations to send (for DHCPv6-PD)
################## TCP/IP Stack Hardening ##################
# Enable SYN cookies (SYN flood protection)
# Increase SYN backlog for better performance under load
# Disable TCP timestamps (privacy - prevents uptime detection)
# Note: Disabling may reduce performance on high-bandwidth connections
# net.ipv4.tcp_timestamps = 0
# Enable TCP selective acknowledgments (performance)
# Enable TCP window scaling (performance for high-bandwidth connections)
# Protect against time-wait assassination (security)
# Decrease TIME_WAIT timeout (performance - faster port reuse)
# Increase max number of connection tracking entries
# Timeout for established connections (default is usually good)
# Enable conntrack helper autoassignment (needed for some protocols like FTP)
# Set to 0 for security, 1 for compatibility
################## Network Performance Tuning ##################
# Increase the maximum socket receive buffer size
# Increase the maximum socket send buffer size
# Increase Linux autotuning TCP buffer limits
# Min, default, and max number of bytes to use
# Increase the maximum number of packets queued on the INPUT side
# Increase the maximum amount of option memory buffers
# Enable MTU probing (helps with PMTUD issues)
# Increase local port range for outgoing connections
# Allow reuse of sockets in TIME_WAIT state (performance)
################## Kernel Security ##################
# Restrict kernel logs to root only
# Restrict access to kernel pointers in /proc
# Disable kernel module loading after boot (optional, uncomment for hardening)
# kernel.modules_disabled = 1
# Enable ASLR (Address Space Layout Randomization)
# Restrict perf events to root
# Restrict BPF to privileged users only
# Restrict userfaultfd to privileged users
################## File System Security ##################
# Restrict symlink following
# Restrict FIFO access in sticky directories
# Restrict regular file access in sticky directories
################## Rate Limiting & DoS Protection ##################
# Limit ICMP rate (packets per second)
# Which ICMP types to rate limit (default is all except ping reply)
# IPv6 ICMP rate limiting
################## Additional Security Settings ##################
# Ignore all ICMP echo requests (uncomment to disable ping entirely)
# net.ipv4.icmp_echo_ignore_all = 1
# net.ipv6.icmp.echo_ignore_all = 1
# Disable core dumps (security - prevents information leakage)
# Restrict ptrace to parent process only
################## IPv6 Privacy Extensions ##################
# Enable IPv6 privacy extensions for LAN clients
# This is handled by clients, but router should allow it
# Temporary address valid lifetime
# Temporary address preferred lifetime
# Maximum number of temporary addresses
################## End of Configuration ##################
Key configuration aspects:
- IP forwarding enabled (
ip_forward=1,ipv6.forwarding=1) to route packets between interfaces - Strict reverse path filtering (
rp_filter=1) validates source addresses to prevent IP spoofing - ARP security (
arp_filter,arp_announce,arp_ignore) prevents cache poisoning and routing manipulation - Source routing disabled (
accept_source_route=0) blocks legacy routing manipulation attacks - ICMP redirects blocked (
accept_redirects=0,send_redirects=0) prevents man-in-the-middle attacks - SYN flood protection (
tcp_syncookies=1,tcp_max_syn_backlog=4096) defends against connection exhaustion - Connection tracking scaled (
nf_conntrack_max=262144) supports up to 262k simultaneous connections (~75 MB RAM) - Socket buffers increased (16 MB max with TCP autotuning) for gigabit throughput optimization
- Ephemeral port range expanded (1024-65535) provides ~64k ports for high-concurrency scenarios
- Full ASLR enabled (
randomize_va_space=2) randomizes memory layout to hinder exploits - Kernel pointer hiding (
kptr_restrict=2) prevents memory layout disclosure even to root - Unprivileged BPF disabled (
unprivileged_bpf_disabled=1) restricts BPF to root - Filesystem protections (
protected_symlinks,protected_fifos) prevent/tmpattacks against privileged processes - Core dump restrictions (
suid_dumpable=0) disables dumps for setuid programs to prevent credential leakage - Per-interface boundaries: WAN uses strict filtering and accepts RAs; LAN uses loose filtering for asymmetric routing support
Load the configuration immediately:
Verify global settings:
Both should return 1.
Verify per-interface settings:
Reboot to ensure persistence:
After reboot, verify settings persist:
Testing and verification
IP forwarding test
From a LAN client, test Internet connectivity:
Both should succeed. If forwarding is disabled, traffic does not traverse the router.
Anti-spoofing test (simulated)
From the router, attempt to send packets with a spoofed source address (requires raw socket capability):
With rp_filter=1, the kernel drops these packets at the source. If you enabled logging, check dmesg for martian packet logs.
Connection tracking table inspection
Monitor connection tracking table size:
Under normal load, count should be well below max. If count approaches max, increase nf_conntrack_max.
Troubleshooting common issues
High latency on gigabit connections
If throughput is good but you observe latency spikes, the cause may be insufficient buffer sizes or queue depth.
To fix, increase buffer sizes and queue depth, e.g.,:
IPv6 clients not receiving RAs
If IPv6 stopped working after applying sysctl configuration, it may be due to accept_ra=0 overriding systemd-networkd settings.
To fix, ensure WAN interface configuration includes IPv6AcceptRA=yes in /etc/systemd/network/20-wan.network:
[IPv6AcceptRA]
yes
Advanced tuning considerations
High-concurrency scenarios (>10,000 Connections)
For routers serving thousands of connections:
Tradeoff: Higher memory, e.g., 1M tracked connections ≈ 300 MB RAM.
Low-Latency optimization
For real-time applications (video conferencing, gaming, etc):
Tradeoff: Increased CPU usage in exchange for reduced latency.
You can find more information in this article.
Performance baseline
After applying all configurations, establish a performance baseline using iperf3:
# Server on LAN:
# Client on another LAN device:
You should see near line-rate (900+ Mbps for gigabit Ethernet).
Check latency by doing a simple ping from a client:
Should see <10 ms for most residential Internet connections.
Next steps
With our sysctl configuration, our router now provides solid networking with a strong security posture. You could stop here. But that would be boring, continue to Part 8 to set up WireGuard for secure remote access.