What is IPVS Load Balancing?
IPVS (IP Virtual Server) is the transport-layer load balancing engine built directly into the Linux kernel. It intercepts incoming packets at layer 4 (TCP/UDP) and distributes them across a pool of backend servers based on configurable scheduling algorithms. Unlike reverse proxy solutions such as HAProxy or Nginx, IPVS operates at the kernel level, meaning it does not terminate connections—it forwards packets with minimal overhead, achieving near line-speed throughput and extremely low latency.
IPVS is managed through the ipvsadm userspace tool and is commonly paired with keepalived for high-availability Virtual IP (VIP) management. It supports three forwarding modes: Direct Routing (DR), Network Address Translation (NAT), and IP Tunneling (TUN). Each mode has distinct security implications that must be understood before deployment.
Why Security Hardening Matters
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →By default, IPVS configurations are functional but not secure. A misconfigured IPVS setup can expose backend servers to direct internet access, allow traffic from unintended sources, or become a vector for amplification attacks. Attackers who gain access to the load balancer host can manipulate the IPVS ruleset, redirect traffic to malicious destinations, or perform ARP poisoning in DR mode setups. Hardening is therefore not optional—it is a fundamental part of deploying IPVS in production.
Key risks include:
- ARP interference in DR mode, where backend servers may respond directly to client ARP requests, bypassing the load balancer
- Unauthorized access to the VIP from untrusted networks
- Exposed backend services if firewall rules are not properly scoped
- Resource exhaustion attacks such as SYN floods targeting the connection tracking table
- Privilege escalation through the
ipvsadmbinary or/proc/net/ip_vsexposure
Understanding IPVS Forwarding Modes and Their Security Profiles
Direct Routing (DR) Mode
In DR mode, the load balancer forwards packets to backend servers without modifying the source or destination IP addresses. The backend servers must have the VIP configured on a loopback interface (typically lo:0) and respond directly to the client. This mode delivers the highest performance but introduces a critical security nuance: backend servers must be prevented from answering ARP requests for the VIP, otherwise clients may bypass the load balancer entirely.
Backend servers must be hardened with ARP suppression. The following sysctl settings are mandatory on each real server:
# On each backend server, configure ARP suppression for the VIP
# Replace eth0 with the interface facing the load balancer
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
# Apply immediately
sysctl -w net.ipv4.conf.eth0.arp_ignore=1
sysctl -w net.ipv4.conf.eth0.arp_announce=2
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
Additionally, the VIP on the loopback interface must be configured with a netmask of /32 to prevent the kernel from considering it a local subnet route:
# Configure VIP on loopback with host mask
ip addr add 192.0.2.100/32 dev lo
# Prevent the lo interface from advertising the VIP
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
NAT Mode
In NAT mode, the load balancer rewrites the destination IP address (and optionally the source IP) of incoming packets. Backend servers see traffic sourced from the load balancer's internal IP. This mode naturally isolates backend servers from direct client contact, but the load balancer becomes a single point of failure for connection tracking. The nf_conntrack table can overflow under high connection rates, leading to dropped packets.
Hardening NAT mode involves protecting the connection tracking infrastructure:
# Increase conntrack limits to resist exhaustion
net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
# Apply
sysctl -p /etc/sysctl.d/50-ipvs-conntrack.conf
IP Tunneling (TUN) Mode
TUN mode encapsulates packets using IP-in-IP tunneling. Security concerns mirror DR mode regarding ARP handling, plus additional risks from tunnel interface exposure. Tunnel interfaces should be firewalled to accept only encapsulated traffic from the load balancer's source IP.
Firewall Integration with IPVS
IPVS operates below iptables/nftables in the network stack, which means firewall rules must be carefully coordinated. A common hardening pattern is to use nftables to restrict which source IPs can reach the VIP, while IPVS handles the load distribution logic.
Example nftables ruleset to protect an IPVS VIP:
#!/usr/bin/nft -f
table inet ipvs-shield {
# Define the VIP and allowed client subnets
set allowed_clients {
type ipv4_addr
flags interval
elements = { 203.0.113.0/24, 198.51.100.0/24 }
}
chain input {
# Allow established connections for management
ct state established,related accept
# Restrict VIP access to allowed clients only
ip daddr 192.0.2.100 ip saddr @allowed_clients accept
ip daddr 192.0.2.100 tcp dport { 80, 443 } drop
# Allow SSH only from internal management network
tcp dport 22 ip saddr 10.0.0.0/8 accept
tcp dport 22 drop
}
chain forward {
# In DR/NAT mode, protect backend network
ip daddr 10.0.1.0/24 ip saddr != 10.0.0.5 drop
}
}
# Load the ruleset
nft -f /etc/nftables/ipvs-shield.conf
For DR mode, an additional critical step is to ensure the backend servers themselves have firewall rules that reject traffic destined to the VIP on the wrong interface, preventing accidental exposure:
# On each backend server with nftables
table inet backend-guard {
chain input {
# Block VIP traffic arriving on physical interfaces
iif != "lo" ip daddr 192.0.2.100 drop
# Allow VIP traffic only on loopback
iif "lo" ip daddr 192.0.2.100 accept
}
}
Securing the ipvsadm Management Interface
The ipvsadm command requires CAP_NET_ADMIN capability or root privileges. In production, restrict access to this tool to prevent unauthorized modification of the load balancing ruleset.
Restricting ipvsadm Access via Sudo
# /etc/sudoers.d/ipvsadm
# Allow operators to view IPVS state, but restrict modifications
%lb_operators ALL = (root) NOPASSWD: /usr/sbin/ipvsadm -L*
%lb_operators ALL = (root) NOPASSWD: /usr/sbin/ipvsadm -l*
%lb_operators ALL = (root) NOPASSWD: /usr/sbin/ipvsadm -S*
%lb_operators ALL = (root) NOPASSWD: /usr/sbin/ipvsadm --help
# Modifications require lb_admins group
%lb_admins ALL = (root) NOPASSWD: /usr/sbin/ipvsadm
Auditing IPVS Configuration Changes
Enable audit logging for any ipvsadm invocation that modifies state:
# Add audit rules for ipvsadm writes
auditctl -w /usr/sbin/ipvsadm -p x -k ipvs_modification
auditctl -w /proc/net/ip_vs -p w -k ipvs_kernel_write
# Make audit rules persistent in /etc/audit/rules.d/ipvs.rules
echo "-w /usr/sbin/ipvsadm -p x -k ipvs_modification" >> /etc/audit/rules.d/ipvs.rules
echo "-w /proc/net/ip_vs -p w -k ipvs_kernel_write" >> /etc/audit/rules.d/ipvs.rules
augenrules --load
Protecting Against SYN Floods and Connection Exhaustion
IPVS itself has built-in resilience against SYN floods because it does not maintain a half-open connection table like a reverse proxy would. However, when used with NAT mode, the kernel's connection tracking system (nf_conntrack) can become a bottleneck. The following hardening measures apply:
# /etc/sysctl.d/60-ipvs-synprotect.conf
# Enable SYN cookies to resist SYN floods
net.ipv4.tcp_syncookies = 1
# Reduce SYN_RECV timeout
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
# Enable TCP timestamps for better connection tracking efficiency
net.ipv4.tcp_timestamps = 1
# Increase backlog to absorb bursts
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
# Protect against TIME_WAIT exhaustion
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
# Apply
sysctl -p /etc/sysctl.d/60-ipvs-synprotect.conf
For additional protection, integrate iptables rate-limiting on the VIP before traffic reaches IPVS:
# Limit incoming SYN rate to 200/second on the VIP
iptables -A INPUT -d 192.0.2.100 -p tcp --syn -m limit --limit 200/s --limit-burst 300 -j ACCEPT
iptables -A INPUT -d 192.0.2.100 -p tcp --syn -j DROP
Connection Tracking Table Hardening
When IPVS operates in NAT mode, every connection consumes a conntrack entry. Exhaustion of this table causes silent connection drops. Monitor and size the table appropriately:
# Check current conntrack usage
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# Calculate appropriate sizing:
# Expected concurrent connections × 1.3 (safety factor) = conntrack_max
# Example: 100,000 concurrent connections → set to 131072
# Set in /etc/sysctl.d/70-conntrack.conf
net.netfilter.nf_conntrack_max = 131072
net.netfilter.nf_conntrack_buckets = 32768 # max / 4 for hash table efficiency
# Reduce timeouts for faster recycling
net.netfilter.nf_conntrack_generic_timeout = 120
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 30
# Enable conntrack helper auto-assignment only for needed protocols
# Disable automatic helpers to prevent abuse
net.netfilter.nf_conntrack_helper = 0
Monitor conntrack utilization with a simple script to alert before exhaustion:
#!/bin/bash
# Monitor conntrack utilization and alert at 80%
MAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max)
CURRENT=$(cat /proc/sys/net/netfilter/nf_conntrack_count)
USAGE=$(( CURRENT * 100 / MAX ))
if [ $USAGE -gt 80 ]; then
logger -p kern.warning "IPVS conntrack usage at ${USAGE}% (${CURRENT}/${MAX})"
fi
Securing Keepalived for High Availability
Most IPVS deployments use keepalived for VRRP-based failover. The VRRP advertisements must be authenticated and restricted to trusted interfaces.
# /etc/keepalived/keepalived.conf (security-relevant excerpt)
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
# Use VRRP authentication (type 2 = simple password, type 1 = IPSec AH)
authentication {
auth_type PASS
auth_pass "a-strong-random-password-at-least-32-chars"
}
virtual_ipaddress {
192.0.2.100/24 dev eth0
}
# Restrict VRRP to specific source IPs on the peer
# Use iptables/nftables to only accept VRRP from known peers
}
# Corresponding firewall rule for VRRP multicast
# Only accept VRRP advertisements from the known peer IP
iptables -A INPUT -i eth0 -s 10.0.0.2 -d 224.0.0.18 -p vrrp -j ACCEPT
iptables -A INPUT -i eth0 -d 224.0.0.18 -p vrrp -j DROP
Preventing Split-Brain Through Network Isolation
A split-brain scenario where two load balancers both hold the VIP can cause traffic corruption. Mitigate this by ensuring VRRP traffic uses a dedicated management network or by configuring a "backup" firewall rule that blocks the VIP if the node is in BACKUP state:
# keepalived notify script to enforce VIP ownership
# /etc/keepalived/notify.sh
#!/bin/bash
TYPE=$1
NAME=$2
case "$TYPE" in
"MASTER")
# Enable VIP acceptance
iptables -D INPUT -d 192.0.2.100 -j DROP 2>/dev/null
logger "Promoted to MASTER - VIP enabled"
;;
"BACKUP")
# Block VIP traffic to prevent split-brain
iptables -A INPUT -d 192.0.2.100 -j DROP
logger "Demoted to BACKUP - VIP blocked"
;;
"FAULT")
iptables -A INPUT -d 192.0.2.100 -j DROP
logger "FAULT state - VIP blocked"
;;
esac
Kernel Hardening Specific to IPVS
Several kernel parameters directly affect IPVS security and resilience. Apply these in a dedicated sysctl configuration file:
# /etc/sysctl.d/80-ipvs-hardening.conf
# Disable IP forwarding on non-router interfaces
net.ipv4.ip_forward = 1 # Only on interfaces that need it
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.forwarding = 0
# Prevent source-routed packets from bypassing routing decisions
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Drop ICMP redirects to prevent routing table manipulation
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Ignore bogus ICMP errors
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Reverse path filtering prevents IP spoofing
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Protect against martian packets (unroutable source addresses)
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# Disable IP dynamic address space features unless needed
net.ipv4.ip_dynaddr = 0
# Apply
sysctl -p /etc/sysctl.d/80-ipvs-hardening.conf
Monitoring and Intrusion Detection
Continuous monitoring of IPVS state is essential to detect unauthorized changes or anomalous traffic patterns. The /proc/net/ip_vs and /proc/net/ip_vs_stats files expose real-time metrics that can be scraped.
Detecting Unauthorized IPVS Rule Changes
#!/bin/bash
# Monitor IPVS ruleset checksum and alert on changes
# Run via cron every minute
EXPECTED_CHECKSUM_FILE="/var/lib/ipvs/expected_checksum"
CURRENT_RULES=$(ipvsadm -S -n | md5sum | awk '{print $1}')
if [ ! -f "$EXPECTED_CHECKSUM_FILE" ]; then
echo "$CURRENT_RULES" > "$EXPECTED_CHECKSUM_FILE"
exit 0
fi
EXPECTED=$(cat "$EXPECTED_CHECKSUM_FILE")
if [ "$CURRENT_RULES" != "$EXPECTED" ]; then
logger -p kern.alert "CRITICAL: IPVS ruleset changed! Current: $CURRENT_RULES, Expected: $EXPECTED"
# Send alert via your monitoring system
fi
Exporting IPVS Metrics for Prometheus
Use the ipvsadm stats output to feed monitoring systems:
# Extract per-service connection statistics
ipvsadm -L -n --stats --rate
# Example output parsing script for Prometheus textfile collector
#!/bin/bash
# Write IPVS metrics to /var/lib/node_exporter/textfile_collector/ipvs.prom
OUTPUT="/var/lib/node_exporter/textfile_collector/ipvs.prom"
TEMP=$(mktemp)
ipvsadm -L -n --stats | awk '
/^TCP|^UDP/ {
# Parse VIP:Port -> RealServer:Port
vip_port=$2; rs_ip=$3; rs_port=$4
}
/^ ->/ {
gsub(/[^0-9]/, " ", $0)
split($0, vals)
print "ipvs_connections_total{vip=\""vip_port"\",backend=\""rs_ip":"rs_port"\"} " vals[1]
print "ipvs_incoming_packets_total{vip=\""vip_port"\",backend=\""rs_ip":"rs_port"\"} " vals[2]
print "ipvs_outgoing_packets_total{vip=\""vip_port"\",backend=\""rs_ip":"rs_port"\"} " vals[3]
print "ipvs_incoming_bytes_total{vip=\""vip_port"\",backend=\""rs_ip":"rs_port"\"} " vals[4]
print "ipvs_outgoing_bytes_total{vip=\""vip_port"\",backend=\""rs_ip":"rs_port"\"} " vals[5]
}' > "$TEMP"
mv "$TEMP" "$OUTPUT"
Best Practices Summary
- Always use ARP suppression in DR and TUN modes—configure
arp_ignore=1andarp_announce=2on all backend servers - Restrict VIP access at the firewall level before traffic reaches IPVS, using
nftablesoriptablesto enforce source IP allowlists - Never expose
ipvsadmto unprivileged users—usesudopolicies with command restrictions and enable audit logging - Protect VRRP traffic with strong authentication passwords and firewall rules that only accept advertisements from known peer addresses
- Size
nf_conntrack_maxappropriately for NAT mode deployments and monitor utilization continuously - Apply kernel hardening sysctl parameters including reverse-path filtering, ICMP redirect rejection, and source-route disabling
- Implement a notify script in keepalived to block VIP traffic when a node transitions to BACKUP or FAULT state, preventing split-brain
- Monitor IPVS ruleset integrity with checksum-based change detection and alert on any unexpected modification
- Use dedicated management networks for VRRP, SSH, and monitoring traffic, keeping them separate from the load-balanced data path
- Test failover security regularly—simulate MASTER failure and verify that BACKUP nodes correctly assume the VIP without exposing backend servers
Conclusion
IPVS provides a high-performance, kernel-level load balancing foundation, but its raw speed must be paired with deliberate security engineering. The hardening measures outlined in this tutorial—ARP suppression, firewall shielding, connection tracking protection, VRRP authentication, kernel parameter tuning, and continuous monitoring—transform a functional IPVS setup into a resilient, production-grade deployment. Each layer of hardening addresses a specific risk vector, and together they form a defense-in-depth posture that protects both the load balancing infrastructure and the backend services it fronts. Apply these practices incrementally, test each change in a staging environment, and maintain audit trails to ensure your IPVS deployment remains secure as your infrastructure evolves.