A Linux netfilter module to aid in (d)dos protection
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3.6 KiB

What is the cookie

The cookie is used to prevent address spoofing, without the firewall having to remember the ip-address of the clients. It does this by forcing the client to send a cookie, it can only get from the server. The cookie is generated from the current time, the source and destination address and port, and a secret that only the server has. It works on the same principle that authenticators do. This method forces the client to reply with the same ip/port to the same server ip/port in order to continue.

How is the cookie generated

The cookie is the hashed ClientIp, ServerIp, ClientPort and ServerPort using siphash24 and a key that is one quarter of a cookie_seed. Every second another quarter of the cookie_seed is used as key. The server generates a new cookie_seed every 4 seconds, and always keeps 2 cookie_seeds. That means a client has atleast 4 seconds, and atmost 8 seconds to reply before the cookie becomes invalid. ClientIp, ServerIp, ClientPort and ServerPort are in network order.

cookie_seed = sha512(random_seed << 32 | (unix_time & 0xffffffff))
cookie = siphash24(cookie_seed >> ((time & 3) * 128), Concat(ClientIp, ServerIp, ClientPort, ServerPort))

What is the Random-Seed

The server keeps a secret called random-seed. Should a attacker ever get hold of the random-seed a new random-seed must be used. Otherwise any protection that the cookie offers would be compromised. Since a cookie is only valid for atmost eight seconds, changing the random-seed would at the worst prevent users from logging into a Teamspeak-Server for atmost eight seconds, but the most common case would be no outage what so ever.

How to generate a Random-Seed

xxd -l 60 -c 60 -p /dev/urandom > random_seed

Format of COMMAND_GET_COOKIE

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'T'      |      'S'      |       '3'     |      'I'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      'N'      |      'I'      |       'T'     |      '1'      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           PacketId            |           ClientId            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Type + Flags |                Client Version                ->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                |    Command    |           Timestamp          ->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                |       Random Sequence        ->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                |            RESERVERD          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            RESERVED                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            RESERVERD          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • All fields are encoded in big endian, unless otherwise specified.
  • PacketId is always 101.
  • ClientId is always 0.
  • Type + Flags is always 0x88.
  • Client Version is the build number of the client.
  • Command is always 0.
  • Timestamp is the unixtime of the client maschine, encoded in big endian.
  • Random Sequence is a random value generated by the client.
  • Every RESERVED field must be zero.