From owner-freebsd-pf@FreeBSD.ORG Sun Dec 6 13:18:25 2009 Return-Path: Delivered-To: freebsd-pf@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 010A01065694 for ; Sun, 6 Dec 2009 13:18:25 +0000 (UTC) (envelope-from ohauer@gmx.de) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by mx1.freebsd.org (Postfix) with SMTP id 738E68FC19 for ; Sun, 6 Dec 2009 13:18:24 +0000 (UTC) Received: (qmail invoked by alias); 06 Dec 2009 13:18:22 -0000 Received: from u18-124.dsl.vianetworks.de (EHLO [172.20.1.100]) [194.231.39.124] by mail.gmx.net (mp023) with SMTP; 06 Dec 2009 14:18:22 +0100 X-Authenticated: #1956535 X-Provags-ID: V01U2FsdGVkX1/XK4oVFQDXlyQ9lrysEO1G4px1suHKEGDkZz3+hi 10gKikYRRALEcI Message-ID: <4B1BAF1D.9070105@gmx.de> Date: Sun, 06 Dec 2009 14:18:21 +0100 From: olli hauer User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: Nico De Dobbeleer References: <6783768.102251260022192330.JavaMail.root@zimbra-store> In-Reply-To: <6783768.102251260022192330.JavaMail.root@zimbra-store> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Y-GMX-Trusted: 0 X-FuHaFi: 0.42 Cc: freebsd-pf@freebsd.org Subject: Re: Limit connections doens't work X-BeenThere: freebsd-pf@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Technical discussion and general questions about packet filter \(pf\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 06 Dec 2009 13:18:25 -0000 Nico De Dobbeleer wrote: > Hello, > > As most of the public ip's my servers are constantly under bruteforce attack see example: > > Dec 5 13:56:36 hosting sshd[18621]: Failed password for invalid user tim from 173.10.126.226 port 47871 ssh2 > Dec 5 13:56:37 hosting sshd[18623]: Invalid user support123 from 173.10.126.226 > Dec 5 13:56:39 hosting sshd[18623]: Failed password for invalid user support123 from 173.10.126.226 port 48289 ssh2 ... > > Now I want to limit the connection over ssh to a specific ipaddress and I added the rules below for that. > ------------------------------------------------------------------------------------------------------------------ > #Tables > table persist file "/etc/pf.abusive_ips.block.list" > table persist > > # Rules > > block quick from > block quick from > > > # Limit connections per IP > > pass in quick on { $ext_if, $int_if, $mng_if } inet proto tcp from any to xx.xx.xx.xx port ssh flags S/SA keep state > (max-src-conn 10, max-src-conn-rate 3/15, overload flush) > pass in quick on { $ext_if, $int_if, $mng_if } inet proto tcp from any to xx.xx.xx.xx port ssh flags S/SA keep state > (max-src-conn 10, max-src-conn-rate 3/15, overload flush) > pass in quick on { $ext_if, $int_if, $mng_if } inet proto tcp from any to xx.xx.xx.xx port ssh flags S/SA keep state > (max-src-conn 10, max-src-conn-rate 3/15, overload flush) > -------------------------------------------------------------------------------------------------------------------- > > The only problem is that it doesn't work. These rules don't write the abusive ip in the abusif list file or in the table. > > Anyone an idea why it doesn't overload the ip's when the connections per ip are more then 10 of more then 3/15? - which FreeBSD version is this 6.x 7.x/8.x? - avoid the quick keyword in the rules with overload - pf can preload IP's from file specified in "table ... file "/filename" but does not write IP's into the file. I use the script below to do this on a OpenBSD machine. - rewrite your rule and avoid the any keyword pass in on { $ext_if, $int_if, $mng_if } inet proto tcp \ from ! to xx.xx.xx.xx port ssh flags S/SA keep state \ (max-src-conn 10, max-src-conn-rate 3/15, overload flush) hint: - look for the additional keyword global (flush global) - If the IP in your rule is your base IP on $ext_if write it with as $ext_if:0 this script writes IP's from the bf_* tables into a file so you can preload them next time pf rules are installed or the machine reboots. additional it can send you a mail with IP's added to the table and if GeoIP is installed you get the GeoIP info. With a little modification of the script/rules It will work for you #!/bin/sh ################################################################## # $Source: RCS/pftable_to_file.sh,v $ # OS: OpenBSD # # olli hauer # ################################################################## # sample rule for pf # --------------------------- # block in log quick proto { tcp, udp } from \ # to any port ssh label BRUTFORCE-SSH # table for overload connections # # pass in log on $if_ext inet proto tcp from ! to $if_ext \ # port = ssh flags S/SA keep state \ # (source-track rule, max-src-conn 10, \ # max-src-conn-rate 3/90, overload \ # flush global, if-bound, src.track 90) \ # label "SSH" umask 077 PF_TABLES="bf_mail bf_ssh bf_web" OUTDIR="/etc/pf" GEOIP=/usr/local/bin/geoiplookup # hold the output from pfctl -tx -Ts TMP_PFCTL=`mktemp /tmp/.tmp_pf_table.XXXXXXXXXX` || exit 1 # hold the diff between old and new TMP_DIFF=`mktemp /tmp/.tmp_diff.XXXXXXXXXX` || exit 1 trap 'rm -f ${TMP_PFCTL} ${TMP_DIFF}' 0 1 2 3 13 15 [ -d ${OUTDIR} ] || mkdir -p ${OUTDIR} for TABLE in ${PF_TABLES}; do # make sure the output file exists [ -f ${OUTDIR}/${TABLE} ] || /usr/bin/touch ${OUTDIR}/${TABLE} # extraxt IP's from table /sbin/pfctl -t${TABLE} -Ts | awk '{print $1}' > ${TMP_PFCTL} # we need only the '+diff' to grep for this later /usr/bin/diff -bu ${OUTDIR}/${TABLE} ${TMP_PFCTL} > ${TMP_DIFF} RETVAL=$? case ${RETVAL} in 0) continue ;; 1) # save the old file if [ -f ${OUTDIR}/${TABLE} ]; then cp ${OUTDIR}/${TABLE} ${OUTDIR}/${TABLE}.old fi # mail message header date echo "change in table: ${TABLE}" echo "------------------------------------" # lookup the IP in the GeoIP database if [ -x ${GEOIP} ]; then for IP in `egrep "^\+[0-9]" ${TMP_DIFF} | tr -d \+`; do # print the IP wo. linefeed printf "%-20s # " ${IP} # strip netmask if we add NET by hand IPT=`echo ${IP} | sed 's/\/[[:digit:]]*//g'` # make a short GeoIP output ${GEOIP} ${IPT} | sed 's/ Country Edition//g' done else egrep "^\+[0-9]" ${TMP_DIFF} | tr -d \+ fi mv ${TMP_PFCTL} ${OUTDIR}/${TABLE} ;; *) echo "error in diff" ;; esac done small snippet from my bf_ssh file (places with IP rangees I don't visit in near time) snippet from file:/etc/pf/bf_ssh 12.0.0.0/8 21.0.0.0/8 24.0.0.0/8 25.0.0.0/8 26.0.0.0/8 28.0.0.0/8 29.0.0.0/8 30.0.0.0/8 32.0.0.0/8 33.0.0.0/8 38.0.0.0/8 58.0.0.0/8 59.0.0.0/8 60.0.0.0/8 61.0.0.0/8 62.0.0.0/8 63.0.0.0/8 64.0.0.0/8 ... 216.0.0.0/8 217.0.0.0/8 218.0.0.0/8 219.0.0.0/8 220.0.0.0/8 221.0.0.0/8 222.0.0.0/8