Page MenuHomeVyOS Platform

FTP PASV breaks control connection
Closed, ResolvedPublicBUG

Description

I'm running a local FTP server behind VyOS with the firewall opened to allow the control connection on TCP/21. Clients on the WAN side are able to interact with the FTP server up until a PASV command is issued. The FTP server responds with an internal IP and port and this is properly mangled by conntrack to VyOS's WAN IP. Client are then able to establish the data connection; however at this point the control connection is wedged. Packets from both sides, which moments before crossed the NAT, are now dropped at VyOS.

Clients which issue an ESPV command instead continue to have a functional control connection, are also able to establish the data connection, and complete an FTP transfer.

vyos@vyos:~$ show version
Version:          VyOS 1.5-rolling-202409210006
Release train:    current
Release flavor:   generic

Built by:         autobuild@vyos.net
Built on:         Sat 21 Sep 2024 00:06 UTC
Build UUID:       2f25692e-e899-4266-b0e6-388578fea859
Build commit ID:  3f579439714481

Architecture:     x86_64
Boot via:         installed image
System type:      Xen HVM guest
Secure Boot:      n/a (BIOS)

Hardware vendor:  Xen
Hardware model:   HVM domU
Hardware S/N:     [snipped]
Hardware UUID:    [snipped]

Copyright:        VyOS maintainers and contributors
vyos@vyos# show nat destination rule 51
 destination {
     port 21
 }
 inbound-interface {
     name eth0
 }
 protocol tcp
 translation {
     address 192.168.0.10
     port 21
 }
vyos@vyos# show nat source
 rule 100 {
     outbound-interface {
         name eth0
     }
     source {
         address 192.168.0.0/24
     }
     translation {
         address masquerade
     }
 }
 rule 110 {
     description Hairpin
     destination {
         address 192.168.0.0/24
     }
     outbound-interface {
         name eth1
     }
     protocol tcp_udp
     source {
         address 192.168.0.0/24
     }
     translation {
         address masquerade
     }
 }
vyos@vyos# show system conntrack
 modules {
     ftp
     h323
     nfs
     pptp
     sip
     sqlnet
     tftp
 }

It sounded like this worked earlier in the year, per T5376, but I'm unable to find a copy of rolling-202402230022 to confirm.

Details

Version
VyOS 1.5-rolling-202409210006. VyOS 1.4.3
Is it a breaking change?
Behavior change
Issue type
Bug (incorrect behavior)

Event Timeline

syncer triaged this task as Normal priority.
n.fort subscribed.

I think we hit the same issue in 1.4.3. This is reproducible with the following configs:

  1. FTP Client, external network
set interfaces ethernet eth1 address '192.168.1.5/24'
set protocols static route 192.168.100.1/32 next-hop 192.168.1.1

Note: you may want to install the ftp client to test it properly. I'm not sure if this is reproducible in other ways: https://packages.debian.org/bookworm/tnftp

  1. VyOS router, NAT in the middle
set interfaces dummy dum1 address '192.168.100.1/32'
set interfaces ethernet eth1 address '192.168.1.1/24'
set interfaces ethernet eth2 address '192.168.2.1/24'
set nat destination rule 100 destination address '192.168.100.1/32'
set nat destination rule 100 translation address '192.168.2.2/32'
set nat source rule 100 source address '192.168.2.2/32'
set nat source rule 100 translation address '192.168.100.1/32'
set system conntrack modules ftp
set system conntrack modules h323
set system conntrack modules nfs
set system conntrack modules pptp
set system conntrack modules sip
set system conntrack modules sqlnet
set system conntrack modules tftp

FTP server, internal network

set container name FTPSRV allow-host-networks
set container name FTPSRV environment FTP_PASS value 'foobar'
set container name FTPSRV environment FTP_USER value 'ftpuser'
set container name FTPSRV environment PUBLIC_IP value '192.168.2.2'
set container name FTPSRV image 'docker.io/garethflowers/ftp-server:latest'
set container name FTPSRV volume FTPVOL destination '/home/ftpuser/'
set container name FTPSRV volume FTPVOL source '/config/ftpsrv'
set interfaces ethernet eth1 address '192.168.2.2/24'
set protocols static route 192.168.1.5/32 next-hop 192.168.2.1
set system name-server '1.1.1.1'
What is happening

With such a combination, an attempt to use passive mode looks like this:

root@vyos:/home/vyos# ftp -s 192.168.1.5 ftp://ftpuser:foobar@192.168.100.1
Connected to 192.168.100.1.
220 FTP Server
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
200 Switching to Binary mode.
ftp> epsv4 off
EPSV/EPRT on IPv4 off.
ftp> ls
227 Entering Passive Mode (192,168,100,1,156,71).
421 Service not available, remote server has closed connection.
ftp>

The interesting part here is: remote server has closed connection. Actually, the connection is not closed by the remote server. For some reason, this is what happens during the ls command:

20:04:49.017548 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 80: (tos 0x10, ttl 64, id 21887, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.1.5.43529 > 192.168.100.1.21: Flags [P.], cksum 0x55d0 (correct), seq 3749605933:3749605941, ack 4018950651, win 16384, options [nop,nop,TS val 358040743 ecr 3416769954], length 8: FTP, length: 8
	TYPE A
20:04:49.017624 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 80: (tos 0x10, ttl 63, id 21887, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.1.5.43529 > 192.168.2.2.21: Flags [P.], cksum 0xb7cf (correct), seq 3749605933:3749605941, ack 4018950651, win 16384, options [nop,nop,TS val 358040743 ecr 3416769954], length 8: FTP, length: 8
	TYPE A
20:04:49.018994 eth2  In  ifindex 4 0c:14:95:6a:00:01 ethertype IPv4 (0x0800), length 102: (tos 0x0, ttl 64, id 11234, offset 0, flags [DF], proto TCP (6), length 82)
    192.168.2.2.21 > 192.168.1.5.43529: Flags [P.], cksum 0x1743 (correct), seq 1:31, ack 8, win 510, options [nop,nop,TS val 3416780674 ecr 358040743], length 30: FTP, length: 30
	200 Switching to ASCII mode.
20:04:49.019071 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 102: (tos 0x0, ttl 63, id 11234, offset 0, flags [DF], proto TCP (6), length 82)
    192.168.100.1.21 > 192.168.1.5.43529: Flags [P.], cksum 0xb543 (correct), seq 1:31, ack 8, win 510, options [nop,nop,TS val 3416780674 ecr 358040743], length 30: FTP, length: 30
	200 Switching to ASCII mode.
20:04:49.019627 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 72: (tos 0x10, ttl 64, id 21888, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.5.43529 > 192.168.100.1.21: Flags [.], cksum 0xfdc1 (correct), seq 8, ack 31, win 16384, options [nop,nop,TS val 358040745 ecr 3416780674], length 0
20:04:49.019721 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 72: (tos 0x10, ttl 63, id 21888, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.5.43529 > 192.168.2.2.21: Flags [.], cksum 0x5fc1 (correct), seq 8, ack 31, win 16384, options [nop,nop,TS val 358040745 ecr 3416780674], length 0
20:04:49.019763 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 78: (tos 0x10, ttl 64, id 21889, offset 0, flags [DF], proto TCP (6), length 58)
    192.168.1.5.43529 > 192.168.100.1.21: Flags [P.], cksum 0x4d12 (correct), seq 8:14, ack 31, win 16384, options [nop,nop,TS val 358040745 ecr 3416780674], length 6: FTP, length: 6
	PASV
20:04:49.019782 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 78: (tos 0x10, ttl 63, id 21889, offset 0, flags [DF], proto TCP (6), length 58)
    192.168.1.5.43529 > 192.168.2.2.21: Flags [P.], cksum 0xaf11 (correct), seq 8:14, ack 31, win 16384, options [nop,nop,TS val 358040745 ecr 3416780674], length 6: FTP, length: 6
	PASV
20:04:49.020903 eth2  In  ifindex 4 0c:14:95:6a:00:01 ethertype IPv4 (0x0800), length 121: (tos 0x0, ttl 64, id 11235, offset 0, flags [DF], proto TCP (6), length 101)
    192.168.2.2.21 > 192.168.1.5.43529: Flags [P.], cksum 0x2322 (correct), seq 31:80, ack 14, win 510, options [nop,nop,TS val 3416780676 ecr 358040745], length 49: FTP, length: 49
	227 Entering Passive Mode (192,168,2,2,156,64).
20:04:49.020935 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 123: (tos 0x0, ttl 63, id 11235, offset 0, flags [DF], proto TCP (6), length 103)
    192.168.100.1.21 > 192.168.1.5.43529: Flags [P.], cksum 0x90f2 (correct), seq 31:82, ack 14, win 510, options [nop,nop,TS val 3416780676 ecr 358040745], length 51: FTP, length: 51
	227 Entering Passive Mode (192,168,100,1,156,64).
20:04:49.021571 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 64, id 38367, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.1.5.60585 > 192.168.100.1.40000: Flags [S], cksum 0xf8ca (correct), seq 4277438209, win 65535, options [mss 1460,sackOK,TS val 358040747 ecr 0,nop,wscale 2], length 0
20:04:49.021765 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 63, id 38367, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.1.5.60585 > 192.168.2.2.40000: Flags [S], cksum 0x5aca (correct), seq 4277438209, win 65535, options [mss 1460,sackOK,TS val 358040747 ecr 0,nop,wscale 2], length 0
20:04:49.022189 eth2  In  ifindex 4 0c:14:95:6a:00:01 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.2.2.40000 > 192.168.1.5.60585: Flags [S.], cksum 0x3f1f (correct), seq 4251673713, ack 4277438210, win 65160, options [mss 1460,sackOK,TS val 3416780678 ecr 358040747,nop,wscale 7], length 0
20:04:49.022240 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 80: (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    192.168.100.1.40000 > 192.168.1.5.60585: Flags [S.], cksum 0xdd1f (correct), seq 4251673713, ack 4277438210, win 65160, options [mss 1460,sackOK,TS val 3416780678 ecr 358040747,nop,wscale 7], length 0
20:04:49.022681 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 72: (tos 0x0, ttl 64, id 38368, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.5.60585 > 192.168.100.1.40000: Flags [.], cksum 0xca73 (correct), seq 1, ack 1, win 16384, options [nop,nop,TS val 358040748 ecr 3416780678], length 0
20:04:49.022726 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 72: (tos 0x0, ttl 63, id 38368, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.5.60585 > 192.168.2.2.40000: Flags [.], cksum 0x2c73 (correct), seq 1, ack 1, win 16384, options [nop,nop,TS val 358040748 ecr 3416780678], length 0
20:04:49.022754 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 78: (tos 0x10, ttl 64, id 21890, offset 0, flags [DF], proto TCP (6), length 58)
    192.168.1.5.43529 > 192.168.100.1.21: Flags [P.], cksum 0x50ce (correct), seq 14:20, ack 82, win 16384, options [nop,nop,TS val 358040748 ecr 3416780676], length 6: FTP, length: 6
	LIST
20:04:49.022858 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 60: (tos 0x10, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.100.1.21 > 192.168.1.5.43529: Flags [R], cksum 0xdd91 (correct), seq 4018950732, win 0, length 0
20:04:49.023247 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 72: (tos 0x8, ttl 64, id 38369, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.5.60585 > 192.168.100.1.40000: Flags [F.], cksum 0xca71 (correct), seq 1, ack 1, win 16384, options [nop,nop,TS val 358040749 ecr 3416780678], length 0
20:04:49.023266 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 72: (tos 0x8, ttl 63, id 38369, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.1.5.60585 > 192.168.2.2.40000: Flags [F.], cksum 0x2c71 (correct), seq 1, ack 1, win 16384, options [nop,nop,TS val 358040749 ecr 3416780678], length 0
20:04:49.023976 eth2  In  ifindex 4 0c:14:95:6a:00:01 ethertype IPv4 (0x0800), length 72: (tos 0x0, ttl 64, id 6199, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.2.2.40000 > 192.168.1.5.60585: Flags [.], cksum 0x6a71 (correct), seq 1, ack 2, win 510, options [nop,nop,TS val 3416780680 ecr 358040749], length 0
20:04:49.023995 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 72: (tos 0x0, ttl 63, id 6199, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.100.1.40000 > 192.168.1.5.60585: Flags [.], cksum 0x0872 (correct), seq 1, ack 2, win 510, options [nop,nop,TS val 3416780680 ecr 358040749], length 0
20:04:49.233273 eth2  In  ifindex 4 0c:14:95:6a:00:01 ethertype IPv4 (0x0800), length 121: (tos 0x0, ttl 64, id 11236, offset 0, flags [DF], proto TCP (6), length 101)
    192.168.2.2.21 > 192.168.1.5.43529: Flags [P.], cksum 0x224d (correct), seq 31:80, ack 14, win 510, options [nop,nop,TS val 3416780889 ecr 358040745], length 49: FTP, length: 49
	227 Entering Passive Mode (192,168,2,2,156,64).
20:04:49.233356 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 123: (tos 0x0, ttl 63, id 11236, offset 0, flags [DF], proto TCP (6), length 103)
    192.168.100.1.21 > 192.168.1.5.43529: Flags [P.], cksum 0x901d (correct), seq 31:82, ack 14, win 510, options [nop,nop,TS val 3416780889 ecr 358040745], length 51: FTP, length: 51
	227 Entering Passive Mode (192,168,100,1,156,64).
20:04:49.274504 eth1  In  ifindex 3 0c:8d:27:bc:00:02 ethertype IPv4 (0x0800), length 60: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.1.5.43529 > 192.168.100.1.21: Flags [R], cksum 0xcdb0 (correct), seq 3749605947, win 0, length 0
20:04:49.274567 eth2  Out ifindex 4 0c:8b:12:68:00:02 ethertype IPv4 (0x0800), length 60: (tos 0x0, ttl 63, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    192.168.1.5.43529 > 192.168.2.2.21: Flags [R], cksum 0x2fb0 (correct), seq 3749605947, win 0, length 0
20:04:49.276167 eth2  In  ifindex 4 0c:14:95:6a:00:01 ethertype IPv4 (0x0800), length 72: (tos 0x0, ttl 64, id 6200, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.2.2.40000 > 192.168.1.5.60585: Flags [R.], cksum 0x6971 (correct), seq 1, ack 2, win 510, options [nop,nop,TS val 3416780932 ecr 358040749], length 0
20:04:49.276218 eth1  Out ifindex 3 0c:8b:12:68:00:01 ethertype IPv4 (0x0800), length 72: (tos 0x0, ttl 63, id 6200, offset 0, flags [DF], proto TCP (6), length 52)
    192.168.100.1.40000 > 192.168.1.5.60585: Flags [R.], cksum 0x0772 (correct), seq 1, ack 2, win 510, options [nop,nop,TS val 3416780932 ecr 358040749], length 0

Pay attention to packets with timestamps 20:04:49.022754 and 20:04:49.022858. The first one is sent by the FTP client. The second one is actually generated by the router itself and has Flags [R], which forces the client to close the connection.

Most likely, there's an issue with the FTP helper. Without it, the problem is not reproducible, but the address in Entering Passive Mode is not translated, so the command can only work if the FTP server is configured with a proper public IP address.

SrividyaA changed Version from VyOS 1.5-rolling-202409210006 to VyOS 1.5-rolling-202409210006. VyOS 1.4.3.Sep 18 2025, 6:26 AM
SrividyaA subscribed.

This appears to be a kernel issue.

I enabled debugging to see more details, and here’s what I found:

During the very first ls command attempt after the system boot (and only the first one), there is a kernel error:

Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: Conntrackinfo = 2
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(60) >= skblen(60)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: nf_conntrack_ftp: wrong seq pos (UNSET)(0) or (UNSET)(0)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: nf_conntrack_ftp: wrong seq pos (UNSET)(0) or (UNSET)(0)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 34
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 34
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 13
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 13
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 23
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 23
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 19
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 19
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 15
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 15
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 14
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 14
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 9
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 9
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 8
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 8
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 31
Sep 18 13:07:44 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 31
Sep 18 13:07:45 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 8
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 8
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 30
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 30
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 49
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: Pattern matches!
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: Skipped up to 0x0 delimiter!
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: Match succeeded!
Sep 18 13:07:49 vyos kernel: nf_conntrack_ftp: conntrack_ftp: match `192,168,2,2,156,71' (18 bytes at 910033157)
Sep 18 13:07:49 vyos kernel: nf_nat_ftp: type 1, off 27 len 18
Sep 18 13:07:49 vyos kernel: nf_nat_ftp: calling nf_nat_mangle_tcp_packet
Sep 18 13:07:49 vyos kernel: ------------[ cut here ]------------
Sep 18 13:07:49 vyos kernel: Missing nfct_seqadj_ext_add() setup call
Sep 18 13:07:49 vyos kernel: WARNING: CPU: 0 PID: 0 at net/netfilter/nf_conntrack_seqadj.c:41 nf_ct_seqadj_set+0xbf/0xe0 [nf_conntrack]
Sep 18 13:07:49 vyos kernel: Modules linked in: dummy nft_nat nf_nat_tftp nf_conntrack_tftp nf_nat_sip nf_conntrack_sip nf_nat_pptp nf_conntrack_pptp nf_nat_h323 nf_conntrack_h323 nf_nat_ftp nf_conntrack_ftp af_packet nft_ct nft_chain_nat nf_nat nf_tables nfnetlink_cthelper nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nfnetlink intel_rapl_common crct10dif_pclmul crc32_pclmul ghash_clmulni_intel sha512_ssse3 sha256_ssse3 sha1_ssse3 aesni_intel sg crypto_simd cryptd pcspkr button evdev binfmt_misc tcp_bbr sch_fq_codel mpls_iptunnel mpls_router ip_tunnel br_netfilter bridge stp llc fuse efi_pstore configfs ip_tables x_tables autofs4 usb_storage ohci_hcd uhci_hcd ehci_hcd sd_mod squashfs lz4_decompress loop overlay ext4 crc16 mbcache jbd2 nls_cp437 vfat fat efivarfs nls_ascii sr_mod cdrom virtio_blk virtio_net net_failover failover crc32c_intel ata_piix libata virtio_pci virtio_pci_legacy_dev virtio_pci_modern_dev i2c_piix4 virtio scsi_mod scsi_common virtio_ring
Sep 18 13:07:49 vyos kernel: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.6.93-amd64-vyos #1
Sep 18 13:07:49 vyos kernel: Hardware name: QEMU Ubuntu 25.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Sep 18 13:07:49 vyos kernel: RIP: 0010:nf_ct_seqadj_set+0xbf/0xe0 [nf_conntrack]
Sep 18 13:07:49 vyos kernel: Code: ea 44 89 20 89 50 08 eb db 45 85 ed 74 de 80 3d 51 6d 00 00 00 75 d5 48 c7 c7 60 67 b8 c0 c6 05 41 6d 00 00 01 e8 f1 17 d2 ee <0f> 0b eb be be 02 00 00 00 e8 63 fc ff ff 48 89 c3 e9 66 ff ff ff
Sep 18 13:07:49 vyos kernel: RSP: 0018:ffffb3e040003920 EFLAGS: 00010282
Sep 18 13:07:49 vyos kernel: RAX: 0000000000000000 RBX: 0000000000000012 RCX: 0000000000000027
Sep 18 13:07:49 vyos kernel: RDX: ffff99c1bdc1d508 RSI: 0000000000000001 RDI: ffff99c1bdc1d500
Sep 18 13:07:49 vyos kernel: RBP: ffff99c15cc36900 R08: 0000000000000000 R09: ffffb3e0400037b8
Sep 18 13:07:49 vyos kernel: R10: 0000000000000003 R11: ffffffffb0cbab08 R12: ffff99c15cc36900
Sep 18 13:07:49 vyos kernel: R13: 0000000000000002 R14: ffff99c1435c0862 R15: ffff99c1424c6b00
Sep 18 13:07:49 vyos kernel: FS:  0000000000000000(0000) GS:ffff99c1bdc00000(0000) knlGS:0000000000000000
Sep 18 13:07:49 vyos kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Sep 18 13:07:49 vyos kernel: CR2: 00007f605b248000 CR3: 0000000008c80000 CR4: 0000000000750ef0
Sep 18 13:07:49 vyos kernel: PKRU: 55555554
Sep 18 13:07:49 vyos kernel: Call Trace:
Sep 18 13:07:49 vyos kernel:  <IRQ>
Sep 18 13:07:49 vyos kernel:  __nf_nat_mangle_tcp_packet+0x100/0x160 [nf_nat]
Sep 18 13:07:49 vyos kernel:  nf_nat_ftp+0x142/0x280 [nf_nat_ftp]
Sep 18 13:07:49 vyos kernel:  ? kmem_cache_alloc+0x157/0x290
Sep 18 13:07:49 vyos kernel:  ? help+0x4ce/0x880 [nf_conntrack_ftp]
Sep 18 13:07:49 vyos kernel:  help+0x4ce/0x880 [nf_conntrack_ftp]
Sep 18 13:07:49 vyos kernel:  ? nf_confirm+0x11f/0x2e0 [nf_conntrack]
Sep 18 13:07:49 vyos kernel:  nf_confirm+0x11f/0x2e0 [nf_conntrack]
Sep 18 13:07:49 vyos kernel:  nf_hook_slow+0x39/0xb0
Sep 18 13:07:49 vyos kernel:  ip_output+0xb6/0xf0
Sep 18 13:07:49 vyos kernel:  ? __pfx_ip_finish_output+0x10/0x10
Sep 18 13:07:49 vyos kernel:  ip_sublist_rcv_finish+0x7d/0x90
Sep 18 13:07:49 vyos kernel:  ip_sublist_rcv+0x190/0x220
Sep 18 13:07:49 vyos kernel:  ? __pfx_ip_rcv_finish+0x10/0x10
Sep 18 13:07:49 vyos kernel:  ip_list_rcv+0x134/0x160
Sep 18 13:07:49 vyos kernel:  __netif_receive_skb_list_core+0x299/0x2c0
Sep 18 13:07:49 vyos kernel:  netif_receive_skb_list_internal+0x1a7/0x2d0
Sep 18 13:07:49 vyos kernel:  napi_complete_done+0x69/0x1a0
Sep 18 13:07:49 vyos kernel:  virtnet_poll+0x3c0/0x540 [virtio_net]
Sep 18 13:07:49 vyos kernel:  __napi_poll+0x23/0x1a0
Sep 18 13:07:49 vyos kernel:  net_rx_action+0x141/0x2c0
Sep 18 13:07:49 vyos kernel:  handle_softirqs+0xd2/0x280
Sep 18 13:07:49 vyos kernel:  __irq_exit_rcu+0x68/0x90
Sep 18 13:07:49 vyos kernel:  sysvec_apic_timer_interrupt+0x66/0x80
Sep 18 13:07:49 vyos kernel:  </IRQ>
Sep 18 13:07:49 vyos kernel:  <TASK>
Sep 18 13:07:49 vyos kernel:  asm_sysvec_apic_timer_interrupt+0x16/0x20
Sep 18 13:07:49 vyos kernel: RIP: 0010:pv_native_safe_halt+0xb/0x10
Sep 18 13:07:49 vyos kernel: Code: 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 eb 07 0f 00 2d 79 03 3f 00 fb f4 <c3> cc cc cc cc 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 8b
Sep 18 13:07:49 vyos kernel: RSP: 0018:ffffffffb0c03e88 EFLAGS: 00000206
Sep 18 13:07:49 vyos kernel: RAX: ffff99c1bdc2aca0 RBX: 0000000000000000 RCX: 4000000000000000
Sep 18 13:07:49 vyos kernel: RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000000008a934
Sep 18 13:07:49 vyos kernel: RBP: ffffffffb0c0f200 R08: 0000000000000001 R09: 0000000000000000
Sep 18 13:07:49 vyos kernel: R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
Sep 18 13:07:49 vyos kernel: R13: 0000000000000000 R14: ffffffffb0c0f200 R15: 000000000008a000
Sep 18 13:07:49 vyos kernel:  ? ct_kernel_exit.constprop.0+0x63/0x80
Sep 18 13:07:49 vyos kernel:  default_idle+0x5/0x20
Sep 18 13:07:49 vyos kernel:  default_idle_call+0x28/0xb0
Sep 18 13:07:49 vyos kernel:  do_idle+0x1e7/0x230
Sep 18 13:07:49 vyos kernel:  cpu_startup_entry+0x21/0x30
Sep 18 13:07:49 vyos kernel:  rest_init+0xae/0xb0
Sep 18 13:07:49 vyos kernel:  arch_call_rest_init+0x5/0x30
Sep 18 13:07:49 vyos kernel:  start_kernel+0x4c5/0x770
Sep 18 13:07:49 vyos kernel:  x86_64_start_reservations+0x14/0x30
Sep 18 13:07:49 vyos kernel:  x86_64_start_kernel+0x71/0x80
Sep 18 13:07:49 vyos kernel:  secondary_startup_64_no_verify+0x178/0x17b
Sep 18 13:07:49 vyos kernel:  </TASK>
Sep 18 13:07:49 vyos kernel: ---[ end trace 0000000000000000 ]---
Sep 18 13:07:50 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 49
Sep 18 13:07:50 vyos kernel: nf_conntrack_ftp: Pattern matches!
Sep 18 13:07:50 vyos kernel: nf_conntrack_ftp: Skipped up to 0x0 delimiter!
Sep 18 13:07:50 vyos kernel: nf_conntrack_ftp: Match succeeded!
Sep 18 13:07:50 vyos kernel: nf_conntrack_ftp: conntrack_ftp: match `192,168,2,2,156,71' (18 bytes at 910033157)
Sep 18 13:07:50 vyos kernel: nf_nat_ftp: type 1, off 27 len 18
Sep 18 13:07:50 vyos kernel: nf_nat_ftp: calling nf_nat_mangle_tcp_packet
Sep 18 13:07:50 vyos kernel: nf_conntrack_ftp: ftp: dataoff(40) >= skblen(40)

All subsequent attempts do not trigger a kernel issue and look like this:

Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: Conntrackinfo = 2
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(60) >= skblen(60)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: nf_conntrack_ftp: wrong seq pos (UNSET)(0) or (UNSET)(0)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: nf_conntrack_ftp: wrong seq pos (UNSET)(0) or (UNSET)(0)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 34
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 34
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 13
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 13
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 23
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 23
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 19
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 19
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 15
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 15
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 14
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 14
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 7
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 9
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 9
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 8
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 8
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 31
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 31
Sep 18 13:08:59 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 8
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 8
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 30
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `229 ': dlen = 30
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: ftp: dataoff(52) >= skblen(52)
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `PORT': dlen = 6
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `EPRT': dlen = 6
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 49
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: Pattern matches!
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: Skipped up to 0x0 delimiter!
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: Match succeeded!
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: conntrack_ftp: match `192,168,2,2,156,69' (18 bytes at 676714108)
Sep 18 13:09:04 vyos kernel: nf_nat_ftp: type 1, off 27 len 18
Sep 18 13:09:04 vyos kernel: nf_nat_ftp: calling nf_nat_mangle_tcp_packet
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: find_pattern `227 ': dlen = 49
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: Pattern matches!
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: Skipped up to 0x0 delimiter!
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: Match succeeded!
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: conntrack_ftp: match `192,168,2,2,156,69' (18 bytes at 676714108)
Sep 18 13:09:04 vyos kernel: nf_nat_ftp: type 1, off 27 len 18
Sep 18 13:09:04 vyos kernel: nf_nat_ftp: calling nf_nat_mangle_tcp_packet
Sep 18 13:09:04 vyos kernel: nf_conntrack_ftp: ftp: dataoff(40) >= skblen(40)

It looks like something is wrong here, as the helper cannot modify the packet properly: https://github.com/torvalds/linux/blob/8b789f2b7602a818e7c7488c74414fae21392b63/net/netfilter/nf_nat_ftp.c#L61-L112

It was investigated - the bug is indeed in the kernel.
Currently, the patch is proposed. But it probably would be refactored in the near future to a patch ver3:

https://lkml.org/lkml/2025/10/16/653

Viacheslav claimed this task.
Viacheslav reassigned this task from Viacheslav to a.melnychenko.
Viacheslav moved this task from Need Triage to Completed on the VyOS Rolling board.
Viacheslav subscribed.