]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
extensions: *NAT: Drop NF_NAT_RANGE_PROTO_RANDOM* flag checks
authorPhil Sutter <phil@nwl.cc>
Wed, 2 Nov 2022 20:54:41 +0000 (21:54 +0100)
committerPhil Sutter <phil@nwl.cc>
Fri, 11 Nov 2022 18:13:10 +0000 (19:13 +0100)
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 <phil@nwl.cc>
extensions/libip6t_SNAT.c
extensions/libipt_SNAT.c
extensions/libxt_DNAT.c
extensions/libxt_REDIRECT.t
extensions/libxt_REDIRECT.txlate

index 4fe272b262a3d2431ed7ba317350f3e729d210f5..8bf7b035f84b6da7baab2740330bc6d34bfb7412 100644 (file)
@@ -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,
index 211a20bc45bfe4a8c8885c3e1d54802f2ed6e37c..9c8cdb46a158586fd010bef2acb2e30d365d773e 100644 (file)
@@ -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;
 }
 
index 7bfefc7961fac68898bb8c81d4f9fa2d8ebe28c5..af44518798aef71b497b5d308612805c74e3240d 100644 (file)
@@ -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,
        },
index f607dd0a12c51911d8232c2a7e79b59c084ad627..362efa8428ed499c874f960988e6acd1616fa665 100644 (file)
@@ -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
index 2c536495b35a2be2232424d34e16b5242d480700..36419a46bb366aed09ea0fe6c85dca5fc66e84fb 100644 (file)
@@ -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