diff -urP linux/Documentation/Configure.help linux/Documentation/Configure.help --- linux/Documentation/Configure.help Tue Jan 4 13:12:10 2000 +++ linux/Documentation/Configure.help Thu Feb 10 17:29:48 2000 @@ -12039,7 +12039,40 @@ If you do not have any Quicknet telephony cards, you can safely ignore this option. - + +Deny packets with SYN and FIN set. +CONFIG_TCPIP_STACK_SYNFIN + This will DENY all incoming packets with the SYN & FIN flags set. Much + like the option TCP_DROP_SYNFIN in the FreeBSD kernel config. This + breaks RFC 1644 but say Y if security is more important. + +Drop packets without SYN, FIN or RST +CONFIG_TCPIP_STACK_BOGUS + All incoming TCP packets must have either SYN, FIN or RST set, or the + packet will be dropped. Say Y if security is more important. + +Deny packets looking for ACK values +CONFIG_TCPIP_STACK_ACK + Typlicly OS detection tools will send packets to an open port looking for + the ACK to be the same as the ISN, or ISN++. This will deny incoming TCP + packets with FIN, PSH and URG set, thus blocking packets with SYN, + FIN, URG and PSH also. Packets of these structure are use in OS detection + utilites such as nmap (test 3 & 7). Say Y if security is more important. + +Block outgoing ICMP Port Unreachable Messages +CONFIG_TCPIP_STACK_ICMP_PU + Instead of limiting the rate that the kernel sends destination port + unreachable messages, totaly block them. Setting this will block all UDP + portscans, and block packets used for OS detection (nmap's PU test). This + breaks allot of RFC's, as do many of these TCPIP configurable stack + options. Say N if you plan to do this with ipchains, otherwise say Y. + +Log all packets with bad flags +CONFIG_TCPIP_STACK_LOG + This would probably be a good idea if you are interested in knowing what + is going on, on your system. Any TCP packets you set to deny above will + be logged, the logs will also include the flags used. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff -urP linux/arch/i386/config.in linux/arch/i386/config.in --- linux/arch/i386/config.in Tue Jan 4 13:12:11 2000 +++ linux/arch/i386/config.in Thu Feb 10 17:29:48 2000 @@ -207,3 +207,12 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ endmenu +mainmenu_option next_comment +comment 'TCP/IP stack options' + +bool 'Deny packets with SYN and FIN set' CONFIG_TCPIP_STACK_SYNFIN +bool 'Drop packets without SYN, FIN or RST' CONFIG_TCPIP_STACK_BOGUS +bool 'Deny packets looking for ACK values' CONFIG_TCPIP_STACK_ACK +bool 'Block outgoing ICMP Port Unreachable Messages' CONFIG_TCPIP_STACK_ICMP_PU +bool 'Log all packets with bad tcp flags' CONFIG_TCPIP_STACK_LOG +endmenu diff -urP linux/arch/i386/defconfig linux/arch/i386/defconfig --- linux/arch/i386/defconfig Wed Aug 25 20:29:46 1999 +++ linux/arch/i386/defconfig Thu Feb 10 17:29:48 2000 @@ -354,6 +354,15 @@ # CONFIG_SOUND is not set # +# TCP/IP stack +# +CONFIG_TCPIP_STACK_SYNFIN=y +CONFIG_TCPIP_STACK_BOGUS=y +CONFIG_TCPIP_STACK_ACK=y +CONFIG_TCPIP_STACK_ICMP_PU=n +CONFIG_TCPIP_STACK_LOG=y + +# # Kernel hacking # # CONFIG_MAGIC_SYSRQ is not set diff -urP linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c --- linux/net/ipv4/tcp_ipv4.c Tue Jan 4 13:12:27 2000 +++ linux/net/ipv4/tcp_ipv4.c Thu Feb 10 17:34:59 2000 @@ -1708,6 +1708,21 @@ if (len < sizeof(struct tcphdr)) goto bad_packet; +#ifdef CONFIG_TCPIP_STACK_SYNFIN + if(th->fin && th->syn) + goto tcp_bad_flag; +#endif + +#ifdef CONFIG_TCPIP_STACK_BOGUS + if(!(th->ack || th->syn || th->rst)) + goto tcp_bad_flag; +#endif + +#ifdef CONFIG_TCPIP_STACK_ACK + if(th->fin && th->psh && th->urg) + goto tcp_bad_flag; +#endif + /* Try to use the device checksum if provided. */ switch (skb->ip_summed) { case CHECKSUM_NONE: @@ -1768,6 +1783,31 @@ __skb_queue_tail(&sk->back_log, skb); return 0; + +#ifdef CONFIG_TCPIP_STACK_LOG + +tcp_bad_flag: + printk(KERN_INFO + "Packet log: badflag DENY %s PROTO=TCP %d.%d.%d.%d:%d " + "%d.%d.%d.%d:%d L=%hu:%u:%u S=0x%2.2hX I=%hu:%u:%u " + "T=%hu %c%c%c%c%c%c\n", + skb->dev->name, NIPQUAD(skb->nh.iph->saddr), ntohs(th->source), + NIPQUAD(skb->nh.iph->daddr), ntohs(th->dest), + ntohs(skb->nh.iph->tot_len), skb->len, skb->len - th->doff*4, + skb->nh.iph->tos, ntohs(skb->nh.iph->id), ntohl(th->seq), + ntohl(th->ack_seq), skb->nh.iph->ttl, + th->ack ? 'A' : '.', + th->syn ? 'S' : '.', + th->fin ? 'F' : '.', + th->rst ? 'R' : '.', + th->psh ? 'P' : '.', + th->urg ? 'U' : '.' ); + goto bad_packet; + +#else +tcp_bad_flag: + goto bad_packet; +#endif no_tcp_socket: tcp_v4_send_reset(skb); diff -urP linux/net/ipv4/udp.c linux/net/ipv4/udp.c --- linux/net/ipv4/udp.c Mon Aug 9 15:05:10 1999 +++ linux/net/ipv4/udp.c Thu Feb 10 17:29:48 2000 @@ -1131,9 +1131,12 @@ (unsigned short)csum_fold(csum_partial((char*)uh, ulen, skb->csum))) goto csum_error; #endif - udp_statistics.UdpNoPorts++; - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + udp_statistics.UdpNoPorts++; +#ifdef CONFIG_TCPIP_STACK_ICMP_PU +#else + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); +#endif /* * Hmm. We got an UDP broadcast to a port to which we * don't wanna listen. Ignore it.