From nobody Mon Sep 17 00:00:00 2001 Subject: [PATCH] ported CONFIG_IP_STEALTH from 2.2.20. From: Willy TARREAU Date: 1136766949 +0100 [PATCH] ported CONFIG_IP_STEALTH from 2.2.20. It permits to drop connection attempts to closed ports without sending an RST back, which proves useful as a first protection barrier. The ICMP code has been removed from the patch since kernel 2.4 provides everything to block outgoing ICMP. --- Documentation/Configure.help | 24 ++++++++++++++++++++++++ include/linux/sysctl.h | 5 +++++ net/ipv4/Config.in | 1 + net/ipv4/igmp.c | 9 +++++++++ net/ipv4/sysctl_net_ipv4.c | 14 ++++++++++++++ net/ipv4/tcp_ipv4.c | 13 +++++++++++++ net/ipv4/udp.c | 9 ++++++++- 7 files changed, 74 insertions(+), 1 deletions(-) ad5a2a7ea795e0e29d1d1179b692d6a1fedd47b3 diff --git a/Documentation/Configure.help b/Documentation/Configure.help index a54a4c2..d03689b 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -3648,6 +3648,30 @@ CONFIG_IP6_NF_MATCH_IPV6HEADER If unsure, say 'N'. +Stealth IP stack +CONFIG_IP_STEALTH + Use this option to enable "Stealth" code in the kernel's IP Stack. + The purpose of this is to make your machine "invisible" on a network. + + If you say Y here, note that stealth options are not enabled by + default; you can enable them by saying Y to "/proc filesystem support" + and "Sysctl support" below and executing a command such as: + echo 1 >/proc/sys/net/ipv4/tcp_restrict_rst + + Features and /proc interfaces: + tcp_restrict_rst - Do not send TCP RST packets + (no "Connection Refused") + udp_restrict_pu - Do not send ICMP_UNREACH on udp + (Prevents UDP portscans) + igmp_restrict - Do not reply to IGMP requests + + Note that there is already a sysctl to ignore ICMP pings, + echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all + + Enabling all of the above and filtering all open ports should make + your machine very hard to detect, while not interfering with (most) + normal operation. + SYN flood protection CONFIG_SYN_COOKIES Normal TCP/IP networking is open to an attack known as "SYN diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 23c7ae4..87e4a0a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -253,6 +253,11 @@ enum NET_IPV4_FIB_HASH=19, NET_IPV4_NETFILTER=20, +#ifdef CONFIG_IP_STEALTH + NET_IPV4_TCP_RESTRICT_RST=30, + NET_IPV4_UDP_RESTRICT_PU=31, + NET_IPV4_IGMP_RESTRICT=32, +#endif NET_IPV4_TCP_TIMESTAMPS=33, NET_IPV4_TCP_WINDOW_SCALING=34, NET_IPV4_TCP_SACK=35, diff --git a/net/ipv4/Config.in b/net/ipv4/Config.in index 7417be6..2b29b8c 100644 --- a/net/ipv4/Config.in +++ b/net/ipv4/Config.in @@ -40,6 +40,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; the fi bool ' IP: TCP Explicit Congestion Notification support' CONFIG_INET_ECN bool ' IP: TCP syncookie support (disabled per default)' CONFIG_SYN_COOKIES +bool ' IP: Stealth Code (not enabled per default)' CONFIG_IP_STEALTH if [ "$CONFIG_NETFILTER" != "n" ]; then source net/ipv4/netfilter/Config.in fi diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 8159746..f7a87e2 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -104,6 +104,10 @@ #define IP_MAX_MEMBERSHIPS 20 #define IP_MAX_MSF 10 +#ifdef CONFIG_IP_STEALTH +int sysctl_igmp_restrict = 0; +#endif + #ifdef CONFIG_IP_MULTICAST /* Parameter names and values are taken from igmp-v2-06 draft */ @@ -615,6 +619,11 @@ static int igmp_send_report(struct in_de struct net_device *dev = in_dev->dev; u32 group = pmc ? pmc->multiaddr : 0; u32 dst; + +#ifdef CONFIG_IP_STEALTH + if (sysctl_igmp_restrict) + return -1; +#endif if (type == IGMPV3_HOST_MEMBERSHIP_REPORT) return igmpv3_send_report(in_dev, pmc); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index acdb779..6fd36f0 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -47,6 +47,12 @@ extern int inet_peer_maxttl; extern int inet_peer_gc_mintime; extern int inet_peer_gc_maxtime; +#ifdef CONFIG_IP_STEALTH +extern int sysctl_tcp_restrict_rst; +extern int sysctl_udp_restrict_pu; +extern int sysctl_igmp_restrict; +#endif + #ifdef CONFIG_SYSCTL static int tcp_retr1_max = 255; static int ip_local_port_range_min[] = { 1, 1 }; @@ -182,6 +188,14 @@ ctl_table ipv4_table[] = { &sysctl_icmp_ignore_bogus_error_responses, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_ROUTE, "route", NULL, 0, 0555, ipv4_route_table}, +#ifdef CONFIG_IP_STEALTH + {NET_IPV4_TCP_RESTRICT_RST, "tcp_restrict_rst", + &sysctl_tcp_restrict_rst, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_UDP_RESTRICT_PU, "udp_restrict_pu", + &sysctl_udp_restrict_pu, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_IGMP_RESTRICT, "igmp_restrict", + &sysctl_igmp_restrict, sizeof(int), 0644, NULL, &proc_dointvec}, +#endif #ifdef CONFIG_IP_MULTICAST {NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships", &sysctl_igmp_max_memberships, sizeof(int), 0644, NULL, &proc_dointvec}, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index fa56df8..76d0404 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -73,6 +73,10 @@ extern int sysctl_ip_default_ttl; int sysctl_tcp_tw_reuse = 0; int sysctl_tcp_low_latency = 0; +#ifdef CONFIG_IP_STEALTH +int sysctl_tcp_restrict_rst = 0; +#endif + /* Check TCP sequence numbers in ICMP packets. */ #define ICMP_MIN_LENGTH 8 @@ -1157,6 +1161,15 @@ static void tcp_v4_send_reset(struct sk_ struct tcphdr rth; struct ip_reply_arg arg; +#ifdef CONFIG_IP_STEALTH + /* We can avoid sending an RST in response to a SYN on a closed port. + This slows down port scans without the need of a firewall, and + without the firewall disagreeing with all any process. Also, out + of sync packets are still answered. + */ + if (sysctl_tcp_restrict_rst && th->syn && !th->ack) + return; +#endif /* Never send a reset in response to a reset. */ if (th->rst) return; diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index c0b89c1..7e3cf4f 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -98,6 +98,10 @@ #include #include +#ifdef CONFIG_IP_STEALTH +int sysctl_udp_restrict_pu = 0; +#endif + /* * Snmp MIB for the UDP layer */ @@ -1001,7 +1005,10 @@ int udp_rcv(struct sk_buff *skb) goto csum_error; UDP_INC_STATS_BH(UdpNoPorts); - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); +#ifdef CONFIG_IP_STEALTH + if (!sysctl_udp_restrict_pu) +#endif + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); /* * Hmm. We got an UDP packet to a port to which we -- 1.0.6