I've set up a max-src-conn-rate rule on my gateway router to mitigate brute-force ssh attacks. This router protects a /28 subnet, 25.108.82.80/28. The relevant rules: # pfctl -sr | grep attack block drop in log quick proto tcp from <sshd_attackers> to any pass in log proto tcp from any to any port = ssh keep state (source-track rule, max-src-conn-rate 3/30, overload <sshd_attackers> flush global, src.track 30) # What the three columns of output in the below tcpdump output are: timestamp, rule action, and target host. As you can tell from the tcpdump command, the sending host is the same in all cases, 208.53.147.204 reading from file /var/log/pflog, link-type PFLOG (OpenBSD pflog file) 12:09:45.849594 pass 25.103.82.80 12:09:45.850279 pass 25.103.82.82 12:09:45.850827 pass 25.103.82.83 12:09:45.851310 pass 25.103.82.84 12:09:45.852003 pass 25.103.82.85 12:09:45.852496 pass 25.103.82.86 12:09:45.853007 pass 25.103.82.87 12:09:45.866580 pass 25.103.82.88 12:09:45.867345 pass 25.103.82.89 12:09:45.868339 pass 25.103.82.92 12:09:45.902389 pass 25.103.82.95 12:25:52.632295 pass 25.103.82.80 12:25:52.632973 pass 25.103.82.82 12:25:52.648804 pass 25.103.82.83 12:25:52.684792 pass 25.103.82.84 12:25:52.687989 pass 25.103.82.85 12:25:52.688652 pass 25.103.82.86 12:25:52.690882 pass 25.103.82.87 12:25:52.691371 pass 25.103.82.88 12:25:52.692290 pass 25.103.82.89 12:25:52.695340 pass 25.103.82.92 12:25:52.698864 pass 25.103.82.95 13:08:36.949178 pass 25.103.82.87 13:08:38.864585 pass 25.103.82.87 13:08:40.452215 pass 25.103.82.87 13:08:42.038388 pass 25.103.82.87 13:08:46.923469 block 25.103.82.88 13:08:49.922116 block 25.103.82.88 13:08:50.212040 block 25.103.82.87 13:08:51.099435 block 25.103.82.87 # It seems to me like this host should have been blocked back at 12:09:45, not 13:08:46. Am I misunderstanding the rule? --david [demime 1.01d removed an attachment of type application/pgp-signature which had a name of signature.asc]
Nobody? Sad, it's still doing it. had a name of signature.asc] [demime 1.01d removed an attachment of type application/pgp-signature which had a name of signature.asc]
David, Was the offending client completing the 3-way handshake everytime it connected? For stateful TCP connections, limits on established connections (connec- tions which have completed the TCP 3-way handshake) can also be enforced per source IP. The max-src-conn-rate <number>/<seconds> limit the rate of new connections over a time interval. The connection rate is an approximation calculated as a moving average. You may also want to use synproxy for ssh and take a look at max-src-states. I have examples here: http://calomel.org/pf_config.html -- Calomel @ http://calomel.org
I didn't respond to this until now, because I wanted to do some research first. As the hosts that are being blocked by this aren't hosts I control, I needed to set up some access on the outside. So it looks like i can run 'nmap -sS -p22 25.103.82.80/28' until doomsday and it will always show as a passed connection. But when i start telnetting to port 22 on machines in this subnet, the fourth 'telnet' connection is blocked, no matter which host I hit previously. So I think that you are correct in that the attackers are not initially completing the 3-way handshake, and are thus not tripping the filter. I'll look in to max-src-states, but I think now that I've shown that the actual "attack" (if that's what they are) attempts are blocked properly, I'm not terribly concerned if they can scan the subnet. Thanks, had a name of signature.asc] [demime 1.01d removed an attachment of type application/pgp-signature which had a name of signature.asc]
David, I would take a look at adding synproxy to your rules before worrying about max-src-states. Synproxy will allow max-src-conn-rate to work more reliably. By default, pf(4) passes packets that are part of a tcp(4) handshake be- tween the endpoints. The synproxy state option can be used to cause pf(4) itself to complete the handshake with the active endpoint, perform a handshake with the passive endpoint, and then forward packets between the endpoints. No packets are sent to the passive endpoint before the active endpoint has completed the handshake, hence so-called SYN floods with spoofed source addresses will not reach the passive endpoint, as the sender can't complete the handshake. The proxy is transparent to both endpoints, they each see a single connection from/to the other endpoint. pf(4) chooses random initial se- quence numbers for both handshakes. Once the handshakes are completed, the sequence number modulators (see previous section) are used to translate further packets of the connection. Synproxy state includes modulate state. (pf.conf man page) -- Calomel @ http://calomel.org
I'm not a pf newbie by any means, but I'm not really qualified to answer questions about it either. That said, I don't usually use an '=' sign in my pf rules, and the pf faq doesn't list that as one of the accepted operators for the port range (http://www.openbsd.org/faq/pf/filter.html). If the rule wasn't being parsed correctly, it would cause the behavior you're seeing. Try, block in log quick proto tcp port ssh keep state \ (source-track rule, max-src-conn-rate 3 / 30 overload <sshd_attackers>, src.track 30) Note that I wouldn't use a flush global directive for a rule like this, because it can lead to a neat DoS where somebody can spoof one of your own IP addresses and shut down any ssh sessions you have active. Here's a working sample from my own currently active pf file: pass in on $ext proto tcp to <server6> port smtp keep state \ (max-src-conn 15 max-src-conn-rate 10 / 45 overload <smtp-overload>) \ queue 6smtp (FYI, the smtp-overload table moves traffic to a queue that simply throttles the connections a little.) - R.
I don't have an = sign in my rule, either, i have it in pf.conf as:
pass in log proto tcp from any to any port ssh \
keep state (max-src-conn-rate 3/30, \
overload <sshd_attackers> flush global)
I want to pass ssh traffic by default, so a block rule won't be
Mine's pretty similar, if a bit more verbose. And I don't use
max-src-conn or queueing.
Huh. What's your output from pfctl -s rules -v ? Also, I should parrot some of the earlier conversations that have been on this list on this subject (limiting attempts at ssh attacks). Doing this with a max-src-conn-rate rule probably isn't what you really want to do anyway; there are some good log file analyzers which would be better suited to this (see http://www.ossec.net/, http://www.ossec.net/en/attacking-loganalysis.html, and http://marc.info/?l=openbsd-misc&m=118660109014882&w=2); strong ssh passwords are the best defense against dictionary attacks; etc. At best, all you're really doing is keeping your authlog a bit leaner, and maybe compiling a list of evildoers. - R. - R.
Understood that this is not going to be a be-all end-all from a security perspective, and that it isn't going to save me from being stupid and having weak passwords. It's still a useful mitigating control. That said, my original question wasn't about whether or not this is a good idea, it's about why what PF claims to do and what PF does seem to be different. --david
I tried various combinations on my test machine and noticed the following pattern. Setting the max-src-conn to be twice the max-src-conn-rate seems to work better at stopping brute-force SSH attempts. Probably there is no rational basis for this observation and there must be some other explanation. I did try a few combinations and it seemed to have had a positive impact in getting the IP address to the sshd_attackers table at the right max-src-conn-rate. So I am wondering if pass in log proto tcp from any to any port ssh keep state (max-src-conn 6 max-src-conn-rate 3/30, overload <sshd_attackers> flush global) would be an appropriate thing for you to try. Anyways, hope this helps in some way. -- Vijay Sankar, M.Eng., P.Eng. President & CEO ForeTell Technologies Limited 59 Flamingo Avenue, Winnipeg, MB Canada R3J 0X6 Phone: +1 204 885 9535, E-Mail: vsankar@foretell.ca
hell no! if the rule can't be parsed correctly, pfctl throws an error no. src-conn-rate works w/ established tcp conns, AFTER the 3whs, thus making spoofing unfeasible. that info, of course, is in the manpage... very loud and clear. why don't you check there before spreading fud on the list? this doesn't only comply to you, but is completely beyond me. why dowe invest lots of time and nerves and whatnot in manpages when people do not read them, and instead guess a bit and then spread shit because the guess was of course wrong? read the damn manpages! -- Henning Brauer, hb@bsws.de, henning@openbsd.org BS Web Services, http://bsws.de Full-Service ISP - Secure Hosting, Mail and DNS Services Dedicated Servers, Rootservers, Application Hosting - Hamburg & Amsterdam
I was quoting that from memory, specifically from Joachim Schipper's comment on August 9th: "Or maybe not - 'flush' enables an attacker to not only prevent you connecting, but actually to log you out as well." (http://marc.info/?l=openbsd-misc&m=118665539219389&w=2) People read the man pages. I would sooner read, re-read, and then study the man pages, then perform background research, experiment, and then write sample code, before asking a question on this list. The guy's question had languished for 2 days. I didn't bother to go back through the 2,079 lines of pf.conf manpage to get the correct answer; my bad. I had five minutes today in which I wasn't catching shit from someone else, so I thought I'd give a best guess and catch some shit here instead. - R.
