Garry's Mod: Securing a Server Against Exploits and Connection Floods
Garry's Mod server security remains a pressing concern in 2026, as legacy vulnerabilities and modern attack vectors continue to threaten community-run instances. Despite patches from Facepunch and the Source engine's maturation, GMod servers face a unique combination of Lua sandbox escapes, network-layer DDoS floods, and exploit chains targeting outdated addons. This article examines whether your server is still exposed, which attack surfaces persist, and how kernel-level defenses like XDP and nftables can mitigate threats without breaking compatibility with essential workshop content or admin tools.
We'll walk through the current threat landscape, explain why userspace mitigations fall short under volumetric attacks, and demonstrate how to configure stateless packet filtering at the XDP layer alongside stateful connection tracking in nftables—all without conflicting with existing Docker containers, fail2ban rules, or iptables-persistent configurations.
The 2026 Garry's Mod Exploit Landscape
Garry's Mod inherits vulnerabilities from three layers: the Source engine (branch ~2013), third-party Lua addons, and the network stack exposed on UDP port 27015 (game) and TCP port 27015 (RCON). While Valve periodically patches critical engine bugs, GMod servers often lag behind due to addon incompatibilities or manual update cycles.
Persistent Attack Vectors
- Lua Sandbox Escapes: Malicious workshop addons or injected Lua code can bypass
RunStringandCompileStringprotections, granting attackers file-system access or arbitrary command execution. - Network-Layer DDoS: UDP amplification (Source engine A2S_INFO queries return ~300–800 bytes per 25-byte request), SYN floods against RCON, and ICMP attacks targeting the host interface.
- Addon Chain Exploits: Popular frameworks (DarkRP, Pointshop, ULX) contain outdated dependencies; attackers chain CVE disclosures in MySQL connectors (e.g., MySQLOO) or HTTP libraries (CHTTP, gmsv_reqwest) to pivot from in-game admin to root shell.
- Resource Exhaustion: Prop spam, entity floods, and net-message bombs that crash the server or saturate CPU before application-layer rate-limits engage.
Why Traditional Mitigations Fail Under Load
Userspace firewalls like UFW or iptables process packets after they traverse the network stack, consuming CPU cycles even when dropping malicious traffic. At 500k pps—a modest DDoS by 2026 standards—interrupt handling and conntrack table lookups can saturate cores, leaving legitimate players unable to connect. Application-layer addons (e.g., anti-DDoS Lua scripts) only see packets that already reached gmsv_dedicated, so they cannot prevent kernel-level resource exhaustion.
Cloud scrubbing services (Cloudflare Spectrum, OVH Game DDoS Protection) mitigate volumetric attacks upstream but add 15–40 ms latency and monthly costs starting at €40–200. For community servers on tight budgets, kernel-level protection on the server itself offers a cost-effective first line of defense.
Kernel-Level Defense: XDP + nftables Architecture
XDP (eXpress Data Path) and eBPF allow you to filter packets at the network driver layer—before sk_buff allocation—delivering sub-microsecond per-packet processing and the ability to handle several million pps on commodity hardware. When combined with nftables' stateful connection tracking, you gain both high-throughput pre-filtering (XDP) and nuanced policy enforcement (nftables), all without disrupting Docker's DOCKER-USER chain or fail2ban's dynamic IP blocks.
How XDP Works for GMod Servers
An XDP program attaches to your primary network interface (e.g., eth0) and inspects Ethernet, IP, and transport-layer headers in a single pass. For each packet, the program returns one of five verdicts:
XDP_DROP— discard immediately (zero CPU overhead beyond BPF instructions)XDP_PASS— hand to kernel stack for normal processingXDP_TX— bounce back on the same interface (rare for game servers)XDP_REDIRECT— forward to another interfaceXDP_ABORTED— error condition
By maintaining BPF maps (hash tables in kernel memory), you can enforce:
- IP blacklist / whitelist with O(1) lookup
- Per-port packet-per-second (pps) rate-limits using a sliding window or token bucket
- Global pps caps to prevent interface saturation
- Min/max packet size filters (drop DNS amplification responses, oversized UDP fragments)
PAKKT.io deploys a single XDP program per interface—the PAKKT Engine—capable of handling up to 256 simultaneous rules driven by BPF maps. Each rule specifies a port range, protocol (TCP/UDP/ICMP/any), action (block / rate_limit / allow_only), and optional max_pps or packet-size bounds. Because XDP is stateless, it excels at volumetric flood mitigation but cannot track TCP handshake state or per-connection quotas—that's where nftables complements the stack.
Stateful Protection with nftables
The nftables framework (successor to iptables) provides connection tracking (conntrack), TCP flag validation, and per-connection rate-limiting via the meter primitive. PAKKT provisions an isolated inet pakkt table, ensuring zero conflict with Docker's nat table, existing filter rules, or fail2ban's f2b-sshd chains.
Example ruleset for a GMod server on TCP/UDP 27015:
table inet pakkt {
chain input {
type filter hook input priority filter; policy accept;
# Allow established/related (players already connected)
ct state established,related accept
# Drop invalid packets
ct state invalid drop
# SYN flood protection: max 50 new TCP conns/sec to RCON
tcp dport 27015 tcp flags syn ct state new limit rate 50/second accept
tcp dport 27015 tcp flags syn drop
# UDP game traffic: per-source IP rate-limit (100 pps/IP)
udp dport 27015 meter player_limits { ip saddr limit rate 100/second } accept
udp dport 27015 drop
# ICMP: allow ping at 10/sec, drop the rest
icmp type echo-request limit rate 10/second accept
icmp type echo-request drop
}
}
Apply with:
nft -f /etc/nftables.d/pakkt.nft
This configuration permits legitimate players (established connections) unrestricted throughput while throttling new connection attempts and per-IP UDP packet rates—critical for mitigating A2S_INFO reflection and handshake floods.
Deploying Dual-Layer IP Lists and Real-Time Monitoring
Static rulesets alone cannot adapt to evolving attacks. Modern DDoS campaigns rotate source IPs every few minutes, and manual nft add element commands introduce operator latency. A centralized control plane synchronizes blacklist/whitelist updates across XDP maps and nftables sets in real time, enabling sub-second response to new threat intelligence.
Dual-Layer IP Blacklist/Whitelist
PAKKT maintains two synchronized representations of each IP list:
- XDP BPF map (
LPM_TRIEorHASH): checked at driver RX, drops packets before allocation—ideal for high-volume sources. - nftables named set (
set blacklist { type ipv4_addr; }): enforces the same policy in the stateful layer, catching any packets that bypass XDP (e.g., due to hardware offload limitations).
When an admin adds an IP to the blacklist via the PAKKT dashboard or API, the Go agent:
- Updates the BPF map using
bpf_map_update_elemvia the agent's embedded BPF syscall wrapper. - Executes
nft add element inet pakkt blacklist { 203.0.113.42 }to mirror the entry. - Logs the action to the audit trail (timestamped, attributed to the API key or user account).
The agent performs this synchronization within 30 seconds (the heartbeat interval) or immediately if the dashboard pushes a priority update over the mTLS channel.
GeoIP Insights and Per-Port Metrics
Understanding where attacks originate and which ports absorb the most traffic is essential for tuning rules. PAKKT's centralized panel integrates MaxMind GeoIP2 data to render:
- A world heatmap of source IPs (last 24 hours)
- Top 10 source countries by packet count
- Top 10 individual IPs and their GeoIP metadata
Per-port and per-rule metrics—stored in TimescaleDB for efficient time-series queries—let you correlate traffic spikes with rule changes. For instance, if you observe a sudden 200k pps surge on UDP 27015 from a single ASN, you can instantly add that netblock to the XDP blacklist and watch the mitigation take effect in the next dashboard refresh (1-second polling interval).
Internal agent logs (syslog forwarding, queryable via the panel) capture BPF program load/unload events, map resize operations, and nftables rule commits, providing full auditability for compliance or post-incident analysis.
Practical Hardening Checklist for GMod in 2026
Combine kernel-level defenses with application-layer hygiene to close as many attack surfaces as possible:
1. Kernel & Driver Requirements
- Linux kernel 5.x or higher (XDP generic mode requires 4.18+, native mode benefits from 5.x+ driver support)
- Verify XDP support:
ip link set dev eth0 xdp obj pakkt_engine.bpf.o sec xdp - Enable BTF (BPF Type Format) for CO-RE portability:
CONFIG_DEBUG_INFO_BTF=yin kernel config
2. Network-Layer Rules
- XDP rule: rate-limit UDP 27015 to 10,000 pps globally (adjust based on player cap × 66 tickrate)
- XDP rule: drop packets <28 bytes or >1400 bytes on UDP 27015 (filters malformed queries and fragmentation attacks)
- nftables: enforce TCP SYN cookies implicitly via
tcp flags syn ct state new limit rate over 100/second drop - nftables: block all traffic except SSH (22), game (27015), and optional web panel (443) unless explicitly allowed
3. Application-Layer Hardening
- Disable
sv_allowuploadandsv_allowdownloadto prevent client-supplied Lua execution - Run a dedicated MySQL server with
bind-address=127.0.0.1; never expose 3306 to the internet - Audit workshop collections monthly; remove unmaintained addons (check GitHub last-commit dates)
- Use ULX or ServerGuard with strict
ulx groupallowpolicies; never grant fullFCVAR_SERVER_CAN_EXECUTEto untrusted admins
4. Monitoring & Incident Response
- Enable PAKKT's real-time dashboard to observe pps trends per port
- Configure alerts (webhook to Discord/Slack) when global pps exceeds baseline × 3
- Review audit logs weekly for unexpected blacklist additions or rule deletions
- Test fail-over: temporarily set XDP policy to
DROPall and verify your SSH whitelist rule works
5. Integration with Existing Infrastructure
If you manage multiple GMod servers via Pterodactyl v1.x, PAKKT's public API allows you to programmatically apply protection templates (e.g., "GMod DarkRP," "GMod TTT") to each node. The API accepts JSON payloads specifying rule sets, IP lists, and per-server overrides, enabling infrastructure-as-code workflows with Ansible or Terraform.
Because PAKKT provisions rules in an isolated inet pakkt table, you retain full control over Docker's DOCKER-USER chain (for container port forwarding) and fail2ban's dynamic filter chains (for SSH brute-force protection)—zero conflict, zero manual iptables surgery.
Conclusion
Garry's Mod servers in 2026 remain exploitable through Lua sandbox weaknesses, network-layer DDoS, and outdated addon dependencies. However, deploying XDP for stateless, high-throughput packet filtering alongside nftables for stateful connection tracking delivers robust kernel-level defense without application changes or prohibitive latency. By combining dual-layer IP lists, per-port rate-limits, and centralized real-time monitoring, server operators can mitigate volumetric floods, enforce strict ingress policies, and maintain audit trails—all while preserving compatibility with Docker, fail2ban, and existing firewall rules. Regular addon audits and strict RCON access controls complete a defense-in-depth posture suited to community-run GMod instances on any Linux host.
FAQ
Can XDP block Lua sandbox exploits in Garry's Mod addons?
No. XDP operates at the network driver layer and inspects only Ethernet, IP, and transport headers—it cannot parse Lua bytecode or application payloads. Lua sandbox escapes must be mitigated by vetting workshop addons, disabling RunString on untrusted input, and running the game server under a restricted Linux user with no write access to garrysmod/lua/autorun. XDP's role is to prevent the server from being overwhelmed by network floods that would otherwise mask or enable exploitation attempts.
Does enabling XDP rate-limits break legitimate high-tickrate GMod gameplay?
Not if you size limits correctly. A 128-tick GMod server with 32 players sends roughly 4,096 packets per second outbound and receives a similar inbound rate during peak action. Setting an XDP per-port pps cap of 10,000–15,000 provides headroom for bursts (player connects, map changes) while dropping flood traffic that exceeds normal gameplay by an order of magnitude. Monitor your baseline pps in PAKKT's dashboard for one week, then set the global cap at 2–3× observed peak to avoid false positives.
How do I safely test XDP DROP rules without locking myself out of SSH?
Always whitelist your management IP in both the XDP BPF map and nftables before deploying broad DROP policies. For example, add your office IP to the whitelist via bpftool map update name pakkt_whitelist key 198.51.100.10 value 1 and the corresponding nftables rule nft add rule inet pakkt input ip saddr 198.51.100.10 accept. Then load the XDP program in generic mode first (ip link set dev eth0 xdpgeneric …) so you can unload it with a simple ip link set dev eth0 xdpgeneric off if connectivity breaks. Only switch to native mode once you confirm SSH and game traffic flow correctly.
Deploy PAKKT in 30 seconds
Dual-layer kernel protection. XDP + nftables. Driven from a central panel. 7-day free trial.