Solved Help with STO

Hi,

Could someone please explain me what this rule does exactly?
Code:
WebSTO  ="(max  4096, source-track rule, max-src-conn  64, max-src-nodes 512, max-src-conn-rate 500/100, overload <BLOCKTEMP> flush global)"

I understand that It help preventing DDOS attack but not too sure I understand it all.
My understanding:
max, set total of connection nginx daemon can handle
max-src-conn-rate block if it received more than 500 connection in 100 seconds
overload, put block connection in table BLOCKTEMP
 
On its own, that line is just a macro (not a rule), and does nothing. See "MACROS" in pf.conf(5). The options are described under "STATEFUL TRACKING OPTIONS". It only does something if included in a rule, for example pass in proto tcp from any to any port www keep state $WebSTO.

It isn't really a DDoS thing as such, just a resource limits thing. It limits total connections, connections per source IP, and connection rate per source IP. It wouldn't really help solve the fundamental problems with a DDoS (unless the individual hosts involved in the DDoS reliably exceeded the max-src-* limits), just cap the number of active connections handled by the daemon(s) behind the port(s) it is attached to. A sophisticated attacker with a suitably large number of zombies at their command could easily DDoS a web server protected by that (I'm not going to explain how, as I'd prefer not to educate people who might engage in a DDoS). The operating system would get some protection from it, but the attacked services would still suffer degradation or outage.
 
Sorry, I forgot to add this code in original post
Code:
### $ExtIf inbound
pass in log on $ExtIf inet proto tcp  from !($ExtIf)      to 10.10.10.100 port https $TcpState $WebSTO
pass in log on $ExtIf inet proto tcp  from !($ExtIf)      to 10.10.10.100 port www   $TcpState $WebSTO

So if I am understaing, the above code is more to protect FreeBSD than the web server itself.
Thank you for clarifying
 
Sorry, I forgot to add this code in original post
Code:
### $ExtIf inbound
pass in log on $ExtIf inet proto tcp  from !($ExtIf)      to 10.10.10.100 port https $TcpState $WebSTO
pass in log on $ExtIf inet proto tcp  from !($ExtIf)      to 10.10.10.100 port www   $TcpState $WebSTO

So if I am understaing, the above code is more to protect FreeBSD than the web server itself.
Thank you for clarifying

Yes, that's pretty much it, assuming that the server can actually cope with sustained operation at the limits. It very much depends on just what is available behind your URLs. A small server which only serves static files could probably cope fine with 4096 simultaneous sessions, but if you have complex CGI/PHP/Perl/Python/Java/etc then 4096 sessions would possibly require a fairly huge server to sustain without problems.

Those options may mitigate the impact of some DDoS attacks, but they certainly won't cover all possible cases / attackers. If the limits are low enough for your specific combination of server hardware, bandwidth, and web content, they should at least prevent any attacker from exhausting your memory or otherwise causing the entire OS to grind to a painful halt. Preventing attackers from bringing the entire system to its knees is the objective with those options, as you can at least hopefully still login and administer the system while under attack.

It's not really possible to give good specific advice on what you should set those limits to. Possibly approximately 2x, 3x, or 4x normal expected peak activity (e.g. allowing for all normal usage plus an abnormal surge of non-abusive traffic if you get hit by the "Slashdot effect"), if your system can cope with that level of load. For what it's worth, 4096 is a fairly high limit (or it's certainly not low/light usage), and may need some significant systems engineering to reliably handle that level of activity).
 
Hi Murph
Server is Dell R610 Server 2 x E5620 2.4GHz Xeon Quad Core, 24GB Ram, raidz2
I have 1 Mysql jail, 1 Mail jail, 1 reverse proxy jail and curently 10 webserver jails (1domain=1jail)
Each webjail run its own nginx and php deamon..

What do you thing ? is 4096 too hight?
 
What do you thing ? is 4096 too hight?

Maybe, maybe not. It really all depends on what those PHP daemons are doing (assuming they are the only non-static content being served), and on what the normal peak load is. If normal peak load (with whatever padding you choose) is not 4096 HTTP + 4096 HTTPS, then it may well be too high. I consider best practice to set protective limits to some small multiple of normal expected peak load (i.e. 2x, 3x, 4x, maybe even 10x for lightly loaded services, etc), so that it blocks abusive load spikes but has a very low chance of getting in the way of legitimate traffic (including legitimate spikes).

A nice modern 8 core box like that should certainly be able to handle a decent web workload. You need to ask yourself the question of whether the server can really handle 8192 instances of the heaviest PHP scripts on the system. Only you can really answer that. If the HTTP service is just simple 301 redirects over to HTTPS, then you can more or less drop those from your reckoning and ask yourself if it can handle 4096 instances of the heaviest scripts (and their database queries).

Of course, if you set it too low, an attacker does not need so many zombies to soak up the limit and cause legitimate connections to be blocked. There is an element of damned if you do, damned if you don't to this (i.e. both small and large limits have potential negatives)

If you want a limit that is shared between HTTP and HTTPS (and all other rules with max-src-* limits), use source-track global.

Food for thought: For 8192 connections, your server has 1024 connections per core and only 3MB RAM per connection. The worst case attack for you with that config is 8192 instances of the heaviest (CPU + memory) requests (and the attack failing to be dynamically blocked by max-src-*).
 
Murph
Thank you very much to have taken the time to write such good explanation for me:)
Its is really appreciated.
I actually never tough of how much HTTP or HTTPS traffic go trough the firewall. I always check traffic for individual sites.
I know that I could look at traffic from google webmaster tools abd add the number but is there a native way of checking traffic in PF?
 
Murph
Thank you very much to have taken the time to write such good explanation for me:)
Its is really appreciated.
I actually never tough of how much HTTP or HTTPS traffic go trough the firewall. I always check traffic for individual sites.
I know that I could look at traffic from google webmaster tools abd add the number but is there a native way of checking traffic in PF?

No problem, you're welcome. :)

pfctl -s states, pfctl -v -s rules, and pfctl -s Sources will let you inspect PF and its various counters. Experiment with 0, 1, or 2 -v parameters for increasing levels of detail. I don't know the specifics, but I'd be surprised if there isn't a SNMP MIB interface for PF somewhere; that seems like something someone would probably have implemented (maybe check pfSense's docs?).

FreeBSD doesn't have pflow(4), but you can send the TCP SYN establishing each connection out to pflog(4).

I still use Apache myself, so not sure about nginx, but I guess it should have the equivalent of mod_status, to let you inspect/query status, request rates, etc.

All of the above are quite feasible to feed into MRTG, Munin, Nagios, etc, as you see fit (and if you are willing to do the necessary scripting, etc).
 
Back
Top