diff -cr linux-pure/Documentation/Configure.help linux-patched/Documentation/Configure.help *** linux-pure/Documentation/Configure.help Thu Dec 11 02:21:47 1997 --- linux-patched/Documentation/Configure.help Wed Jan 14 18:54:56 1998 *************** *** 4111,4116 **** --- 4111,4134 ---- This is the driver for the Sun ESP SCSI host adapter. The ESP chipset is present in most SPARC-based computers. + TCP connection auditing (aka tcpd) + CONFIG_TCP_AUDIT + Audits all connection attempts, whether they were accepted or not, and if + they were accepted, some extra information about what accepted it. + + Strobe flood protection + CONFIG_STROBE_PROTECT + Strobing is what potential crackers will do to see, in a sense, + what 'doors' [ports] are open on your computer to the network. With this + option, we are able to judge if we are being strobed, and if so, we + make ourselves look like we have no ports open to the strober to + exploit. We do this by counting the amount of failed connection + requests we receive each second from a given IP. If a limit is reached + a message is logged and the IP gets nothing other than RST's on + each successive connection request. Once the requests stop coming, + the IP is ignored for another given amount of time, after which, things + will be set back to normal. Author: Jesse Off [joff@iastate.edu] + Sparc /dev/openprom compatibility driver CONFIG_SUN_OPENPROMIO This driver provides user programs with an interface to the Sparc diff -cr linux-pure/arch/i386/defconfig linux-patched/arch/i386/defconfig *** linux-pure/arch/i386/defconfig Mon Sep 22 20:44:01 1997 --- linux-patched/arch/i386/defconfig Wed Jan 14 18:54:56 1998 *************** *** 72,77 **** --- 72,79 ---- # CONFIG_IP_ACCT is not set # CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set + CONFIG_TCP_AUDIT=y + CONFIG_STROBE_PROTECT=y # # (it is safe to leave these untouched) diff -cr linux-pure/net/Config.in linux-patched/net/Config.in *** linux-pure/net/Config.in Tue Aug 12 18:30:22 1997 --- linux-patched/net/Config.in Wed Jan 14 18:54:56 1998 *************** *** 24,27 **** --- 24,39 ---- if [ "$CONFIG_NETLINK" = "y" ]; then bool 'Routing messages' CONFIG_RTNETLINK fi + bool 'Strobe flood protection' CONFIG_STROBE_PROTECT + + if [ "$CONFIG_STROBE_PROTECT" = "y" ]; then + int 'post-strobe ignore period (secs)' IGNORE_TIME 10 + fi + + if [ "$CONFIG_STROBE_PROTECT" = "y" ]; then + int 'refused connections/sec considered a strobe' MAX_SYN_SEC 3 + fi + + + bool 'TCP connection auditing (aka tcpd)' CONFIG_TCP_AUDIT endmenu diff -cr linux-pure/net/ipv4/af_inet.c linux-patched/net/ipv4/af_inet.c *** linux-pure/net/ipv4/af_inet.c Fri Aug 15 19:23:23 1997 --- linux-patched/net/ipv4/af_inet.c Sun Jan 18 01:59:08 1998 *************** *** 778,783 **** --- 778,788 ---- sk2 = sk1->prot->accept(sk1,flags); if (sk2 == NULL) return sock_error(sk1); + #ifdef CONFIG_TCP_AUDIT + else + printk ( KERN_INFO "TCP connection accepted: ip=%d.%d.%d.%d port=%d uid=%d process=%s[%d]\n", + NIPQUAD(sk2->daddr), sk2->num, current->uid, current->comm, current->pid ); + #endif } newsock->data = (void *)sk2; sk2->sleep = newsock->wait; diff -cr linux-pure/net/ipv4/tcp_input.c linux-patched/net/ipv4/tcp_input.c *** linux-pure/net/ipv4/tcp_input.c Fri Oct 31 19:34:12 1997 --- linux-patched/net/ipv4/tcp_input.c Wed Jan 14 18:54:56 1998 *************** *** 43,48 **** --- 43,63 ---- #include #include + + #ifdef CONFIG_STROBE_PROTECT + + #define MAX_FLOOD 64 /* a good round number */ + + + static struct flood { + u32 ip; + unsigned int count; + unsigned long timestamp; + } flood_hash[MAX_FLOOD]; + unsigned int dummy_temp, dummy_temp2; + #endif + + /* * Policy code extracted so it's now separate */ *************** *** 2311,2316 **** --- 2326,2386 ---- else #endif sk = __tcp_v4_lookup(th, saddr, th->source, daddr, th->dest, dev); + if ((th->syn && !th->ack && !th->rst && ip_chk_addr(daddr)==IS_MYADDR) && + !(sk && sk->state == TCP_SYN_RECV)) { + #ifdef CONFIG_STROBE_PROTECT + dummy_temp2 = dummy_temp = saddr % MAX_FLOOD; + /* Ok, this is probably WAY overdue for something as trivial as strobing, and it is still not + * perfect, as forged SYN packets can be used deny service for the forged IP [although for not very long] + * and it is still possible to get a modified, spoofing, strober to fill up the flood hash. But even + * then, it will have to refill up the flood hash every second or so, which means the strobe could take a + * LONG time to complete, depending on what MAX_FLOOD is set as. Generally speaking MAX_FLOOD is link + * dependent and is the expected maximum connection requests per second _from different sources_ it should be + * prepared for. You raise this, you lower chances of anyone getting a meaningful strobe [but also waste memory + * for all those flood_structs]. If anyone rewrites a strober to do the spoofing and hash filling mentioned + * above, you are even more stupid than me for writing this patch. I still don't know why I did this. I + * think I just like playing with hashes :) [Thanks to NivFreak for pointing out that we should not deny + * packets from ourself!] + * Jesse Off [joff@iastate.edu] + */ + cli(); /* Don't know much about race conditions, cli()/sti() actually needed? */ + restart_fhash: + if ( (flood_hash[dummy_temp].timestamp < xtime.tv_sec) ) { /* simplest case: slot useable */ + if (!sk ) { + flood_hash[dummy_temp].ip = saddr; + flood_hash[dummy_temp].count = 1; + flood_hash[dummy_temp].timestamp = xtime.tv_sec; + } + } else { /* slot in use */ + if ( flood_hash[dummy_temp].ip != saddr ) { /* handle collision */ + dummy_temp = (dummy_temp + 1) % MAX_FLOOD; + if (dummy_temp != dummy_temp2) goto restart_fhash; + printk(KERN_CRIT "Flood hash full, not good...\n"); } + else { /* slot in use by this current ip, increment or deny */ + if ( flood_hash[dummy_temp].count >= MAX_SYN_SEC && ip_chk_addr(saddr) != IS_MYADDR ) { + if (flood_hash[dummy_temp].count == MAX_SYN_SEC) { + printk(KERN_CRIT "Strobe from %d.%d.%d.%d, rejecting until they stop for %d seconds\n", + NIPQUAD(saddr), IGNORE_TIME); + flood_hash[dummy_temp].count++; /* Takes care of logfile runaway */ + } + flood_hash[dummy_temp].timestamp = xtime.tv_sec + IGNORE_TIME; + goto no_tcp_socket; /* DENY */ + sti(); + } + if (!sk) flood_hash[dummy_temp].count++; + } + } + sti(); + #endif + #ifdef CONFIG_TCP_AUDIT + if (!sk) printk( KERN_INFO "TCP connection rejected from %d.%d.%d.%d, port %d\n", + NIPQUAD(saddr), ntohs(th->dest) ); + #endif + + + + + } if (!sk) goto no_tcp_socket; skb->sk = sk; *************** *** 2333,2338 **** --- 2403,2409 ---- return(0); } } + /* * If this socket has got a reset it's to all intents and purposes