From owner-freebsd-net@FreeBSD.ORG Thu Jan 22 11:26:33 2004 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0540216A4CF for ; Thu, 22 Jan 2004 11:26:33 -0800 (PST) Received: from mailtoaster1.pipeline.ch (mailtoaster1.pipeline.ch [62.48.0.70]) by mx1.FreeBSD.org (Postfix) with ESMTP id 313A843D2D for ; Thu, 22 Jan 2004 11:26:26 -0800 (PST) (envelope-from andre@freebsd.org) Received: (qmail 67695 invoked from network); 22 Jan 2004 19:26:25 -0000 Received: from unknown (HELO freebsd.org) ([62.48.0.53]) (envelope-sender ) by mailtoaster1.pipeline.ch (qmail-ldap-1.03) with SMTP for ; 22 Jan 2004 19:26:25 -0000 Message-ID: <401023E0.9D6A5952@freebsd.org> Date: Thu, 22 Jan 2004 20:26:24 +0100 From: Andre Oppermann X-Mailer: Mozilla 4.76 [en] (Windows NT 5.0; U) X-Accept-Language: en MIME-Version: 1.0 To: Mike Silbersack References: <4010165F.2080507@freebsd.org> <20040122130156.N7234@odysseus.silby.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit cc: freebsd-net@freebsd.org Subject: Re: Rate limiting icmp host unreachable replies? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Jan 2004 19:26:33 -0000 Mike Silbersack wrote: > > On Thu, 22 Jan 2004, Andre Oppermann wrote: > > > I'm having a FreeBSD router here that has many networks connected to it which > > are only sparsely populated. These days I get network scans (deliberate and > > worms scanning for new targets) every second or so going through every IP in > > my netblocks. The router is faithfully generating ICMP host unreachable replies > > to all these scans for each and every unreachable destination IP. > > > > I wonder whether it is justifyable to rate limit the icmp host unreachable replies > > just like the other icmp stuff to 200 (default) per second? Should help alot if > > the next SQL slammer is coming around and you get thousands of packets per second > > for unreachable destinations. > > > > Comments and opinions welcome! > > I like this a lot, and I would be willing to write up an implementation! > > > PS: I've already coded it and it works nicely. > > > > -- > > Andre > > Doh! Well, I guess we'll just have to go with your implementation then. > :) Here it is (pretty trivial actually): Index: icmp_var.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/icmp_var.h,v retrieving revision 1.21 diff -u -p -r1.21 icmp_var.h --- icmp_var.h 19 Mar 2002 21:25:46 -0000 1.21 +++ icmp_var.h 22 Jan 2004 19:23:23 -0000 @@ -81,11 +81,12 @@ SYSCTL_DECL(_net_inet_icmp); extern int badport_bandlim(int); #define BANDLIM_UNLIMITED -1 #define BANDLIM_ICMP_UNREACH 0 -#define BANDLIM_ICMP_ECHO 1 -#define BANDLIM_ICMP_TSTAMP 2 -#define BANDLIM_RST_CLOSEDPORT 3 /* No connection, and no listeners */ -#define BANDLIM_RST_OPENPORT 4 /* No connection, listener */ -#define BANDLIM_MAX 4 +#define BANDLIM_ICMP_UNREACH_HOST 1 +#define BANDLIM_ICMP_ECHO 2 +#define BANDLIM_ICMP_TSTAMP 3 +#define BANDLIM_RST_CLOSEDPORT 4 /* No connection, and no listeners */ +#define BANDLIM_RST_OPENPORT 5 /* No connection, listener */ +#define BANDLIM_MAX 5 #endif #endif Index: ip_icmp.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_icmp.c,v retrieving revision 1.87 diff -u -p -r1.87 ip_icmp.c --- ip_icmp.c 8 Jan 2004 17:40:06 -0000 1.87 +++ ip_icmp.c 22 Jan 2004 19:23:23 -0000 /* * ICMP broadcast echo sysctl */ @@ -169,6 +173,18 @@ icmp_error(n, type, code, dest, destifp) if (n->m_flags & (M_BCAST|M_MCAST)) goto freeit; /* + * Limit sending of ICMP host unreachable messages. + * If we are acting as a router and someone is doing a sweep + * scan (eg. nmap and/or numerous windows worms) for destinations + * we are the gateway for but are not reachable (ie. a /24 on a + * interface and only a couple of hosts on the ethernet) we would + * generate a storm of ICMP host unreachable messages. + */ + if (type == ICMP_UNREACH && code == ICMP_UNREACH_HOST) { + if (badport_bandlim(BANDLIM_ICMP_UNREACH_HOST) < 0) + goto freeit; + } + /* * First, formulate icmp message */ m = m_gethdr(M_DONTWAIT, MT_HEADER); @@ -859,7 +901,8 @@ badport_bandlim(int which) struct timeval lasttime; int curpps;; } rates[BANDLIM_MAX+1] = { - { "icmp unreach response" }, + { "icmp unreach port response" }, + { "icmp unreach host response" }, { "icmp ping response" }, { "icmp tstamp response" }, { "closed port RST response" },