SSL renegotiation DOS mitigation

Problem this snippet solves:

See this article for complete details.

Earlier this year, a paper was posted to the IETF TLS working group outlining a very easy denial of service attack that a single client could use against a web server that supports SSL/TLS.

http://www.ietf.org/mail-archive/web/tls/current/msg07553.html

The premise of the attack is simple: “An SSL/TLS handshake requires at least 10 times more processing power on the server than on the client”. If a client machine and server machine were equal in RSA processing power, the client could overwhelm the server by sending ten times as many SSL handshake requests as the server could service. This vulnerability exists for all SSL negotiations; the only mitigation is the ratio between the two participants, which is why SSL acceleration is such a critical feature.

Because BIG-IP uses state-of-the-art hardware crypto-processors, it is certainly not vulnerable to a single attack from a single client. However, it is quite conceivable that someone might very easily modify one of the botnets tools (such as the Low Orbit Ion Cannon that we saw used in the Wikileaks attacks) and thus the attack could become distributed.

How to use this snippet:

This iRule requires LTM v10.1 or higher.

Credits

iRule created by Jason Rahm, David Holmes, Spark, Hoolio, with input by others.

Code :

when RULE_INIT {

# The goal of this iRule is to limit the number of SSL handshakes per client IP to a virtual server IP:port
# over a given time interval to mitigate SSL renegotiation DOS attacks
#
# Adapted from:
# https://devcentral.f5.com/s/weblogs/david/archive/2011/05/03/ssl-renegotiation-dos-attack-ndash-an-irule-countermeasure.aspx#feedback

# Maximum handshakes per time interval (in seconds)
set static::max_handshakes 5
set static::interval 60
}
when CLIENT_ACCEPTED {
# Initialize a counter for the number of handshakes on this connection
set hs_count 0
}
when CLIENTSSL_HANDSHAKE {

# Use the client IP and VS IP:port to identify a connection flow
set flow "[IP::client_addr]@[IP::local_addr][TCP::local_port]"

# Count the handshakes on this connection
incr hs_count

# Save the count in a subtable for this connection
table set -subtable "hs_rate:$flow" "[TCP::client_port]:$hs_count" "-" indefinite $static::interval

# If the count of connections with a handshake is over the maximum, 
# wait 5 seconds and then drop the connection from the connection table
if { [table keys -count -subtable "hs_rate:$flow"] > $static::max_handshakes } {

after 5000
drop
}
}
when CLIENT_CLOSED {
# Delete the subtable entries for this connection
for { set i 1 } { $i <= $hs_count } { incr i } {
table delete -subtable "hs_rate:$flow" "[TCP::client_port]:$i"
}
}
Published Mar 18, 2015
Version 1.0
No CommentsBe the first to comment