There have been several (many?) products attempting to solve the TCP
SYN attack through timeouts. They watch the SYN packets, and flush
ones, by doing a RESET on the connection if the third packet isn't
received in time. Or letting conenctions fail by flushing the infant
connection table when full. I believe this is wrong!
There is, I believe, a much simpler solution.
The problem is, as I see it, that the current implementations
are keeping the first packet (in some form) around, as state.
Instead, we want to discard all this state information, to allow
us to accept more packets. Only when we have a full connection
do we want to keep state information. The only piece of
information we require at this early stage is the initial sequence
number for our side.
I propose a solution where the initial sequence number is calculated
(not random), and is based on a cryptographic calculation of the
senders Initial Sequence Number, the ports, and a "per boot"
secret number. In this way the initial packet can be discarded,
and on receipt of the third SYN packet can be recalculated.
This means that initial packets, fired from random addreses will
never have the third packet, and no overheads are consumed,
except for the hash calculation.
Since there is only one random number in the connection, the
initial sequence number from the originating site, there is a
higher probability of "rogue", or lost packets, but if the
initial ISN was truely random this shouldn't be to much of a
problem (hmmm - am I sure?).
Host A to conenct to Host B
host A (good) Host B (good)
send packet to B ---> receives packet, and ISN.
uses F(ISN(A) + ports + secret)
as calculated ISN for return
and sends to A, discards all
receives packet <---- state.
as normal, and
sends third packet ---> receives packet, recalculates
ISN from 1st step. If it
matches the ACK in the packet
then this is a valid connection.
The nice thing about this is that no changes have to occur on the
sending side. This solution will work with current IP stacks, but
will automatically reject bogus connections, and has no silly
timeout on valid connections.
This scheme does have implications with firewalls that base all
decisions on the first packet, such as packet filtering firewalls, but
then again, I don't consider them real firewalls.
I'm going to implement this, using boring old md5, and give it a try,
but I was wondering if there are any thoughts about this as a solution?
Any obvious holes I missed.
Rex di Bona.