From 7dbd1b1dd95449b1ab8c35cd35fe904eb35db374 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 2 Nov 2022 21:54:41 +0100 Subject: extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks SNAT, DNAT and REDIRECT extensions tried to prevent NF_NAT_RANGE_PROTO_RANDOM flag from being set if no port or address was also given. With SNAT and DNAT, this is not possible as the respective --to-destination or --to-source parameters are mandatory anyway. Looking at the kernel code, doing so with REDIRECT seems harmless. Moreover, nftables supports 'redirect random' without specifying a port-range. Signed-off-by: Phil Sutter --- extensions/libip6t_SNAT.c | 20 +++++--------------- extensions/libipt_SNAT.c | 16 ++++++---------- extensions/libxt_DNAT.c | 28 ++++------------------------ extensions/libxt_REDIRECT.t | 1 + extensions/libxt_REDIRECT.txlate | 3 +++ 5 files changed, 19 insertions(+), 49 deletions(-) diff --git a/extensions/libip6t_SNAT.c b/extensions/libip6t_SNAT.c index 4fe272b2..8bf7b035 100644 --- a/extensions/libip6t_SNAT.c +++ b/extensions/libip6t_SNAT.c @@ -20,9 +20,6 @@ enum { O_RANDOM, O_RANDOM_FULLY, O_PERSISTENT, - F_TO_SRC = 1 << O_TO_SRC, - F_RANDOM = 1 << O_RANDOM, - F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, }; static void SNAT_help(void) @@ -166,19 +163,13 @@ static void SNAT_parse(struct xt_option_call *cb) case O_PERSISTENT: range->flags |= NF_NAT_RANGE_PERSISTENT; break; - } -} - -static void SNAT_fcheck(struct xt_fcheck_call *cb) -{ - static const unsigned int f = F_TO_SRC | F_RANDOM; - static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; - struct nf_nat_range *range = cb->data; - - if ((cb->xflags & f) == f) + case O_RANDOM: range->flags |= NF_NAT_RANGE_PROTO_RANDOM; - if ((cb->xflags & r) == r) + break; + case O_RANDOM_FULLY: range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; + break; + } } static void print_range(const struct nf_nat_range *range) @@ -295,7 +286,6 @@ static struct xtables_target snat_tg_reg = { .userspacesize = XT_ALIGN(sizeof(struct nf_nat_range)), .help = SNAT_help, .x6_parse = SNAT_parse, - .x6_fcheck = SNAT_fcheck, .print = SNAT_print, .save = SNAT_save, .x6_options = SNAT_opts, diff --git a/extensions/libipt_SNAT.c b/extensions/libipt_SNAT.c index 211a20bc..9c8cdb46 100644 --- a/extensions/libipt_SNAT.c +++ b/extensions/libipt_SNAT.c @@ -13,9 +13,6 @@ enum { O_RANDOM, O_RANDOM_FULLY, O_PERSISTENT, - F_TO_SRC = 1 << O_TO_SRC, - F_RANDOM = 1 << O_RANDOM, - F_RANDOM_FULLY = 1 << O_RANDOM_FULLY, }; static void SNAT_help(void) @@ -141,20 +138,19 @@ static void SNAT_parse(struct xt_option_call *cb) case O_PERSISTENT: mr->range->flags |= NF_NAT_RANGE_PERSISTENT; break; + case O_RANDOM: + mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM; + break; + case O_RANDOM_FULLY: + mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; + break; } } static void SNAT_fcheck(struct xt_fcheck_call *cb) { - static const unsigned int f = F_TO_SRC | F_RANDOM; - static const unsigned int r = F_TO_SRC | F_RANDOM_FULLY; struct nf_nat_ipv4_multi_range_compat *mr = cb->data; - if ((cb->xflags & f) == f) - mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM; - if ((cb->xflags & r) == r) - mr->range->flags |= NF_NAT_RANGE_PROTO_RANDOM_FULLY; - mr->rangesize = 1; } diff --git a/extensions/libxt_DNAT.c b/extensions/libxt_DNAT.c index 7bfefc79..af445187 100644 --- a/extensions/libxt_DNAT.c +++ b/extensions/libxt_DNAT.c @@ -31,9 +31,6 @@ enum { O_TO_PORTS, O_RANDOM, O_PERSISTENT, - F_TO_DEST = 1 << O_TO_DEST, - F_TO_PORTS = 1 << O_TO_PORTS, - F_RANDOM = 1 << O_RANDOM, }; static void DNAT_help(void) @@ -229,6 +226,9 @@ static void __DNAT_parse(struct xt_option_call *cb, __u16 proto, case O_PERSISTENT: range->flags |= NF_NAT_RANGE_PERSISTENT; break; + case O_RANDOM: + range->flags |= NF_NAT_RANGE_PROTO_RANDOM; + break; } } @@ -250,21 +250,12 @@ static void DNAT_parse(struct xt_option_call *cb) mr->range->max = range.max_proto; /* fall through */ case O_PERSISTENT: + case O_RANDOM: mr->range->flags |= range.flags; break; } } -static void __DNAT_fcheck(struct xt_fcheck_call *cb, unsigned int *flags) -{ - static const unsigned int redir_f = F_TO_PORTS | F_RANDOM; - static const unsigned int dnat_f = F_TO_DEST | F_RANDOM; - - if ((cb->xflags & redir_f) == redir_f || - (cb->xflags & dnat_f) == dnat_f) - *flags |= NF_NAT_RANGE_PROTO_RANDOM; -} - static void DNAT_fcheck(struct xt_fcheck_call *cb) { struct nf_nat_ipv4_multi_range_compat *mr = cb->data; @@ -274,8 +265,6 @@ static void DNAT_fcheck(struct xt_fcheck_call *cb) if (mr->range[0].flags & NF_NAT_RANGE_PROTO_OFFSET) xtables_error(PARAMETER_PROBLEM, "Shifted portmap ranges not supported with this kernel"); - - __DNAT_fcheck(cb, &mr->range[0].flags); } static char *sprint_range(const struct nf_nat_range2 *r, int family) @@ -388,11 +377,6 @@ static void DNAT_parse_v2(struct xt_option_call *cb) __DNAT_parse(cb, entry->ip.proto, cb->data, AF_INET); } -static void DNAT_fcheck_v2(struct xt_fcheck_call *cb) -{ - __DNAT_fcheck(cb, &((struct nf_nat_range2 *)cb->data)->flags); -} - static void DNAT_print_v2(const void *ip, const struct xt_entry_target *target, int numeric) { @@ -428,8 +412,6 @@ static void DNAT_fcheck6(struct xt_fcheck_call *cb) if (range->flags & NF_NAT_RANGE_PROTO_OFFSET) xtables_error(PARAMETER_PROBLEM, "Shifted portmap ranges not supported with this kernel"); - - __DNAT_fcheck(cb, &range->flags); } static void DNAT_print6(const void *ip, const struct xt_entry_target *target, @@ -619,7 +601,6 @@ static struct xtables_target dnat_tg_reg[] = { .print = DNAT_print_v2, .save = DNAT_save_v2, .x6_parse = DNAT_parse_v2, - .x6_fcheck = DNAT_fcheck_v2, .x6_options = DNAT_opts, .xlate = DNAT_xlate_v2, }, @@ -634,7 +615,6 @@ static struct xtables_target dnat_tg_reg[] = { .print = DNAT_print6_v2, .save = DNAT_save6_v2, .x6_parse = DNAT_parse6_v2, - .x6_fcheck = DNAT_fcheck_v2, .x6_options = DNAT_opts, .xlate = DNAT_xlate6_v2, }, diff --git a/extensions/libxt_REDIRECT.t b/extensions/libxt_REDIRECT.t index f607dd0a..362efa84 100644 --- a/extensions/libxt_REDIRECT.t +++ b/extensions/libxt_REDIRECT.t @@ -14,3 +14,4 @@ -p tcp -j REDIRECT --to-ports ftp-ssh;;FAIL -p tcp -j REDIRECT --to-ports 10-ssh;;FAIL -j REDIRECT --to-ports 42;;FAIL +-j REDIRECT --random;=;OK diff --git a/extensions/libxt_REDIRECT.txlate b/extensions/libxt_REDIRECT.txlate index 2c536495..36419a46 100644 --- a/extensions/libxt_REDIRECT.txlate +++ b/extensions/libxt_REDIRECT.txlate @@ -16,6 +16,9 @@ nft add rule ip nat prerouting tcp dport 80 counter redirect to :10-22 iptables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT --to-ports 8080 --random nft add rule ip nat prerouting tcp dport 80 counter redirect to :8080 random +iptables-translate -t nat -A prerouting -j REDIRECT --random +nft add rule ip nat prerouting counter redirect random + ip6tables-translate -t nat -A prerouting -p tcp --dport 80 -j REDIRECT nft add rule ip6 nat prerouting tcp dport 80 counter redirect -- cgit v1.2.3