Opened 15 months ago
Last modified 11 months ago
#12991 new Bug report
Passive Transfers Fail When Client Has CGNAT IP
Reported by: | John Hossbach | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | FileZilla Server |
Keywords: | passive transfer PASV CGNAT | Cc: | |
Component version: | 1.7.3 | Operating system type: | Windows |
Operating system version: | Server 2019 |
Description (last modified by )
Reference: my original forum post
In my server config, I'm using a hostname to provide the correct external IP for passive transfers. I also have the "Use the default host for local connections" option enabled. This works great for the private network address space, however, it does not recognize the Carrier-grade NAT (CGNAT) address space, which is also non-Internet-routable IP space. Can we please get 100.64.0.0/10 added to the exception list? I've confirmed this is still a problem with FileZilla Server 1.7.3.
Not recognizing this CGNAT space results in failed passive transfers and the following error:
Data peer IP [A.B.C.D] differs from control peer IP [100.x.x.x]: this shouldn't happen, aborting the data connection.
What's happening here is that the CGNAT address space is being treated as a non-local connection and is being sent the "public" IP (resolved from the hostname provided) in the 227 response. Instead, CGNAT address space should be treated the same as private network address space and the 227 response should have the server's IP.
Sample logs:
- 100.x.x.x - Client CGNAT IP (IP assigned to client)
- 9.8.7.6 - Client Public Outbound NAT IP
- 1.2.3.4 - Server
2023-10-02T16:00:23.572Z << [FTP Session 15 100.x.x.x] 220-FileZilla Server 1.7.3 2023-10-02T16:00:23.572Z << [FTP Session 15 100.x.x.x] 220 Please visit https://filezilla-project.org/ 2023-10-02T16:00:23.650Z >> [FTP Session 15 100.x.x.x] USER myuser 2023-10-02T16:00:23.650Z << [FTP Session 15 100.x.x.x] 331 Please, specify the password. 2023-10-02T16:00:23.728Z >> [FTP Session 15 100.x.x.x] PASS **** 2023-10-02T16:00:23.806Z << [FTP Session 15 100.x.x.x myuser] 230 Login successful. 2023-10-02T16:00:23.900Z >> [FTP Session 15 100.x.x.x myuser] PWD 2023-10-02T16:00:23.900Z << [FTP Session 15 100.x.x.x myuser] 257 "/" is current directory. 2023-10-02T16:00:23.994Z >> [FTP Session 15 100.x.x.x myuser] CWD somedir 2023-10-02T16:00:23.994Z << [FTP Session 15 100.x.x.x myuser] 250 CWD command successful 2023-10-02T16:00:24.088Z >> [FTP Session 15 100.x.x.x myuser] PASV 2023-10-02T16:00:24.088Z << [FTP Session 15 100.x.x.x myuser] 227 Entering Passive Mode (1,2,3,4,195,234) 2023-10-02T16:00:24.228Z !! [FTP Session 15 100.x.x.x myuser] Data peer IP [9.8.7.6] differs from control peer IP [100.x.x.x]: this shouldn't happen, aborting the data connection. 2023-10-02T16:00:24.244Z >> [FTP Session 15 100.x.x.x myuser] TYPE I 2023-10-02T16:00:24.244Z << [FTP Session 15 100.x.x.x myuser] 200 Type set to I 2023-10-02T16:00:24.322Z >> [FTP Session 15 100.x.x.x myuser] SIZE somefile.ext 2023-10-02T16:00:24.322Z << [FTP Session 15 100.x.x.x myuser] 213 2015 2023-10-02T16:00:24.385Z >> [FTP Session 15 100.x.x.x myuser] RETR somefile.ext 2023-10-02T16:00:24.385Z << [FTP Session 15 100.x.x.x myuser] 425 Unable to build data connection: EINVAL - Invalid argument passed 2023-10-02T16:00:24.463Z >> [FTP Session 15 100.x.x.x myuser] QUIT 2023-10-02T16:00:24.463Z << [FTP Session 15 100.x.x.x myuser] 221 Goodbye.
Change History (12)
comment:1 by , 15 months ago
Description: | modified (diff) |
---|
comment:2 by , 15 months ago
Description: | modified (diff) |
---|
comment:3 by , 15 months ago
Description: | modified (diff) |
---|
comment:4 by , 15 months ago
Description: | modified (diff) |
---|
follow-up: 7 comment:5 by , 15 months ago
Status: | new → moreinfo |
---|
comment:6 by , 15 months ago
Status: | moreinfo → new |
---|
This is completely unrelated to the address type.
When the "Use the default host for local connections" option is enabled, the behavior of FZS that I've witnessed is that when the client IP is in private address space (10, 172, 192.168), the passive 227 response uses the server's IP. When the client IP is anything else, the passive 227 response uses the IP of the resolved hostname provided in the config. Unfortunately, this breaks passive connections where the client IP is in the CGNAT address space.
To mitigate data connection stealing attacks (to fully prevent this, TLS session resumption must be used), FileZilla Server requires that the peer IP address of the control connection is the very same as the peer connection of the data connection.
Our IoT devices only support unencrypted FTP unfortunately.
How did you manage to have a public sever hosted behind a CGNAT in the first place?
The IoT device is on CGNAT and is connected over a VPN tunnel to us. The network for the IoT device also has direct Internet access (through a NAT router). In case the VPN tunnel goes down, it is supposed to use DIA as backup.
Your terminology is very confusing, for example what is a "Client Public Outbound NAT IP" even supposed to be? It's either a public IP, or a private NAT IP. It cannot be both.
Sorry, it's the terminology we use frequently. It means the public IP used by the NAT device for outgoing connections from internal devices. So, if the internal device was 100.64.1.2 and trying to hit 8.8.8.8, the NAT router would elect to NAT using 3.4.5.6 as the source IP. So 3.4.5.6 would be the Client Public Outbound NAT IP.
Please describe the network topology in more detail.
We have cellular-connected IoT devices that reside on a partner-managed network and are assigned both 10.x and 100.x IPs. That partner-managed network has direct Internet access (DIA) as well as a VPN tunnel to our internal network. Communication over the VPN tunnel is the preferred communication path to talk to our servers, but DIA is available as a backup communication method.
The IoT devices with 10.x IPs don't have a problem using passive FTP, but the ones with 100.x IPs are having the passive FTP problem.
Any particular reason why you are not simply using IPv6 to avoid having to deal with all the NAT madness?
We don't have control over the IP space for the client devices as we're using a partner for the cellular-connected IoT devices.
follow-up: 8 comment:7 by , 14 months ago
Replying to Tim Kosse:
Did my reply answer all your questions or do you still need more information?
comment:8 by , 13 months ago
Replying to John Hossbach:
Replying to Tim Kosse:
Did my reply answer all your questions or do you still need more information?
Maybe I missed something? This still seems like a bug to me that needs to be fixed. CGNAT should be included in the range to prevent bad information from being sent to the client.
follow-up: 10 comment:9 by , 12 months ago
Just checking in, in case you missed my last comment. I appreciate your help with looking into this.
comment:10 by , 11 months ago
Replying to John Hossbach:
Just checking in, in case you missed my last comment. I appreciate your help with looking into this.
Following up after the holiday to see what is needed to move this along. This is a big impact for us and we don't have the ability to enable TLS.
follow-up: 12 comment:11 by , 11 months ago
This is my understanding of the issue:
- The client connects to address A to establish the control connection
- The server sees the client coming from address B
- The server advertises address A in the PASV reply
- The server expects the data connection to also come from address B
- For unknown reasons, the data connection appears to originate from some other address C.
In this scenario it does not matter the slightest whether addresses A/B/C are considered Internet routable or not.
comment:12 by , 11 months ago
Replying to Tim Kosse:
This is my understanding of the issue:
- The client connects to address A to establish the control connection
- The server sees the client coming from address B
- The server advertises address A in the PASV reply
- The server expects the data connection to also come from address B
- For unknown reasons, the data connection appears to originate from some other address C.
In this scenario it does not matter the slightest whether addresses A/B/C are considered Internet routable or not.
You are absolutely correct given the scenario you painted here. However, FileZilla Server provides an option to modify this behavior: Settings > Protocols settings > FTP and FTP over TLS (FTPS) > Passive Mode > Use the following host (leave empty to keep the default one).
This option changes your step 3.
In addition, there is an override for this option provided as well: Settings > Protocols settings > FTP and FTP over TLS (FTPS) > Passive Mode > Use the default host for local connections.
The idea being that if a client with an IP in private IP space (non-routable) connects to the server, FileZella will ignore the provided hostname when "Use the default host for local connections" is checked.
Extending that logic, FileZilla also needs to ignore the provided hostname when the client's IP is in the CGNAT IP space (also non-routable). This is the part that's missing and is the bug I'm reporting.
Example configuration:
Server IP: 10.1.2.3
Use the following host (leave empty to keep the default one): externalftp.example.com (1.2.3.4)
Use the default host for local connections: Enabled
Current behavior:
- The client connects to 10.1.2.3 to establish the control connection
- The server sees the client coming from 100.64.1.2
- The server advertises 1.2.3.4 in the PASV reply; Server chose 1.2.3.4 because 100.64.1.2 isn't considered a "local connection"
- The server expects the data connection to also come from 100.64.1.2
Problem: Client is unable to establish PASV data connection.
Desired behavior:
- The client connects to 10.1.2.3 to establish the control connection
- The server sees the client coming from 100.64.1.2
- The server advertises 10.1.2.3 in the PASV reply; Server should choose default host because 100.64.0.0/10 should be included and treated as a "local connection"
- The server expects the data connection to also come from 100.64.1.2
This is completely unrelated to the address type.
To mitigate data connection stealing attacks (to fully prevent this, TLS session resumption must be used), FileZilla Server requires that the peer IP address of the control connection is the very same as the peer connection of the data connection.
How did you manage to have a public sever hosted behind a CGNAT in the first place?
Your terminology is very confusing, for example what is a "Client Public Outbound NAT IP" even supposed to be? It's either a public IP, or a private NAT IP. It cannot be both.
Please describe the network topology in more detail.
Any particular reason why you are not simply using IPv6 to avoid having to deal with all the NAT madness?