netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] [PATCH v3] add stealth mode
@ 2015-09-02  8:47 Matteo Croce
  2015-09-15 19:00 ` David Miller
  0 siblings, 1 reply; 14+ messages in thread
From: Matteo Croce @ 2015-09-02  8:47 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel, Matteo Croce

Add option to disable any reply not related to a listening socket,
like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
Also disables ICMP replies to echo request and timestamp.
The stealth mode can be enabled selectively for a single interface.

Signed-off-by: Matteo Croce <matteo@openwrt.org>
---
 Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
 include/linux/inetdevice.h             |  1 +
 include/linux/ipv6.h                   |  1 +
 include/uapi/linux/ip.h                |  1 +
 net/ipv4/devinet.c                     |  1 +
 net/ipv4/icmp.c                        |  6 ++++++
 net/ipv4/ip_input.c                    |  5 +++--
 net/ipv4/tcp_ipv4.c                    |  3 ++-
 net/ipv4/udp.c                         |  4 +++-
 net/ipv6/addrconf.c                    |  7 +++++++
 net/ipv6/icmp.c                        |  3 ++-
 net/ipv6/ip6_input.c                   |  5 +++--
 net/ipv6/tcp_ipv6.c                    |  2 +-
 net/ipv6/udp.c                         |  3 ++-
 14 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 5fae770..50fe7df 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1181,6 +1181,13 @@ tag - INTEGER
 	Allows you to write a number, which can be used as required.
 	Default value is 0.
 
+stealth - BOOLEAN
+	Disable any reply not related to a listening socket,
+	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
+	Also disables ICMP replies to echo requests and timestamp
+	and ICMP errors for unknown protocols.
+	Default value is 0.
+
 Alexey Kuznetsov.
 kuznet@ms2.inr.ac.ru
 
@@ -1584,6 +1591,13 @@ stable_secret - IPv6 address
 
 	By default the stable secret is unset.
 
+stealth - BOOLEAN
+	Disable any reply not related to a listening socket,
+	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
+	Also disables ICMPv6 replies to echo requests
+	and ICMP errors for unknown protocols.
+	Default value is 0.
+
 icmp/*:
 ratelimit - INTEGER
 	Limit the maximal rates for sending ICMPv6 packets.
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index a4328ce..a64c01e 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -128,6 +128,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
 #define IN_DEV_ARP_ANNOUNCE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
 #define IN_DEV_ARP_IGNORE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
 #define IN_DEV_ARP_NOTIFY(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
+#define IN_DEV_STEALTH(in_dev)		IN_DEV_MAXCONF((in_dev), STEALTH)
 
 struct in_ifaddr {
 	struct hlist_node	hash;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 82806c6..49494ec 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -53,6 +53,7 @@ struct ipv6_devconf {
 	__s32           ndisc_notify;
 	__s32		suppress_frag_ndisc;
 	__s32		accept_ra_mtu;
+	__s32		stealth;
 	struct ipv6_stable_secret {
 		bool initialized;
 		struct in6_addr secret;
diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
index 08f894d..4acbf99 100644
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -165,6 +165,7 @@ enum
 	IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL,
 	IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL,
 	IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
+	IPV4_DEVCONF_STEALTH,
 	__IPV4_DEVCONF_MAX
 };
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 2d9cb17..6d9c080 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2190,6 +2190,7 @@ static struct devinet_sysctl_table {
 					      "promote_secondaries"),
 		DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET,
 					      "route_localnet"),
+		DEVINET_SYSCTL_RW_ENTRY(STEALTH, "stealth"),
 	},
 };
 
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index f5203fb..e8e71fb 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -882,6 +882,9 @@ static bool icmp_echo(struct sk_buff *skb)
 {
 	struct net *net;
 
+	if (IN_DEV_STEALTH(skb->dev->ip_ptr))
+		return true;
+
 	net = dev_net(skb_dst(skb)->dev);
 	if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
 		struct icmp_bxm icmp_param;
@@ -915,6 +918,9 @@ static bool icmp_timestamp(struct sk_buff *skb)
 	if (skb->len < 4)
 		goto out_err;
 
+	if (IN_DEV_STEALTH(skb->dev->ip_ptr))
+		return true;
+
 	/*
 	 *	Fill in the current time as ms since midnight UT:
 	 */
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 2db4c87..c8e0c5b 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -223,8 +223,9 @@ static int ip_local_deliver_finish(struct sock *sk, struct sk_buff *skb)
 			if (!raw) {
 				if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 					IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS);
-					icmp_send(skb, ICMP_DEST_UNREACH,
-						  ICMP_PROT_UNREACH, 0);
+					if (!IN_DEV_STEALTH(skb->dev->ip_ptr))
+						icmp_send(skb, ICMP_DEST_UNREACH,
+							  ICMP_PROT_UNREACH, 0);
 				}
 				kfree_skb(skb);
 			} else {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 0ea2e1c..0b8a492 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -77,6 +77,7 @@
 #include <net/busy_poll.h>
 
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/ipv6.h>
 #include <linux/stddef.h>
 #include <linux/proc_fs.h>
@@ -1652,7 +1653,7 @@ csum_error:
 		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
 		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
-	} else {
+	} else if (!IN_DEV_STEALTH(skb->dev->ip_ptr)) {
 		tcp_v4_send_reset(NULL, skb);
 	}
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 1b8c5ba..2e19cf3 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -96,6 +96,7 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
 #include <net/tcp_states.h>
@@ -1823,7 +1824,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+	if (!IN_DEV_STEALTH(skb->dev->ip_ptr))
+		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
 
 	/*
 	 * Hmm.  We got an UDP packet to a port to which we
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 21c2c81..b9e44e2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5585,6 +5585,13 @@ static struct addrconf_sysctl_table
 			.proc_handler	= addrconf_sysctl_stable_secret,
 		},
 		{
+			.procname	= "stealth",
+			.data		= &ipv6_devconf.stealth,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec,
+		},
+		{
 			/* sentinel */
 		}
 	},
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 713d743..47797a6 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -723,7 +723,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
 
 	switch (type) {
 	case ICMPV6_ECHO_REQUEST:
-		icmpv6_echo_reply(skb);
+		if (!idev->cnf.stealth)
+			icmpv6_echo_reply(skb);
 		break;
 
 	case ICMPV6_ECHO_REPLY:
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 57990c9..97e68aa 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -255,8 +255,9 @@ resubmit:
 			if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 				IP6_INC_STATS_BH(net, idev,
 						 IPSTATS_MIB_INUNKNOWNPROTOS);
-				icmpv6_send(skb, ICMPV6_PARAMPROB,
-					    ICMPV6_UNK_NEXTHDR, nhoff);
+				if (!idev->cnf.stealth)
+					icmpv6_send(skb, ICMPV6_PARAMPROB,
+						    ICMPV6_UNK_NEXTHDR, nhoff);
 			}
 			kfree_skb(skb);
 		} else {
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 7a6cea5..ffb1b7d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1445,7 +1445,7 @@ csum_error:
 		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
 		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
-	} else {
+	} else if (!__in6_dev_get(skb->dev)->cnf.stealth) {
 		tcp_v6_send_reset(NULL, skb);
 	}
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e51fc3e..459238bb 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -934,7 +934,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
+	if (!__in6_dev_get(skb->dev)->cnf.stealth)
+		icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
 
 	kfree_skb(skb);
 	return 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH] [PATCH v3] add stealth mode
  2015-09-02  8:47 [PATCH] [PATCH v3] add stealth mode Matteo Croce
@ 2015-09-15 19:00 ` David Miller
  2015-09-16  9:54   ` [PATCH v4] " Matteo Croce
  0 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2015-09-15 19:00 UTC (permalink / raw)
  To: matteo; +Cc: netdev, linux-kernel

From: Matteo Croce <matteo@openwrt.org>
Date: Wed,  2 Sep 2015 10:47:35 +0200

> Add option to disable any reply not related to a listening socket,
> like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> Also disables ICMP replies to echo request and timestamp.
> The stealth mode can be enabled selectively for a single interface.
> 
> Signed-off-by: Matteo Croce <matteo@openwrt.org>

This doesn't apply cleanly to the current tree, please respin.

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4] add stealth mode
  2015-09-15 19:00 ` David Miller
@ 2015-09-16  9:54   ` Matteo Croce
  2015-09-16 10:26     ` Daniel Borkmann
                       ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Matteo Croce @ 2015-09-16  9:54 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-kernel, Matteo Croce

Add option to disable any reply not related to a listening socket,
like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
Also disables ICMP replies to echo request and timestamp.
The stealth mode can be enabled selectively for a single interface.

Signed-off-by: Matteo Croce <matteo@openwrt.org>
---
rebased on 4.3-rc1

 Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
 include/linux/inetdevice.h             |  1 +
 include/linux/ipv6.h                   |  1 +
 include/uapi/linux/ip.h                |  1 +
 net/ipv4/devinet.c                     |  1 +
 net/ipv4/icmp.c                        |  6 ++++++
 net/ipv4/ip_input.c                    |  5 +++--
 net/ipv4/tcp_ipv4.c                    |  3 ++-
 net/ipv4/udp.c                         |  4 +++-
 net/ipv6/addrconf.c                    |  7 +++++++
 net/ipv6/icmp.c                        |  3 ++-
 net/ipv6/ip6_input.c                   |  5 +++--
 net/ipv6/tcp_ipv6.c                    |  2 +-
 net/ipv6/udp.c                         |  3 ++-
 14 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ebe94f2..1d46adc 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1206,6 +1206,13 @@ igmp_link_local_mcast_reports - BOOLEAN
 	224.0.0.X range.
 	Default TRUE
 
+stealth - BOOLEAN
+	Disable any reply not related to a listening socket,
+	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
+	Also disables ICMP replies to echo requests and timestamp
+	and ICMP errors for unknown protocols.
+	Default value is 0.
+
 Alexey Kuznetsov.
 kuznet@ms2.inr.ac.ru
 
@@ -1635,6 +1642,13 @@ stable_secret - IPv6 address
 
 	By default the stable secret is unset.
 
+stealth - BOOLEAN
+	Disable any reply not related to a listening socket,
+	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
+	Also disables ICMPv6 replies to echo requests
+	and ICMP errors for unknown protocols.
+	Default value is 0.
+
 icmp/*:
 ratelimit - INTEGER
 	Limit the maximal rates for sending ICMPv6 packets.
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index a4328ce..a64c01e 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -128,6 +128,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
 #define IN_DEV_ARP_ANNOUNCE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
 #define IN_DEV_ARP_IGNORE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
 #define IN_DEV_ARP_NOTIFY(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
+#define IN_DEV_STEALTH(in_dev)		IN_DEV_MAXCONF((in_dev), STEALTH)
 
 struct in_ifaddr {
 	struct hlist_node	hash;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index f1f32af..a9d0172 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -55,6 +55,7 @@ struct ipv6_devconf {
 	__s32           ndisc_notify;
 	__s32		suppress_frag_ndisc;
 	__s32		accept_ra_mtu;
+	__s32		stealth;
 	struct ipv6_stable_secret {
 		bool initialized;
 		struct in6_addr secret;
diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
index 08f894d..4acbf99 100644
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -165,6 +165,7 @@ enum
 	IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL,
 	IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL,
 	IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
+	IPV4_DEVCONF_STEALTH,
 	__IPV4_DEVCONF_MAX
 };
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 2d9cb17..6d9c080 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2190,6 +2190,7 @@ static struct devinet_sysctl_table {
 					      "promote_secondaries"),
 		DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET,
 					      "route_localnet"),
+		DEVINET_SYSCTL_RW_ENTRY(STEALTH, "stealth"),
 	},
 };
 
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 79fe05b..4cd35b2 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -889,6 +889,9 @@ static bool icmp_echo(struct sk_buff *skb)
 {
 	struct net *net;
 
+	if (IN_DEV_STEALTH(skb->dev->ip_ptr))
+		return true;
+
 	net = dev_net(skb_dst(skb)->dev);
 	if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
 		struct icmp_bxm icmp_param;
@@ -922,6 +925,9 @@ static bool icmp_timestamp(struct sk_buff *skb)
 	if (skb->len < 4)
 		goto out_err;
 
+	if (IN_DEV_STEALTH(skb->dev->ip_ptr))
+		return true;
+
 	/*
 	 *	Fill in the current time as ms since midnight UT:
 	 */
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index f4fc8a7..e75f250 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -224,8 +224,9 @@ static int ip_local_deliver_finish(struct sock *sk, struct sk_buff *skb)
 			if (!raw) {
 				if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 					IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS);
-					icmp_send(skb, ICMP_DEST_UNREACH,
-						  ICMP_PROT_UNREACH, 0);
+					if (!IN_DEV_STEALTH(skb->dev->ip_ptr))
+						icmp_send(skb, ICMP_DEST_UNREACH,
+							  ICMP_PROT_UNREACH, 0);
 				}
 				kfree_skb(skb);
 			} else {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 93898e0..fe62ae0 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -77,6 +77,7 @@
 #include <net/busy_poll.h>
 
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/ipv6.h>
 #include <linux/stddef.h>
 #include <linux/proc_fs.h>
@@ -1652,7 +1653,7 @@ csum_error:
 		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
 		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
-	} else {
+	} else if (!IN_DEV_STEALTH(skb->dev->ip_ptr)) {
 		tcp_v4_send_reset(NULL, skb);
 	}
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c0a15e7..033a051 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -96,6 +96,7 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
 #include <net/tcp_states.h>
@@ -1843,7 +1844,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+	if (!IN_DEV_STEALTH(skb->dev->ip_ptr))
+		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
 
 	/*
 	 * Hmm.  We got an UDP packet to a port to which we
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 030fefd..09d6baa 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5713,6 +5713,13 @@ static struct addrconf_sysctl_table
 			.proc_handler	= addrconf_sysctl_ignore_routes_with_linkdown,
 		},
 		{
+			.procname	= "stealth",
+			.data		= &ipv6_devconf.stealth,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec,
+		},
+		{
 			/* sentinel */
 		}
 	},
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6c2b213..dbec4d76 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -723,7 +723,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
 
 	switch (type) {
 	case ICMPV6_ECHO_REQUEST:
-		icmpv6_echo_reply(skb);
+		if (!idev->cnf.stealth)
+			icmpv6_echo_reply(skb);
 		break;
 
 	case ICMPV6_ECHO_REPLY:
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index adba03a..0955db4 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -256,8 +256,9 @@ resubmit:
 			if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 				IP6_INC_STATS_BH(net, idev,
 						 IPSTATS_MIB_INUNKNOWNPROTOS);
-				icmpv6_send(skb, ICMPV6_PARAMPROB,
-					    ICMPV6_UNK_NEXTHDR, nhoff);
+				if (!idev->cnf.stealth)
+					icmpv6_send(skb, ICMPV6_PARAMPROB,
+						    ICMPV6_UNK_NEXTHDR, nhoff);
 			}
 			kfree_skb(skb);
 		} else {
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 97d9314..50178ce 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1445,7 +1445,7 @@ csum_error:
 		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
 		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
-	} else {
+	} else if (!__in6_dev_get(skb->dev)->cnf.stealth) {
 		tcp_v6_send_reset(NULL, skb);
 	}
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0aba654..f865aca 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -934,7 +934,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
+	if (!__in6_dev_get(skb->dev)->cnf.stealth)
+		icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
 
 	kfree_skb(skb);
 	return 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-16  9:54   ` [PATCH v4] " Matteo Croce
@ 2015-09-16 10:26     ` Daniel Borkmann
  2015-09-16 10:45       ` Matteo Croce
  2015-09-16 11:06     ` Florian Westphal
  2015-09-16 11:11     ` Eric Dumazet
  2 siblings, 1 reply; 14+ messages in thread
From: Daniel Borkmann @ 2015-09-16 10:26 UTC (permalink / raw)
  To: Matteo Croce, David Miller; +Cc: netdev, linux-kernel

On 09/16/2015 11:54 AM, Matteo Croce wrote:
> Add option to disable any reply not related to a listening socket,
> like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> Also disables ICMP replies to echo request and timestamp.
> The stealth mode can be enabled selectively for a single interface.
>
> Signed-off-by: Matteo Croce <matteo@openwrt.org>
> ---
> rebased on 4.3-rc1
>
>   Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
>   include/linux/inetdevice.h             |  1 +
>   include/linux/ipv6.h                   |  1 +
>   include/uapi/linux/ip.h                |  1 +
>   net/ipv4/devinet.c                     |  1 +
>   net/ipv4/icmp.c                        |  6 ++++++
>   net/ipv4/ip_input.c                    |  5 +++--
>   net/ipv4/tcp_ipv4.c                    |  3 ++-
>   net/ipv4/udp.c                         |  4 +++-
>   net/ipv6/addrconf.c                    |  7 +++++++
>   net/ipv6/icmp.c                        |  3 ++-
>   net/ipv6/ip6_input.c                   |  5 +++--
>   net/ipv6/tcp_ipv6.c                    |  2 +-
>   net/ipv6/udp.c                         |  3 ++-
>   14 files changed, 47 insertions(+), 9 deletions(-)
>
> diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
> index ebe94f2..1d46adc 100644
> --- a/Documentation/networking/ip-sysctl.txt
> +++ b/Documentation/networking/ip-sysctl.txt
> @@ -1206,6 +1206,13 @@ igmp_link_local_mcast_reports - BOOLEAN
>   	224.0.0.X range.
>   	Default TRUE
>
> +stealth - BOOLEAN
> +	Disable any reply not related to a listening socket,
> +	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> +	Also disables ICMP replies to echo requests and timestamp
> +	and ICMP errors for unknown protocols.
> +	Default value is 0.
> +

Hmm, what about all other protocols besides TCP/UDP such as SCTP, DCCP,
etc? It seems it gives false expectations in such cases when the user
enables being "stealth", but finds out it has no effect at all there ...
nmap f.e. has a couple of scanning options for SCTP, and at least SCTP
is still relevant in telco space.

I know this question has been asked before, but the only answer on this
was so far: "well, I've never played with SCTP before" ... :/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-16 10:26     ` Daniel Borkmann
@ 2015-09-16 10:45       ` Matteo Croce
  2015-09-16 11:11         ` Daniel Borkmann
  0 siblings, 1 reply; 14+ messages in thread
From: Matteo Croce @ 2015-09-16 10:45 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: David Miller, netdev, linux-kernel

2015-09-16 12:26 GMT+02:00 Daniel Borkmann <daniel@iogearbox.net>:
> On 09/16/2015 11:54 AM, Matteo Croce wrote:
>>
>> Add option to disable any reply not related to a listening socket,
>> like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
>> Also disables ICMP replies to echo request and timestamp.
>> The stealth mode can be enabled selectively for a single interface.
>>
>> Signed-off-by: Matteo Croce <matteo@openwrt.org>
>> ---
>> rebased on 4.3-rc1
>>
>>   Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
>>   include/linux/inetdevice.h             |  1 +
>>   include/linux/ipv6.h                   |  1 +
>>   include/uapi/linux/ip.h                |  1 +
>>   net/ipv4/devinet.c                     |  1 +
>>   net/ipv4/icmp.c                        |  6 ++++++
>>   net/ipv4/ip_input.c                    |  5 +++--
>>   net/ipv4/tcp_ipv4.c                    |  3 ++-
>>   net/ipv4/udp.c                         |  4 +++-
>>   net/ipv6/addrconf.c                    |  7 +++++++
>>   net/ipv6/icmp.c                        |  3 ++-
>>   net/ipv6/ip6_input.c                   |  5 +++--
>>   net/ipv6/tcp_ipv6.c                    |  2 +-
>>   net/ipv6/udp.c                         |  3 ++-
>>   14 files changed, 47 insertions(+), 9 deletions(-)
>>
>> diff --git a/Documentation/networking/ip-sysctl.txt
>> b/Documentation/networking/ip-sysctl.txt
>> index ebe94f2..1d46adc 100644
>> --- a/Documentation/networking/ip-sysctl.txt
>> +++ b/Documentation/networking/ip-sysctl.txt
>> @@ -1206,6 +1206,13 @@ igmp_link_local_mcast_reports - BOOLEAN
>>         224.0.0.X range.
>>         Default TRUE
>>
>> +stealth - BOOLEAN
>> +       Disable any reply not related to a listening socket,
>> +       like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
>> +       Also disables ICMP replies to echo requests and timestamp
>> +       and ICMP errors for unknown protocols.
>> +       Default value is 0.
>> +
>
>
> Hmm, what about all other protocols besides TCP/UDP such as SCTP, DCCP,
> etc? It seems it gives false expectations in such cases when the user
> enables being "stealth", but finds out it has no effect at all there ...
> nmap f.e. has a couple of scanning options for SCTP, and at least SCTP
> is still relevant in telco space.
>
> I know this question has been asked before, but the only answer on this
> was so far: "well, I've never played with SCTP before" ... :/

Right, I was thinking to add them in a later version

-- 
Matteo Croce
OpenWrt Developer
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 CHAOS CALMER
 -----------------------------------------------------
  * 1 1/2 oz Gin            Shake with a glassful
  * 1/4 oz Triple Sec       of broken ice and pour
  * 3/4 oz Lime Juice       unstrained into a goblet.
  * 1 1/2 oz Orange Juice
  * 1 tsp. Grenadine Syrup
 -----------------------------------------------------

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-16  9:54   ` [PATCH v4] " Matteo Croce
  2015-09-16 10:26     ` Daniel Borkmann
@ 2015-09-16 11:06     ` Florian Westphal
  2015-09-23 16:36       ` Matteo Croce
  2015-09-16 11:11     ` Eric Dumazet
  2 siblings, 1 reply; 14+ messages in thread
From: Florian Westphal @ 2015-09-16 11:06 UTC (permalink / raw)
  To: Matteo Croce; +Cc: David Miller, netdev, linux-kernel

Matteo Croce <matteo@openwrt.org> wrote:
> Add option to disable any reply not related to a listening socket,
> like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> Also disables ICMP replies to echo request and timestamp.
> The stealth mode can be enabled selectively for a single interface.

I think it would make more sense to extend the socket match
in xtables if it can't be used to achive this already.

seems like
*filter
:INPUT ACCEPT [0:0]
-A INPUT -p tcp -m socket --nowildcard -j ACCEPT
-A INPUT -p tcp -j DROP
COMMIT

Already does what you want for tcp, udp should work too.
I'd much rather see xtables and/or nftables to be extended
with whatever feature(s) are needed to configure such a policy
rather than pushing this into the core network stack.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-16  9:54   ` [PATCH v4] " Matteo Croce
  2015-09-16 10:26     ` Daniel Borkmann
  2015-09-16 11:06     ` Florian Westphal
@ 2015-09-16 11:11     ` Eric Dumazet
  2015-09-23 16:32       ` Matteo Croce
  2 siblings, 1 reply; 14+ messages in thread
From: Eric Dumazet @ 2015-09-16 11:11 UTC (permalink / raw)
  To: Matteo Croce; +Cc: David Miller, netdev, linux-kernel

On Wed, 2015-09-16 at 11:54 +0200, Matteo Croce wrote:
> diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> index 93898e0..fe62ae0 100644
> --- a/net/ipv4/tcp_ipv4.c
> +++ b/net/ipv4/tcp_ipv4.c
> @@ -77,6 +77,7 @@
>  #include <net/busy_poll.h>
>  
>  #include <linux/inet.h>
> +#include <linux/inetdevice.h>
>  #include <linux/ipv6.h>
>  #include <linux/stddef.h>
>  #include <linux/proc_fs.h>
> @@ -1652,7 +1653,7 @@ csum_error:
>  		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
>  bad_packet:
>  		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
> -	} else {
> +	} else if (!IN_DEV_STEALTH(skb->dev->ip_ptr)) {
>  		tcp_v4_send_reset(NULL, skb);
>  	}


It is illegal to deref skb->dev->ip_ptr without proper accessor /
annotations.

Check 

struct in_device *in_dev = __in_dev_get_rcu(skb->dev); 

(Same remarks in other places of your patch)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-16 10:45       ` Matteo Croce
@ 2015-09-16 11:11         ` Daniel Borkmann
  0 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2015-09-16 11:11 UTC (permalink / raw)
  To: Matteo Croce; +Cc: David Miller, netdev, linux-kernel

On 09/16/2015 12:45 PM, Matteo Croce wrote:
> 2015-09-16 12:26 GMT+02:00 Daniel Borkmann <daniel@iogearbox.net>:
>> On 09/16/2015 11:54 AM, Matteo Croce wrote:
>>>
>>> Add option to disable any reply not related to a listening socket,
>>> like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
>>> Also disables ICMP replies to echo request and timestamp.
>>> The stealth mode can be enabled selectively for a single interface.
>>>
>>> Signed-off-by: Matteo Croce <matteo@openwrt.org>
>>> ---
>>> rebased on 4.3-rc1
>>>
>>>    Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
>>>    include/linux/inetdevice.h             |  1 +
>>>    include/linux/ipv6.h                   |  1 +
>>>    include/uapi/linux/ip.h                |  1 +
>>>    net/ipv4/devinet.c                     |  1 +
>>>    net/ipv4/icmp.c                        |  6 ++++++
>>>    net/ipv4/ip_input.c                    |  5 +++--
>>>    net/ipv4/tcp_ipv4.c                    |  3 ++-
>>>    net/ipv4/udp.c                         |  4 +++-
>>>    net/ipv6/addrconf.c                    |  7 +++++++
>>>    net/ipv6/icmp.c                        |  3 ++-
>>>    net/ipv6/ip6_input.c                   |  5 +++--
>>>    net/ipv6/tcp_ipv6.c                    |  2 +-
>>>    net/ipv6/udp.c                         |  3 ++-
>>>    14 files changed, 47 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/Documentation/networking/ip-sysctl.txt
>>> b/Documentation/networking/ip-sysctl.txt
>>> index ebe94f2..1d46adc 100644
>>> --- a/Documentation/networking/ip-sysctl.txt
>>> +++ b/Documentation/networking/ip-sysctl.txt
>>> @@ -1206,6 +1206,13 @@ igmp_link_local_mcast_reports - BOOLEAN
>>>          224.0.0.X range.
>>>          Default TRUE
>>>
>>> +stealth - BOOLEAN
>>> +       Disable any reply not related to a listening socket,
>>> +       like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
>>> +       Also disables ICMP replies to echo requests and timestamp
>>> +       and ICMP errors for unknown protocols.
>>> +       Default value is 0.
>>> +
>>
>> Hmm, what about all other protocols besides TCP/UDP such as SCTP, DCCP,
>> etc? It seems it gives false expectations in such cases when the user
>> enables being "stealth", but finds out it has no effect at all there ...
>> nmap f.e. has a couple of scanning options for SCTP, and at least SCTP
>> is still relevant in telco space.
>>
>> I know this question has been asked before, but the only answer on this
>> was so far: "well, I've never played with SCTP before" ... :/
>
> Right, I was thinking to add them in a later version

I feel, there would be many follow-ups. :/ Architecturally on the bigger
picture, nft and its connection tracker would be the much better place for
such policies, and it also provides matches for various protocols already.

What has been tried to address this more generically f.e. inside netfilter
subsystem, and why is it absolutely not possible to extend this functionality
over there?

Sorry if my question is stubborn, but from reading over the old threads
it still is not fully clear to me.

Thanks again,
Daniel

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v4] add stealth mode
  2015-09-16 11:11     ` Eric Dumazet
@ 2015-09-23 16:32       ` Matteo Croce
  2015-09-23 18:15         ` David Miller
  0 siblings, 1 reply; 14+ messages in thread
From: Matteo Croce @ 2015-09-23 16:32 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev, linux-kernel, Matteo Croce

Add option to disable any reply not related to a listening socket,
like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
Also disables ICMP replies to echo request and timestamp.
The stealth mode can be enabled selectively for a single interface.

Signed-off-by: Matteo Croce <matteo@openwrt.org>
---
rebased against v4.3-rc2
use __in_dev_get_rcu() to access skb->dev->ip_ptr

 Documentation/networking/ip-sysctl.txt | 14 ++++++++++++++
 include/linux/inetdevice.h             |  1 +
 include/linux/ipv6.h                   |  1 +
 include/uapi/linux/ip.h                |  1 +
 net/ipv4/devinet.c                     |  1 +
 net/ipv4/icmp.c                        |  6 ++++++
 net/ipv4/ip_input.c                    |  5 +++--
 net/ipv4/tcp_ipv4.c                    |  3 ++-
 net/ipv4/udp.c                         |  4 +++-
 net/ipv6/addrconf.c                    |  7 +++++++
 net/ipv6/icmp.c                        |  3 ++-
 net/ipv6/ip6_input.c                   |  5 +++--
 net/ipv6/tcp_ipv6.c                    |  2 +-
 net/ipv6/udp.c                         |  3 ++-
 14 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ebe94f2..1d46adc 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1206,6 +1206,13 @@ igmp_link_local_mcast_reports - BOOLEAN
 	224.0.0.X range.
 	Default TRUE
 
+stealth - BOOLEAN
+	Disable any reply not related to a listening socket,
+	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
+	Also disables ICMP replies to echo requests and timestamp
+	and ICMP errors for unknown protocols.
+	Default value is 0.
+
 Alexey Kuznetsov.
 kuznet@ms2.inr.ac.ru
 
@@ -1635,6 +1642,13 @@ stable_secret - IPv6 address
 
 	By default the stable secret is unset.
 
+stealth - BOOLEAN
+	Disable any reply not related to a listening socket,
+	like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
+	Also disables ICMPv6 replies to echo requests
+	and ICMP errors for unknown protocols.
+	Default value is 0.
+
 icmp/*:
 ratelimit - INTEGER
 	Limit the maximal rates for sending ICMPv6 packets.
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index a4328ce..a64c01e 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -128,6 +128,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
 #define IN_DEV_ARP_ANNOUNCE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE)
 #define IN_DEV_ARP_IGNORE(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_IGNORE)
 #define IN_DEV_ARP_NOTIFY(in_dev)	IN_DEV_MAXCONF((in_dev), ARP_NOTIFY)
+#define IN_DEV_STEALTH(in_dev)		IN_DEV_MAXCONF((in_dev), STEALTH)
 
 struct in_ifaddr {
 	struct hlist_node	hash;
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index f1f32af..a9d0172 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -55,6 +55,7 @@ struct ipv6_devconf {
 	__s32           ndisc_notify;
 	__s32		suppress_frag_ndisc;
 	__s32		accept_ra_mtu;
+	__s32		stealth;
 	struct ipv6_stable_secret {
 		bool initialized;
 		struct in6_addr secret;
diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
index 08f894d..4acbf99 100644
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -165,6 +165,7 @@ enum
 	IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL,
 	IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL,
 	IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
+	IPV4_DEVCONF_STEALTH,
 	__IPV4_DEVCONF_MAX
 };
 
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 2d9cb17..6d9c080 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -2190,6 +2190,7 @@ static struct devinet_sysctl_table {
 					      "promote_secondaries"),
 		DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET,
 					      "route_localnet"),
+		DEVINET_SYSCTL_RW_ENTRY(STEALTH, "stealth"),
 	},
 };
 
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 79fe05b..4cd35b2 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -889,6 +889,9 @@ static bool icmp_echo(struct sk_buff *skb)
 {
 	struct net *net;
 
+	if (IN_DEV_STEALTH(__in_dev_get_rcu(skb->dev)))
+		return true;
+
 	net = dev_net(skb_dst(skb)->dev);
 	if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
 		struct icmp_bxm icmp_param;
@@ -922,6 +925,9 @@ static bool icmp_timestamp(struct sk_buff *skb)
 	if (skb->len < 4)
 		goto out_err;
 
+	if (IN_DEV_STEALTH(__in_dev_get_rcu(skb->dev)))
+		return true;
+
 	/*
 	 *	Fill in the current time as ms since midnight UT:
 	 */
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index f4fc8a7..e75f250 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -224,8 +224,9 @@ static int ip_local_deliver_finish(struct sock *sk, struct sk_buff *skb)
 			if (!raw) {
 				if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 					IP_INC_STATS_BH(net, IPSTATS_MIB_INUNKNOWNPROTOS);
-					icmp_send(skb, ICMP_DEST_UNREACH,
-						  ICMP_PROT_UNREACH, 0);
+					if (!IN_DEV_STEALTH(__in_dev_get_rcu(skb->dev)))
+						icmp_send(skb, ICMP_DEST_UNREACH,
+							  ICMP_PROT_UNREACH, 0);
 				}
 				kfree_skb(skb);
 			} else {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 93898e0..fe62ae0 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -77,6 +77,7 @@
 #include <net/busy_poll.h>
 
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/ipv6.h>
 #include <linux/stddef.h>
 #include <linux/proc_fs.h>
@@ -1652,7 +1653,7 @@ csum_error:
 		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
 		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
-	} else {
+	} else if (!IN_DEV_STEALTH(__in_dev_get_rcu(skb->dev))) {
 		tcp_v4_send_reset(NULL, skb);
 	}
 
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c0a15e7..033a051 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -96,6 +96,7 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/slab.h>
 #include <net/tcp_states.h>
@@ -1843,7 +1844,8 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	UDP_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+	if (!IN_DEV_STEALTH(__in_dev_get_rcu(skb->dev)))
+		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
 
 	/*
 	 * Hmm.  We got an UDP packet to a port to which we
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 030fefd..09d6baa 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5713,6 +5713,13 @@ static struct addrconf_sysctl_table
 			.proc_handler	= addrconf_sysctl_ignore_routes_with_linkdown,
 		},
 		{
+			.procname	= "stealth",
+			.data		= &ipv6_devconf.stealth,
+			.maxlen		= sizeof(int),
+			.mode		= 0644,
+			.proc_handler	= proc_dointvec,
+		},
+		{
 			/* sentinel */
 		}
 	},
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6c2b213..dbec4d76 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -723,7 +723,8 @@ static int icmpv6_rcv(struct sk_buff *skb)
 
 	switch (type) {
 	case ICMPV6_ECHO_REQUEST:
-		icmpv6_echo_reply(skb);
+		if (!idev->cnf.stealth)
+			icmpv6_echo_reply(skb);
 		break;
 
 	case ICMPV6_ECHO_REPLY:
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index adba03a..0955db4 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -256,8 +256,9 @@ resubmit:
 			if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
 				IP6_INC_STATS_BH(net, idev,
 						 IPSTATS_MIB_INUNKNOWNPROTOS);
-				icmpv6_send(skb, ICMPV6_PARAMPROB,
-					    ICMPV6_UNK_NEXTHDR, nhoff);
+				if (!idev->cnf.stealth)
+					icmpv6_send(skb, ICMPV6_PARAMPROB,
+						    ICMPV6_UNK_NEXTHDR, nhoff);
 			}
 			kfree_skb(skb);
 		} else {
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 97d9314..50178ce 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1445,7 +1445,7 @@ csum_error:
 		TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
 		TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
-	} else {
+	} else if (!__in6_dev_get(skb->dev)->cnf.stealth) {
 		tcp_v6_send_reset(NULL, skb);
 	}
 
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 0aba654..f865aca 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -934,7 +934,8 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		goto csum_error;
 
 	UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
-	icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
+	if (!__in6_dev_get(skb->dev)->cnf.stealth)
+		icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
 
 	kfree_skb(skb);
 	return 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-16 11:06     ` Florian Westphal
@ 2015-09-23 16:36       ` Matteo Croce
  2015-09-23 17:29         ` Eric Dumazet
  2015-09-23 18:15         ` David Miller
  0 siblings, 2 replies; 14+ messages in thread
From: Matteo Croce @ 2015-09-23 16:36 UTC (permalink / raw)
  To: Florian Westphal; +Cc: David Miller, netdev, linux-kernel

2015-09-16 13:06 GMT+02:00 Florian Westphal <fw@strlen.de>:
>
> Matteo Croce <matteo@openwrt.org> wrote:
> > Add option to disable any reply not related to a listening socket,
> > like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> > Also disables ICMP replies to echo request and timestamp.
> > The stealth mode can be enabled selectively for a single interface.
>
> I think it would make more sense to extend the socket match
> in xtables if it can't be used to achive this already.
>
> seems like
> *filter
> :INPUT ACCEPT [0:0]
> -A INPUT -p tcp -m socket --nowildcard -j ACCEPT
> -A INPUT -p tcp -j DROP
> COMMIT
>
> Already does what you want for tcp, udp should work too.
> I'd much rather see xtables and/or nftables to be extended
> with whatever feature(s) are needed to configure such a policy
> rather than pushing this into the core network stack.

The point is to do the filtering without *tables at all,
like /proc/sys/net/ipv4/icmp_echo_ignore_all does for pings

-- 
Matteo Croce
OpenWrt Developer
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 CHAOS CALMER
 -----------------------------------------------------
  * 1 1/2 oz Gin            Shake with a glassful
  * 1/4 oz Triple Sec       of broken ice and pour
  * 3/4 oz Lime Juice       unstrained into a goblet.
  * 1 1/2 oz Orange Juice
  * 1 tsp. Grenadine Syrup
 -----------------------------------------------------

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-23 16:36       ` Matteo Croce
@ 2015-09-23 17:29         ` Eric Dumazet
  2015-09-23 18:16           ` David Miller
  2015-09-23 18:15         ` David Miller
  1 sibling, 1 reply; 14+ messages in thread
From: Eric Dumazet @ 2015-09-23 17:29 UTC (permalink / raw)
  To: Matteo Croce; +Cc: Florian Westphal, David Miller, netdev, linux-kernel

On Wed, 2015-09-23 at 18:36 +0200, Matteo Croce wrote:
> 2015-09-16 13:06 GMT+02:00 Florian Westphal <fw@strlen.de>:
> >
> > Matteo Croce <matteo@openwrt.org> wrote:
> > > Add option to disable any reply not related to a listening socket,
> > > like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> > > Also disables ICMP replies to echo request and timestamp.
> > > The stealth mode can be enabled selectively for a single interface.
> >
> > I think it would make more sense to extend the socket match
> > in xtables if it can't be used to achive this already.
> >
> > seems like
> > *filter
> > :INPUT ACCEPT [0:0]
> > -A INPUT -p tcp -m socket --nowildcard -j ACCEPT
> > -A INPUT -p tcp -j DROP
> > COMMIT
> >
> > Already does what you want for tcp, udp should work too.
> > I'd much rather see xtables and/or nftables to be extended
> > with whatever feature(s) are needed to configure such a policy
> > rather than pushing this into the core network stack.
> 
> The point is to do the filtering without *tables at all,
> like /proc/sys/net/ipv4/icmp_echo_ignore_all does for pings

Yes, but this adds code in many places, even for people not caring of
such protection.

The point is : people wanting firewall like protections should instead
use netfilter framework.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-23 16:32       ` Matteo Croce
@ 2015-09-23 18:15         ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2015-09-23 18:15 UTC (permalink / raw)
  To: matteo; +Cc: eric.dumazet, netdev, linux-kernel

From: Matteo Croce <matteo@openwrt.org>
Date: Wed, 23 Sep 2015 18:32:12 +0200

> Add option to disable any reply not related to a listening socket,
> like RST/ACK for TCP and ICMP Port-Unreachable for UDP.
> Also disables ICMP replies to echo request and timestamp.
> The stealth mode can be enabled selectively for a single interface.
> 
> Signed-off-by: Matteo Croce <matteo@openwrt.org>

I don't want to see any more submissions of this feature patch, sorry.

I am convinced, based upon other's arguments, that netfilter can
provide this facility wholly.

So until you can convince us otherwise, your patch is inappropriate.

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-23 16:36       ` Matteo Croce
  2015-09-23 17:29         ` Eric Dumazet
@ 2015-09-23 18:15         ` David Miller
  1 sibling, 0 replies; 14+ messages in thread
From: David Miller @ 2015-09-23 18:15 UTC (permalink / raw)
  To: matteo; +Cc: fw, netdev, linux-kernel

From: Matteo Croce <matteo@openwrt.org>
Date: Wed, 23 Sep 2015 18:36:12 +0200

> The point is to do the filtering without *tables at all,
> like /proc/sys/net/ipv4/icmp_echo_ignore_all does for pings

That's not a good argument, sorry.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v4] add stealth mode
  2015-09-23 17:29         ` Eric Dumazet
@ 2015-09-23 18:16           ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2015-09-23 18:16 UTC (permalink / raw)
  To: eric.dumazet; +Cc: matteo, fw, netdev, linux-kernel

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 23 Sep 2015 10:29:52 -0700

> Yes, but this adds code in many places, even for people not caring of
> such protection.
> 
> The point is : people wanting firewall like protections should instead
> use netfilter framework.

+1

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-09-23 18:16 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-02  8:47 [PATCH] [PATCH v3] add stealth mode Matteo Croce
2015-09-15 19:00 ` David Miller
2015-09-16  9:54   ` [PATCH v4] " Matteo Croce
2015-09-16 10:26     ` Daniel Borkmann
2015-09-16 10:45       ` Matteo Croce
2015-09-16 11:11         ` Daniel Borkmann
2015-09-16 11:06     ` Florian Westphal
2015-09-23 16:36       ` Matteo Croce
2015-09-23 17:29         ` Eric Dumazet
2015-09-23 18:16           ` David Miller
2015-09-23 18:15         ` David Miller
2015-09-16 11:11     ` Eric Dumazet
2015-09-23 16:32       ` Matteo Croce
2015-09-23 18:15         ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).