Search code examples
linuxubuntutcpiptablespacket

IP Table rule to drop TCP packet and connection if PSH payload does not begin with specific bytes


We have an old multiplayer game (no source code) which crashes any time someone sends the server unexpected packets, and many of the players use telnet to do it with ease. I'm using iptables, and I want to filter out packets (and drop the connection) that the game server will not recognize. I want to do the following to the game server's port:

Pseudocode

if (PSH flag && Payload.Length > 0 bytes && Payload.Length < 6 bytes)
{
    // reject data, and drop client

}
else if (PSH flag && Payload.Length > 2)
{
    if (First3BytesOfPayload Not in [7f:ef:09, dc:0b:09, 08:00:09])
    {
        // reject data, and drop client

    }
}

This is not a foolproof solution, but it should work good enough for the few people we have. How can I accomplish this with iptables, if at all?

Thank you for your time.


Solution

  • I figured it out. I did it with the rules below (not all the rules), and it works wonderfully. I suppose I could have used the iptables length option, but I didn't need it. Anyone deciding to do this should make it specific to a port, and understand their program's tcp messaging protocol first, or else you may get locked out.

    iptables -A INPUT -p tcp --dport 1949 --tcp-flags ALL PSH,ACK -m u32 --u32 "39&0xFFFFFF=0x7fef09" -j ACCEPT
    iptables -A INPUT -p tcp --dport 1949 --tcp-flags ALL PSH,ACK -m u32 --u32 "39&0xFFFFFF=0xdc0b09" -j ACCEPT
    iptables -A INPUT -p tcp --dport 1949 --tcp-flags ALL PSH,ACK -m u32 --u32 "39&0xFFFFFF=0x080009" -j ACCEPT
    iptables -A INPUT -p tcp --dport 1949 --tcp-flags ALL PSH,ACK -j DROP