mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-03 15:55:38 +00:00
netfilter: nat: fix icmp id randomization
Sven Auhagen reported that a 2nd ping request will fail if 'fully-random'
mode is used.
Reason is that if no proto information is given, min/max are both 0,
so we set the icmp id to 0 instead of chosing a random value between
0 and 65535.
Update test case as well to catch this, without fix this yields:
[..]
ERROR: cannot ping ns1 from ns2 with ip masquerade fully-random (attempt 2)
ERROR: cannot ping ns1 from ns2 with ipv6 masquerade fully-random (attempt 2)
... becaus 2nd ping clashes with existing 'id 0' icmp conntrack and gets
dropped.
Fixes: 203f2e7820
("netfilter: nat: remove l4proto->unique_tuple")
Reported-by: Sven Auhagen <sven.auhagen@voleatech.de>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
33d1c01817
commit
5bdac418f3
2 changed files with 35 additions and 12 deletions
|
@ -415,9 +415,14 @@ static void nf_nat_l4proto_unique_tuple(struct nf_conntrack_tuple *tuple,
|
|||
case IPPROTO_ICMPV6:
|
||||
/* id is same for either direction... */
|
||||
keyptr = &tuple->src.u.icmp.id;
|
||||
min = range->min_proto.icmp.id;
|
||||
range_size = ntohs(range->max_proto.icmp.id) -
|
||||
ntohs(range->min_proto.icmp.id) + 1;
|
||||
if (!(range->flags & NF_NAT_RANGE_PROTO_SPECIFIED)) {
|
||||
min = 0;
|
||||
range_size = 65536;
|
||||
} else {
|
||||
min = ntohs(range->min_proto.icmp.id);
|
||||
range_size = ntohs(range->max_proto.icmp.id) -
|
||||
ntohs(range->min_proto.icmp.id) + 1;
|
||||
}
|
||||
goto find_free_id;
|
||||
#if IS_ENABLED(CONFIG_NF_CT_PROTO_GRE)
|
||||
case IPPROTO_GRE:
|
||||
|
|
|
@ -321,6 +321,7 @@ EOF
|
|||
|
||||
test_masquerade6()
|
||||
{
|
||||
local natflags=$1
|
||||
local lret=0
|
||||
|
||||
ip netns exec ns0 sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
|
||||
|
@ -354,13 +355,13 @@ ip netns exec ns0 nft -f - <<EOF
|
|||
table ip6 nat {
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 0; policy accept;
|
||||
meta oif veth0 masquerade
|
||||
meta oif veth0 masquerade $natflags
|
||||
}
|
||||
}
|
||||
EOF
|
||||
ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerading"
|
||||
echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerade $natflags"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
|
@ -397,19 +398,26 @@ EOF
|
|||
fi
|
||||
done
|
||||
|
||||
ip netns exec ns2 ping -q -c 1 dead:1::99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: cannot ping ns1 from ns2 with active ipv6 masquerade $natflags (attempt 2)"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
ip netns exec ns0 nft flush chain ip6 nat postrouting
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Could not flush ip6 nat postrouting" 1>&2
|
||||
lret=1
|
||||
fi
|
||||
|
||||
test $lret -eq 0 && echo "PASS: IPv6 masquerade for ns2"
|
||||
test $lret -eq 0 && echo "PASS: IPv6 masquerade $natflags for ns2"
|
||||
|
||||
return $lret
|
||||
}
|
||||
|
||||
test_masquerade()
|
||||
{
|
||||
local natflags=$1
|
||||
local lret=0
|
||||
|
||||
ip netns exec ns0 sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
|
||||
|
@ -417,7 +425,7 @@ test_masquerade()
|
|||
|
||||
ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: canot ping ns1 from ns2"
|
||||
echo "ERROR: cannot ping ns1 from ns2 $natflags"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
|
@ -443,13 +451,13 @@ ip netns exec ns0 nft -f - <<EOF
|
|||
table ip nat {
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 0; policy accept;
|
||||
meta oif veth0 masquerade
|
||||
meta oif veth0 masquerade $natflags
|
||||
}
|
||||
}
|
||||
EOF
|
||||
ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: cannot ping ns1 from ns2 with active ip masquerading"
|
||||
echo "ERROR: cannot ping ns1 from ns2 with active ip masquere $natflags"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
|
@ -485,13 +493,19 @@ EOF
|
|||
fi
|
||||
done
|
||||
|
||||
ip netns exec ns2 ping -q -c 1 10.0.1.99 > /dev/null # ping ns2->ns1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "ERROR: cannot ping ns1 from ns2 with active ip masquerade $natflags (attempt 2)"
|
||||
lret=1
|
||||
fi
|
||||
|
||||
ip netns exec ns0 nft flush chain ip nat postrouting
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Could not flush nat postrouting" 1>&2
|
||||
lret=1
|
||||
fi
|
||||
|
||||
test $lret -eq 0 && echo "PASS: IP masquerade for ns2"
|
||||
test $lret -eq 0 && echo "PASS: IP masquerade $natflags for ns2"
|
||||
|
||||
return $lret
|
||||
}
|
||||
|
@ -750,8 +764,12 @@ test_local_dnat
|
|||
test_local_dnat6
|
||||
|
||||
reset_counters
|
||||
test_masquerade
|
||||
test_masquerade6
|
||||
test_masquerade ""
|
||||
test_masquerade6 ""
|
||||
|
||||
reset_counters
|
||||
test_masquerade "fully-random"
|
||||
test_masquerade6 "fully-random"
|
||||
|
||||
reset_counters
|
||||
test_redirect
|
||||
|
|
Loading…
Add table
Reference in a new issue