From owner-freebsd-net Tue Jul 27 4:26:45 1999 Delivered-To: freebsd-net@freebsd.org Received: from des.follo.net (des.follo.net [195.204.143.216]) by hub.freebsd.org (Postfix) with ESMTP id 67A4714DF1; Tue, 27 Jul 1999 04:26:33 -0700 (PDT) (envelope-from des@des.follo.net) Received: (from des@localhost) by des.follo.net (8.9.3/8.9.3) id NAA55736; Tue, 27 Jul 1999 13:26:21 +0200 (CEST) (envelope-from des) To: net@freebsd.org Subject: TCP/IP hardening, take two Organization: Yes Interactive Visit-Us-At: http://www.yes.no/ From: Dag-Erling Smorgrav Date: 27 Jul 1999 13:26:21 +0200 Message-ID: Lines: 308 X-Mailer: Gnus v5.5/Emacs 19.34 Sender: owner-freebsd-net@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org I cleaned up the previously posted patches, tested them a little more, and added a sysctl knob for logging SYN+FIN packets (before optionally dropping them). A FreeBSD 4.0-CURRENT machine with these patches and no firewall looks like this to nmap (with tcp.drop_synfin and tcp.restrict_rst enabled): | Starting nmap V. 2.12 by Fyodor (fyodor@dhp.com, www.insecure.org/nmap/) | Interesting ports on destmp.follo.net (195.204.143.235): | (Not showing ports in state: filtered) | Port State Protocol Service | 22 open tcp ssh | | TCP Sequence Prediction: Class=random positive increments | Difficulty=38742 (Worthy challenge) | No OS matches for host (see http://www.insecure.org/cgi-bin/nmap-submit.cgi). | TCP/IP fingerprint: | TSeq(Class=RI%gcd=2%SI=1429) | TSeq(Class=RI%gcd=1%SI=1026) | TSeq(Class=RI%gcd=1%SI=9756) | T1(Resp=Y%DF=Y%W=402E%ACK=S++%Flags=AS%Ops=M) | T2(Resp=N) | T3(Resp=N) | T4(Resp=N) | T5(Resp=N) | T6(Resp=N) | T7(Resp=N) | PU(Resp=Y%DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=F%RIPCK=F%UCK=0%ULEN=134%DAT=E) | | | Nmap run completed -- 1 IP address (1 host up) scanned in 75 seconds Note: The TCP sequence prediction difficulty rating is meaningless, Successive nmap runs show ratings from approx. 5000 to approx. 40000 for the same computer with the same software. DES -- Dag-Erling Smorgrav - des@yes.no Index: etc/defaults/rc.conf =================================================================== RCS file: /home/ncvs/src/etc/defaults/rc.conf,v retrieving revision 1.23 diff -u -r1.23 rc.conf --- rc.conf 1999/07/26 10:49:33 1.23 +++ rc.conf 1999/07/27 11:18:30 @@ -48,6 +48,12 @@ tcp_extensions="NO" # Set to Yes to turn on RFC1323 extensions. log_in_vain="NO" # Disallow bad connection logging (or YES). tcp_keepalive="YES" # Kill dead TCP connections (or NO). +tcp_drop_synfin="NO" # Set to YES to drop TCP packets with SYN+FIN + # NOTE: this breaks rfc1644 extensions (T/TCP) +tcp_log_synfin="NO" # Set to YES to log TCP packets with SYN+FIN +tcp_restrict_rst="NO" # Set to YES to restrict emission of RST +icmp_dropredirect="NO" # Set to YES to ignore ICMP REDIRECT packets +icmp_logredirect="NO" # Set to YES to log ICMP REDIRECT packets network_interfaces="auto" # List of network interfaces (or "auto"). ifconfig_lo0="inet 127.0.0.1" # default loopback device configuration. #ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry. Index: etc/rc.network =================================================================== RCS file: /home/ncvs/src/etc/rc.network,v retrieving revision 1.52 diff -u -r1.52 rc.network --- rc.network 1999/07/26 15:17:23 1.52 +++ rc.network 1999/07/27 11:18:30 @@ -197,6 +197,16 @@ echo -n ' broadcast ping responses=YES' sysctl -w net.inet.icmp.bmcastecho=1 >/dev/null fi + + if [ "X$icmp_dropredirect" = X"YES" ]; then + echo -n ' ignore ICMP redirect=YES' + sysctl -w net.inet.icmp.dropredirect=1 >/dev/null + fi + + if [ "X$icmp_logredirect" = X"YES" ]; then + echo -n ' log ICMP redirect=YES' + sysctl -w net.inet.icmp.logredirect=1 >/dev/null + fi if [ "X$gateway_enable" = X"YES" ]; then echo -n ' IP gateway=YES' @@ -216,6 +226,21 @@ if [ "X$tcp_keepalive" = X"YES" ]; then echo -n ' TCP keepalive=YES' sysctl -w net.inet.tcp.always_keepalive=1 >/dev/null + fi + + if [ "X$tcp_drop_synfin" = X"YES" ]; then + echo -n ' drop SYN+FIN packets=YES' + sysctl -w net.inet.tcp.drop_synfin=1 >/dev/null + fi + + if [ "X$tcp_log_synfin" = X"YES" ]; then + echo -n ' log SYN+FIN packets=YES' + sysctl -w net.inet.tcp.log_synfin=1 >/dev/null + fi + + if [ "X$tcp_restrict_rst" = X"YES" ]; then + echo -n ' restrict TCP reset=YES' + sysctl -w net.inet.tcp.restrict_rst=1 >/dev/null fi if [ "X$ipxgateway_enable" = X"YES" ]; then Index: sys/conf/options =================================================================== RCS file: /home/ncvs/src/sys/conf/options,v retrieving revision 1.144 diff -u -r1.144 options --- options 1999/07/05 20:19:34 1.144 +++ options 1999/07/27 11:18:30 @@ -207,6 +207,8 @@ INET opt_inet.h IPDIVERT DUMMYNET opt_ipdn.h +IPFILTER opt_ipfilter.h +IPFILTER_LOG opt_ipfilter.h IPFIREWALL opt_ipfw.h IPFIREWALL_VERBOSE opt_ipfw.h IPFIREWALL_VERBOSE_LIMIT opt_ipfw.h @@ -220,11 +222,11 @@ PPP_BSDCOMP opt_ppp.h PPP_DEFLATE opt_ppp.h PPP_FILTER opt_ppp.h +SLIP_IFF_OPTS opt_slip.h TCP_COMPAT_42 opt_compat.h TCPDEBUG -IPFILTER opt_ipfilter.h -IPFILTER_LOG opt_ipfilter.h -SLIP_IFF_OPTS opt_slip.h +TCP_DROP_SYNFIN opt_tcp_input.h +TCP_RESTRICT_RST opt_tcp_input.h # ATM (HARP version) ATM_CORE opt_atm.h Index: sys/i386/conf/LINT =================================================================== RCS file: /home/ncvs/src/sys/i386/conf/LINT,v retrieving revision 1.620 diff -u -r1.620 LINT --- LINT 1999/07/26 05:47:17 1.620 +++ LINT 1999/07/27 11:18:30 @@ -469,6 +469,20 @@ options IPSTEALTH #support for stealth forwarding options TCPDEBUG +# The following options add sysctl variables for controlling how certain +# TCP packets are handled. +# +# TCP_DROP_SYNFIN adds support for ignoring TCP packets with SYN+FIN. This +# prevents nmap et al. from identifying the TCP/IP stack, but breaks support +# for RFC1644 extensions and is not recommended for web servers. +# +# TCP_RESTRICT_RST adds support for blocking the emission of TCP RST packets. +# This is useful on systems which are exposed to SYN floods (e.g. IRC servers) +# or any system which one does not want to be easily portscannable. +# +options TCP_DROP_SYNFIN #drop TCP packets with SYN+FIN +options TCP_RESTRICT_RST #restrict emission of TCP RST + # ICMP_BANDLIM enables icmp error response bandwidth limiting. You # typically want this option as it will help protect the machine from # D.O.S. packet attacks. Index: sys/netinet/ip_icmp.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_icmp.c,v retrieving revision 1.34 diff -u -r1.34 ip_icmp.c --- ip_icmp.c 1999/03/06 23:10:42 1.34 +++ ip_icmp.c 1999/07/27 11:18:30 @@ -69,6 +69,14 @@ SYSCTL_INT(_net_inet_icmp, ICMPCTL_MASKREPL, maskrepl, CTLFLAG_RW, &icmpmaskrepl, 0, ""); +static int logredirect = 0; +SYSCTL_INT(_net_inet_icmp, OID_AUTO, logredirect, CTLFLAG_RW, + &logredirect, 0, ""); + +static int dropredirect = 0; +SYSCTL_INT(_net_inet_icmp, OID_AUTO, dropredirect, CTLFLAG_RW, + &dropredirect, 0, ""); + #ifdef ICMP_BANDLIM /* @@ -92,8 +100,8 @@ */ static int icmpbmcastecho = 0; -SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW, &icmpbmcastecho, - 0, ""); +SYSCTL_INT(_net_inet_icmp, OID_AUTO, bmcastecho, CTLFLAG_RW, + &icmpbmcastecho, 0, ""); #ifdef ICMPPRINTFS @@ -462,6 +470,23 @@ return; case ICMP_REDIRECT: + if (logredirect) { + u_long src, dst, gw; + + src = ntohl(ip->ip_src.s_addr); + dst = ntohl(icp->icmp_ip.ip_dst.s_addr); + gw = ntohl(icp->icmp_gwaddr.s_addr); + printf("icmp_redirect from %d.%d.%d.%d: " + "%d.%d.%d.%d => %d.%d.%d.%d\n", + (int)(src >> 24), (int)((src & 0xff0000) >> 16), + (int)((src & 0xff00) >> 8), (int)(src & 0xff), + (int)(dst >> 24), (int)((dst & 0xff0000) >> 16), + (int)((dst & 0xff00) >> 8), (int)(dst & 0xff), + (int)(gw >> 24), (int)((gw & 0xff0000) >> 16), + (int)((gw & 0xff00) >> 8), (int)(gw & 0xff)); + } + if (dropredirect) + break; if (code > 3) goto badcode; if (icmplen < ICMP_ADVLENMIN || icmplen < ICMP_ADVLEN(icp) || Index: sys/netinet/tcp_input.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/tcp_input.c,v retrieving revision 1.87 diff -u -r1.87 tcp_input.c --- tcp_input.c 1999/07/18 14:42:48 1.87 +++ tcp_input.c 1999/07/27 11:18:30 @@ -36,6 +36,7 @@ #include "opt_ipfw.h" /* for ipfw_fwd */ #include "opt_tcpdebug.h" +#include "opt_tcp_input.h" #include #include @@ -78,7 +79,7 @@ struct tcpstat tcpstat; SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RD, - &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); + &tcpstat, tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); static int log_in_vain = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, @@ -89,6 +90,21 @@ &tcp_delack_enabled, 0, "Delay ACK to try and piggyback it onto a data packet"); +#ifdef TCP_RESTRICT_RST +static int restrict_rst = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, restrict_rst, CTLFLAG_RW, + &restrict_rst, 0, "Restrict RST emission"); +#endif + +#ifdef TCP_DROP_SYNFIN +static int drop_synfin = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, drop_synfin, CTLFLAG_RW, + &drop_synfin, 0, "Drop TCP packets with SYN+FIN set"); +static int log_synfin = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_synfin, CTLFLAG_RW, + &log_synfin, 0, "Log TCP packets with SYN+FIN set"); +#endif + u_long tcp_now; struct inpcbhead tcb; struct inpcbinfo tcbinfo; @@ -336,6 +352,28 @@ } tiflags = ti->ti_flags; +#ifdef TCP_DROP_SYNFIN + /* + * If the drop_synfin option is enabled, drop all packets with + * both the SYN and FIN bits set. This prevents e.g. nmap from + * identifying the TCP/IP stack. + * + * This is incompatible with RFC1644 extensions (T/TCP). + */ + if (tiflags & TH_SYN && tiflags & TH_FIN) { + if (log_synfin) { + u_long src; + + src = ntohl(ti->ti_src.s_addr); + printf("SYN+FIN from %d.%d.%d.%d\n", + (int)(src >> 24), (int)((src & 0xff0000) >> 16), + (int)((src & 0xff00) >> 8), (int)(src & 0xff)); + } + if (drop_synfin) + goto drop; + } +#endif + /* * Convert TCP protocol specific fields to host format. */ @@ -1764,6 +1802,10 @@ return; dropwithreset: +#ifdef TCP_RESTRICT_RST + if (restrict_rst) + goto drop; +#endif /* * Generate a RST, dropping incoming segment. * Make ACK acceptable to originator of segment. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message