Server security

Garry's Mod: Securing a Server Against Exploits and Connection Floods

August 5, 2026 · 8 min read
Illustration immersive du sujet : Garry's Mod server security

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 RunString and CompileString protections, 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 processing
  • XDP_TX — bounce back on the same interface (rare for game servers)
  • XDP_REDIRECT — forward to another interface
  • XDP_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:

  1. XDP BPF map (LPM_TRIE or HASH): checked at driver RX, drops packets before allocation—ideal for high-volume sources.
  2. 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:

  1. Updates the BPF map using bpf_map_update_elem via the agent's embedded BPF syscall wrapper.
  2. Executes nft add element inet pakkt blacklist { 203.0.113.42 } to mirror the entry.
  3. 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=y in 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_allowupload and sv_allowdownload to 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 groupallow policies; never grant full FCVAR_SERVER_CAN_EXECUTE to 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 DROP all 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.

Protect your servers

Deploy PAKKT in 30 seconds

Dual-layer kernel protection. XDP + nftables. Driven from a central panel. 7-day free trial.