All of lore.kernel.org
 help / color / mirror / Atom feed
From: Balazs Scheidler <bazsi77@gmail.com>
To: netfilter-devel@vger.kernel.org
Cc: Balazs Scheidler <bazsi77@gmail.com>
Subject: [PATCH nftables v2 1/5] socket: add support for "wildcard" key
Date: Sat, 29 Aug 2020 09:04:01 +0200	[thread overview]
Message-ID: <20200829070405.23636-2-bazsi77@gmail.com> (raw)
In-Reply-To: <20200829070405.23636-1-bazsi77@gmail.com>

iptables had a "-m socket --transparent" which didn't match sockets that are
bound to all addresses (e.g.  0.0.0.0 for ipv4, and ::0 for ipv6).  It was
possible to override this behavior by using --nowildcard, in which case it
did match zero bound sockets as well.

The issue is that nftables never included the wildcard check, so in effect
it behaved like "iptables -m socket --transparent --nowildcard" with no
means to exclude wildcarded listeners.

This is a problem as a user-space process that binds to 0.0.0.0:<port> that
enables IP_TRANSPARENT would effectively intercept traffic going in _any_
direction on the specific port, whereas in most cases, transparent proxies
would only need this for one specific address.

The solution is to add "socket wildcard" key to the nft_socket module, which
makes it possible to match on the wildcardness of a socket from
one's ruleset.

This is how to use it:

table inet haproxy {
	chain prerouting {
        	type filter hook prerouting priority -150; policy accept;
		socket transparent 1 socket wildcard 0 mark set 0x00000001
	}
}

This patch effectively depends on its counterpart in the kernel.

Signed-off-by: Balazs Scheidler <bazsi77@gmail.com>
---
 include/linux/netfilter/nf_tables.h | 2 ++
 src/evaluate.c                      | 4 +++-
 src/parser_bison.y                  | 2 ++
 src/parser_json.c                   | 2 ++
 src/scanner.l                       | 1 +
 src/socket.c                        | 6 ++++++
 6 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 1341b52f..10be073a 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -996,10 +996,12 @@ enum nft_socket_attributes {
  *
  * @NFT_SOCKET_TRANSPARENT: Value of the IP(V6)_TRANSPARENT socket option
  * @NFT_SOCKET_MARK: Value of the socket mark
+ * @NFT_SOCKET_WILDCARD: Whether the socket is zero-bound (e.g. 0.0.0.0 or ::0)
  */
 enum nft_socket_keys {
 	NFT_SOCKET_TRANSPARENT,
 	NFT_SOCKET_MARK,
+	NFT_SOCKET_WILDCARD,
 	__NFT_SOCKET_MAX
 };
 #define NFT_SOCKET_MAX	(__NFT_SOCKET_MAX - 1)
diff --git a/src/evaluate.c b/src/evaluate.c
index 320a464f..e1992e2a 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1999,8 +1999,10 @@ static int expr_evaluate_meta(struct eval_ctx *ctx, struct expr **exprp)
 static int expr_evaluate_socket(struct eval_ctx *ctx, struct expr **expr)
 {
 	int maxval = 0;
+	enum nft_socket_keys key = (*expr)->socket.key;
 
-	if((*expr)->socket.key == NFT_SOCKET_TRANSPARENT)
+	if (key == NFT_SOCKET_TRANSPARENT ||
+	    key == NFT_SOCKET_WILDCARD)
 		maxval = 1;
 	__expr_set_context(&ctx->ectx, (*expr)->dtype, (*expr)->byteorder,
 			   (*expr)->len, maxval);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 95adc48f..d938f566 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -213,6 +213,7 @@ int nft_lex(void *, void *, void *);
 
 %token SOCKET			"socket"
 %token TRANSPARENT		"transparent"
+%token WILDCARD			"wildcard"
 
 %token TPROXY			"tproxy"
 
@@ -4595,6 +4596,7 @@ socket_expr		:	SOCKET	socket_key
 
 socket_key 		: 	TRANSPARENT	{ $$ = NFT_SOCKET_TRANSPARENT; }
 			|	MARK		{ $$ = NFT_SOCKET_MARK; }
+			|	WILDCARD	{ $$ = NFT_SOCKET_WILDCARD; }
 			;
 
 offset_opt		:	/* empty */	{ $$ = 0; }
diff --git a/src/parser_json.c b/src/parser_json.c
index 59347168..ac89166e 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -427,6 +427,8 @@ static struct expr *json_parse_socket_expr(struct json_ctx *ctx,
 		keyval = NFT_SOCKET_TRANSPARENT;
 	else if (!strcmp(key, "mark"))
 		keyval = NFT_SOCKET_MARK;
+	else if (!strcmp(key, "wildcard"))
+		keyval = NFT_SOCKET_WILDCARD;
 
 	if (keyval == -1) {
 		json_error(ctx, "Invalid socket key value.");
diff --git a/src/scanner.l b/src/scanner.l
index 45699c85..9e6464f9 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -268,6 +268,7 @@ addrstring	({macaddr}|{ip4addr}|{ip6addr})
 
 "socket"		{ return SOCKET; }
 "transparent"		{ return TRANSPARENT;}
+"wildcard"		{ return WILDCARD; }
 
 "tproxy"		{ return TPROXY; }
 
diff --git a/src/socket.c b/src/socket.c
index d78a163a..673e5d0f 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -26,6 +26,12 @@ const struct socket_template socket_templates[] = {
 		.len		= 4 * BITS_PER_BYTE,
 		.byteorder	= BYTEORDER_HOST_ENDIAN,
 	},
+	[NFT_SOCKET_WILDCARD] = {
+		.token		= "wildcard",
+		.dtype		= &integer_type,
+		.len		= BITS_PER_BYTE,
+		.byteorder	= BYTEORDER_HOST_ENDIAN,
+	},
 };
 
 static void socket_expr_print(const struct expr *expr, struct output_ctx *octx)
-- 
2.17.1


  reply	other threads:[~2020-08-29  7:04 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-29  7:04 Balazs Scheidler
2020-08-29  7:04 ` Balazs Scheidler [this message]
2020-08-29 11:17   ` [PATCH nftables v2 1/5] socket: add support for "wildcard" key Pablo Neira Ayuso
2020-08-29  7:04 ` [PATCH nftables v2 2/5] src/scanner.l: fix whitespace issue for the TRANSPARENT keyword Balazs Scheidler
2020-08-29 11:17   ` Pablo Neira Ayuso
2020-08-29  7:04 ` [PATCH nftables v2 3/5] doc: added documentation on "socket wildcard" Balazs Scheidler
2020-08-29 11:17   ` Pablo Neira Ayuso
2020-08-29  7:04 ` [PATCH nftables v2 4/5] tests: added "socket wildcard" testcases Balazs Scheidler
2020-08-29 11:17   ` Pablo Neira Ayuso
2020-08-29  7:04 ` [PATCH nftables v2 5/5] tests: allow tests/monitor to use a custom nft executable Balazs Scheidler
2020-08-29 11:18   ` Pablo Neira Ayuso
2020-08-29 12:24     ` Stefano Brivio
2020-08-29 14:21       ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200829070405.23636-2-bazsi77@gmail.com \
    --to=bazsi77@gmail.com \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.