zhoudu
zhoudu

Reputation: 661

In Java, how to write a TCP server with defense of slow TCP attacks?

In Java, the simple way to write a TCP server is to use the ServerSocket class. When using the ServerSocket class, the server program calls the accept() method of this class to get an object of the Socket class, which represents a connection with a client, and then, creates a new thread, and in this new thread, calls the getInputStream() and getOutputStream() methods of the Socket object to get an InputStream and an OutputStream, and then read and write TCP data via them. The original thread (the thread that calls the accept() method of the ServerSocket class) continues to call the accept() method, to repeat this, in order to handle multiple clients at the same time. The server program may set a restriction of the maximum number of simultaneous connections (the same with the maximum number of threads processing Socket objects).

However, it seems that, this simple way gives the task of reading and writing data to the TCP protocol entirely, which is vulnerable to slow TCP attacks. For example, a malicious client may send and receive TCP data very slowly (maybe 1 byte per 20 seconds), but not too slowly to trigger TCP timeout. Such behaviours may exhaust the server resources (for example, reaching the maximum number of simultaneous connections) easily. Therefore, this can be a powerful denial of service attack.

I want to know: How can I prevent this?

I have an idea: to send and receive data above a minimum speed (for example, 1 KB per 30 seconds. The exact minimum speed restriction can be configured), and if the speed is lower, the server program aborts this connection. In detail, the server program sends or receives a certain amount of data (for example, 1 KB, or less if the data that needs to be sent or received is less) with a certain timeout (for example, 30 seconds), and if the timeout is reached, the program aborts the connection. But this needs the Socket class to support such data sending and receiving with timeout. It seems that the Socket class doesn't provide this.

Upvotes: 1

Views: 111

Answers (1)

Michael
Michael

Reputation: 44240

"this needs the Socket class to support such data sending and receiving with timeout. It seems that the Socket class doesn't provide this"

Yes it does. Socket::setSoTimeout(int)

Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

Ways of mitigating that kind of attack, according to Wikipedia:

While there are no reliable configurations of the affected web servers that will prevent the Slowloris attack, there are ways to mitigate or reduce the impact of such an attack. In general, these involve increasing the maximum number of clients the server will allow, limiting the number of connections a single IP address is allowed to make, imposing restrictions on the minimum transfer speed a connection is allowed to have, and restricting the length of time a client is allowed to stay connected

Upvotes: 1

Related Questions