On Wed, Feb 07, 2007 at 11:56:05AM +0800, frank hu wrote:

> What is the solution?

Make it a two-step process. Use synproxy for incoming connections on the
external interface, with a larger state limit and adaptive timeouts, like

  set limit states 10000
  set timeout interval 1

  pass in on $ext_if inet proto tcp from any to any port 80
    synproxy state (max 5000, tcp.first 5,
    adaptive.start 10, adaptive.end 5000)

This limits the number of states (including synproxy states that haven't
completed the handshake) to 5000. While there are less than 10 states,
a client has 5 seconds to complete the handshake, before the state is
removed. The more states there are, the more aggressive this timeout
becomes (with 2500 states, it becomes 2.5s, at 4900 states basically 1s).

Now the legitimate client will race against the DoS attack for a free
spot in the state table. The more aggressive the timeouts, the more
spots get freed per second. The larger the limit (try increasing 'max
1000'), the more spots are free at any time. This is not a guarantee
that the legitimate client will promptly get a state at any time, it's
statistics. It depends on how many connection attempts per second the
DoS delivers vs. the frequency of legitimate connection attempts.

Now that you have dealt with spoofed SYNs on the external interface, you
can use connection tracking ('max-src-states', 'max-src-conn-rate') for
outgoing connections on the internal interface (towards the real
server), and they won't include spoofed connections.

Daniel

Reply via email to