From: Andrii Melnychenko <a.melnychenko@vyos.io>
To: netfilter-devel@vger.kernel.org, fw@strlen.de
Subject: [PATCH 1/1] tests: shell: Updated nat_ftp tests
Date: Mon, 27 Oct 2025 12:39:07 +0100 [thread overview]
Message-ID: <20251027113907.451391-1-a.melnychenko@vyos.io> (raw)
Added DNAT and SNAT only tests.
There was an issue with DNAT that was not covered by tests.
DNAT misses setting up the `seqadj`, which leads to FTP failures.
The fix for DNAT has already been proposed to the kernel.
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
---
tests/shell/testcases/packetpath/nat_ftp | 127 +++++++++++++++++++++--
1 file changed, 120 insertions(+), 7 deletions(-)
diff --git a/tests/shell/testcases/packetpath/nat_ftp b/tests/shell/testcases/packetpath/nat_ftp
index d0faf2ef..8d9e5d45 100755
--- a/tests/shell/testcases/packetpath/nat_ftp
+++ b/tests/shell/testcases/packetpath/nat_ftp
@@ -77,31 +77,45 @@ ip -net $S route add ${ip_rc}/64 via ${ip_rs} dev s_r
ip netns exec $C ping -q -6 ${ip_sr} -c1 > /dev/null
assert_pass "topo initialization"
-reload_ruleset()
+reload_ruleset_base()
{
- ip netns exec $R conntrack -F 2> /dev/null
- ip netns exec $R $NFT -f - <<-EOF
+ [[ $# -eq 2 && ( $1 -ne 0 || $2 -ne 0 ) ]]
+ assert_pass "reload ruleset options"
+
+ add_dnat=$1
+ add_snat=$2
+ ruleset=""
+
+ # flush and add FTP helper
+ read -r -d '' str <<-EOF
flush ruleset
table ip6 ftp_helper_nat_test {
ct helper ftp-standard {
type "ftp" protocol tcp;
}
+ EOF
+ ruleset+=$str$'\n'
+ # add DNAT
+ if [[ $add_dnat -ne 0 ]]; then
+ read -r -d '' str <<-EOF
chain PRE-dnat {
type nat hook prerouting priority dstnat; policy accept;
# Dnat the control connection, data connection will be automaticly NATed.
ip6 daddr ${ip_rc} counter ip6 nexthdr tcp tcp dport 2121 counter dnat ip6 to [${ip_sr}]:21
}
+ EOF
+ ruleset+=$str$'\n'
+ fi
+ # add FORWARD
+ read -r -d '' str <<-EOF
chain PRE-aftnat {
type filter hook prerouting priority 350; policy drop;
iifname r_c tcp dport 21 ct state new ct helper set "ftp-standard" counter accept
-
ip6 nexthdr tcp ct state related counter accept
ip6 nexthdr tcp ct state established counter accept
-
ip6 nexthdr icmpv6 counter accept
-
counter log
}
@@ -111,18 +125,51 @@ reload_ruleset()
ip6 nexthdr tcp ct state established counter accept
ip6 nexthdr tcp ct state related counter log accept
}
+ EOF
+ ruleset+=$str$'\n'
+ # add SNAT
+ if [[ $add_snat -ne 0 ]]; then
+ read -r -d '' str <<-EOF
chain POST-srcnat {
type nat hook postrouting priority srcnat; policy accept;
ip6 daddr ${ip_sr} ip6 nexthdr tcp tcp dport 21 counter snat ip6 to [${ip_rs}]:16500
}
- }
+ EOF
+ ruleset+=$str$'\n'
+ fi
+
+ ruleset+=$'}\n'
+
+ ip netns exec $R conntrack -F 2> /dev/null
+ ip netns exec $R $NFT -f - <<-EOF
+ ${ruleset}
EOF
+
assert_pass "apply ftp helper ruleset"
}
+reload_ruleset()
+{
+ reload_ruleset_base 1 1
+}
+
+reload_ruleset_dnat_only()
+{
+ reload_ruleset_base 1 0
+}
+
+reload_ruleset_snat_only()
+{
+ reload_ruleset_base 0 1
+}
+
dd if=/dev/urandom of="$INFILE" bs=4096 count=1 2>/dev/null
chmod 755 $INFILE
+
+mkdir -p /var/run/vsftpd/empty/
+cp $INFILE /var/run/vsftpd/empty/
+
assert_pass "Prepare the file for FTP transmission"
cat > ${FTPCONF} <<-EOF
@@ -158,6 +205,38 @@ tcpdump -nnr ${PCAP} src ${ip_rs} and dst ${ip_sr} 2>&1 |grep -q FTP
assert_pass "assert FTP traffic NATed"
+# test passive mode DNAT only
+reload_ruleset_dnat_only
+ip netns exec $S tcpdump -q --immediate-mode -Ui s_r -w ${PCAP} 2> /dev/null &
+pid=$!
+sleep 0.5
+ip netns exec $C curl --no-progress-meter --connect-timeout 5 ftp://[${ip_rc}]:2121/$(basename $INFILE) -o $OUTFILE
+assert_pass "curl ftp passive mode DNAT only"
+
+cmp "$INFILE" "$OUTFILE"
+assert_pass "FTP Passive mode DNAT only: The input and output files remain the same when traffic passes through NAT."
+
+kill $pid; sync
+tcpdump -nnr ${PCAP} src ${ip_cr} and dst ${ip_sr} 2>&1 |grep -q FTP
+assert_pass "assert FTP traffic DNATed"
+
+
+# test passive mode SNAT only
+reload_ruleset_snat_only
+ip netns exec $S tcpdump -q --immediate-mode -Ui s_r -w ${PCAP} 2> /dev/null &
+pid=$!
+sleep 0.5
+ip netns exec $C curl --no-progress-meter --connect-timeout 5 ftp://[${ip_sr}]:21/$(basename $INFILE) -o $OUTFILE
+assert_pass "curl ftp passive mode SNAT only"
+
+cmp "$INFILE" "$OUTFILE"
+assert_pass "FTP Passive mode SNAT only: The input and output files remain the same when traffic passes through NAT."
+
+kill $pid; sync
+tcpdump -nnr ${PCAP} src ${ip_rs} and dst ${ip_sr} 2>&1 |grep -q FTP
+assert_pass "assert FTP traffic SNATed"
+
+
# test active mode
reload_ruleset
@@ -174,5 +253,39 @@ kill $pid; sync
tcpdump -nnr ${PCAP} src ${ip_rs} and dst ${ip_sr} 2>&1 |grep -q FTP
assert_pass "assert FTP traffic NATed"
+
+# test active mode DNAT only
+reload_ruleset_dnat_only
+
+ip netns exec $S tcpdump -q --immediate-mode -Ui s_r -w ${PCAP} 2> /dev/null &
+pid=$!
+sleep 0.5
+ip netns exec $C curl --no-progress-meter -P - --connect-timeout 5 ftp://[${ip_rc}]:2121/$(basename $INFILE) -o $OUTFILE
+assert_pass "curl ftp active mode "
+
+cmp "$INFILE" "$OUTFILE"
+assert_pass "FTP Active mode: in and output files remain the same when FTP traffic passes through NAT."
+
+kill $pid; sync
+tcpdump -nnr ${PCAP} src ${ip_cr} and dst ${ip_sr} 2>&1 |grep -q FTP
+assert_pass "assert FTP traffic DNATed"
+
+
+# test active mode SNAT only
+reload_ruleset_snat_only
+
+ip netns exec $S tcpdump -q --immediate-mode -Ui s_r -w ${PCAP} 2> /dev/null &
+pid=$!
+sleep 0.5
+ip netns exec $C curl --no-progress-meter -P - --connect-timeout 5 ftp://[${ip_sr}]:21/$(basename $INFILE) -o $OUTFILE
+assert_pass "curl ftp active mode "
+
+cmp "$INFILE" "$OUTFILE"
+assert_pass "FTP Active mode: in and output files remain the same when FTP traffic passes through NAT."
+
+kill $pid; sync
+tcpdump -nnr ${PCAP} src ${ip_rs} and dst ${ip_sr} 2>&1 |grep -q FTP
+assert_pass "assert FTP traffic SNATed"
+
# trap calls cleanup
exit 0
--
2.43.0
next reply other threads:[~2025-10-27 11:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-27 11:39 Andrii Melnychenko [this message]
2025-10-27 19:02 ` [PATCH 1/1] tests: shell: Updated nat_ftp tests Florian Westphal
2025-10-28 14:06 ` Andrii Melnychenko
2025-10-28 14:11 ` Florian Westphal
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=20251027113907.451391-1-a.melnychenko@vyos.io \
--to=a.melnychenko@vyos.io \
--cc=fw@strlen.de \
--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 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).