FTP: Why use IP of PASV response at all? - ftp

When sending the FTP command "PASV", the FTP server responds with information on which host and port a data connection can be established.
This host information can be problematic if there is a NAT involved. Some clients resolve this by comparing the IP of the proposed data connection host with the one from the control connection: If the one proposed after PASV is a local one while the control connection is not using a local one, only the ports given by the PASV response are used while using the IP of the host connection.
As an example, see the Apache Commons implementation: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/ftp/FTPClient.java?revision=1788985&view=markup#l3876
My question is now: Why use the host of the PASV answer at all? Why not just always only use the ports of the PASV answer but use the host of the control connection? As far as I know this is how it's done with IPv6 but I never see it with IPv4. Why?

At the time FTP was designed there were enough IP addresses and NAT was not a thing to be considered. But FTP was designed to support a use case where a client initiated a transfer between two different systems - see figure 2 in RFC 959 or read about File eXchange Protocol for details. And for this use case it was necessary that the IP addresses in the PORT or PASV command could be different from the (single) server resp. client IP.
As far as I know this is how it's done with IPv6 but I never see it with IPv4.
You are probably referring to the EPRT and EPSV commands which only take a port number and no IP address. While these commands were introduced since the original PORT and PASV commands did not support IPv4 these command can be used for both IPv6 and IPv4 and several clients use these for IPv4 too, thereby avoiding the problems with the wrong IP address in PORT/PASV.

Related

Same host UDP packet correlation in Go

In Go one can send UDP packets using net.Addr interface to specify the target endpoint. Some special addresses, e.g. :8080 and 0.0.0.0, sends packets using local loopback interface. When received, still on the same host, the message's net.Addr shows [::1]:8080 as source. What is the the easiest way to determine that the packet was sent and received by the same host?
Here's an example in the Go Playground. It shows 0.0.0.0:8080 (ipv4) instead of [::1]:8080.
I ended up using net.Dial("udp", addr) and eminently closing the connection. Dial also resolves hostnames, which I also needed.
Would be nice to avoid creating a socket, but Dial works for now.
:8080 is not an address, it is a port number, typically used when testing your own http websites on Windows because on Windows you cannot easily use port 80, the actual http port.
This will only use the loopback interface if you use localhost as the IP address.
The localhost address for IPv4 is 127.0.0.1 and for IPv6 it is ::1. The address 0.0.0.0 is usually used as a placeholder address to indicate, for example, listening on all IP addresses, see this question.
As mentioned in the comment, you can use net.IP.Equal to check if your peer is localhost. Just compare your address in question to 127.0.0.1 or to ::1, the net.IP.Equal function considers them equal.

Failed to FTP upload using Windows ftp.exe: "PORT IP is not same as nnn.nnn.nnn.nnn"

I am using a call to ftp.exe to upload file to a FTP Server.
This program is running since many years and uploads to number of servers, so far without problems.
After one of the receiver servers has been updated, uploads are no longer possible.
This is the command sequence:
open ftp.xxx.de
<user>
<pw>
>230 User logged in, proceed
cd upload
bin
put <filename>
and in response to this the server replies:
501 PORT IP is not the same as 10.100.244.5
150 File Status okay, about to open Connection
That is it, after this the connection is stuck and gets closed after a certain timeout period.
Funny enough, a google search for "PORT IP is not the same as" return exactly one result, which explains that the IP seen by the server is different from the one expected.
Also, when using WinSCP, FileZilla or other FTP utility programs, the connection has no problem and does transfer files just fine.
So, why does this appear and how to solve it?
The ftp.exe uses an old-fashioned active mode command PORT, which requires the client to specify its IP address to which the FTP servers needs to connect back to open a data transfer connection.
If your are behind a firewall or a NAT, the client may not know its external IP address and uses its local network address. This causes troubles. Either the server fails to connect back as it obviously cannot connect to the client's local network. Or the server rejects the PORT command straight away, if the specified IP address does not match the IP address, from which the FTP client connects to the server. This is a security measure as the difference may indicate a man-in-the-middle attack. Your server does the validation. Some servers might be configured to ignore the IP address specified in the PORT command and connect to a known IP address of the client.
Another way to solve this is, if the firewall/NAT can inspect the FTP traffic and seamlessly modify the IP address in the PORT command. This is obviously not happening.
You do not get the problem with WinSCP or FileZilla, as these clients default to the passive FTP mode, which does not have the problem. Also in the active mode these clients can be configured to use the external IP address. FileZilla also supports the modern EPRT command, that does not need to specify the IP address at all (the server uses the known IP address of the client).
See my article about active/passive FTP mode for details.
I do not think there's any way to make it working with the Windows ftp.exe. It neither supports the passive mode, nor can be configured to use the external IP address, nor supports the EPRT command.
So unless you can configure the FTP server not to do the check and connect to the known IP address of the client or configure your firewall/NAT to modify the IP address in the PORT command, you have to use another FTP client.
As you know that WinSCP works, see the guide for converting the Windows ftp.exe script to WinSCP script.
(I'm the author of WinSCP)

FTPS | connection closes abruptly after entering passive nide

I would like to connect to an FTP destination and write a file to it.
FTP abruptly closes after entering PASV mode. There is nothing wrong with the FTP server setting as such. I am not really sure what I can fix on the FTP server to fix this problem. Any ideas?
Q: Is the IP address in the client message the same as the servers IP the client accessed or is it the non-public IP address of the server? --- A: It is the non-public IP that the client gets.
This sounds like a FTP server behind a NAT which provides the internal private IP address in the reply for the PASV command. Since the client is probably not in the same private network this private address is not reachable by the client.
Thus the client gets the following error:
"java.net.SocketPermission" "10.xx.xxx.xxx:123456" "connect,resolve"
FTP where one side is behind NAT conflicts with the general architecture of the FTP protocol, that is dynamically created data channels where the endpoints get announced within the control connection. If only one of the peers is behind NAT you can usually work around it by using either passive mode (client behind NAT) or active mode (server behind NAT). If both peers behind NAT or if you want to use passive/active mode in an unsuitable scenario it gets more complicated and you usually need either helpers on the router/firewall or specific configurations for the client/server and lots of ugly port forwarding.

What happens when an ipv6 client connects to an ipv4 host

This is a noob question, but networking isn't my forte. For example if I have an ipv4 server and an ipv6 client connects, what would their ip show as? Also if I wanted to setup a socket connection for example, does my server have to be ipv6 too, or does the code just need to be able to handle it.
I have researched how code handling works, but nothing says if the server has to be ipv6, itself.
IPv4 and IPv6 are not directly compatible. In most installations, a client will have both an IPv4 and an IPv6 address, and will use whichever one is appropriate to connect to a server. That is, they will use their IPv4 address to connect to an IPv4 server, IPv6 to connect to an IPv6 server, and will preferentially choose one of the two — usually IPv6 — if a server supports both.
IPv4-only clients cannot connect to IPv6 servers. Unless you intend to provide a service to IPv6 users only, you will need to provide your service on IPv4, or on both protocols, to support IPv4 clients.
IPv4 and IPv6 are separate incompatible protocols. An IPv6 client cannot connect directly to a server running only IPv4.
A connection is possible if an intervening router or switch maps from the IPv6 protocol to IPv4, or if the server runs both protocols. However, the IPv6 client is still maintaining an IPv6 connection and is unaware of any IPv4 connection.

Viewing incoming ping on windows server

I'm trying to see the results of an incoming ping on a target windows machine. This is needed to verify that the ping, which is running in a background thread, is being sent from the originator.
I have tried netstat to no avail. Are there any other approaches I could try?
Thanks.
Ping is an ICMP packet and doesn't create a TCP connection (hence you won't see it in netstat). On Linux, I'd add a rule to the firewall.
The most simple solution for your case might be to open a connection and close it. That will add it to the output of netstat with WAIT_CLOSE.
As Aaron Digulla already noted, ping is ICMP. This also means the originator even less trustable then with TCP; there's no SYN/ACK handshake. You just get an IP packet on your host, and you have to trust the header fields. Anyone can spoof those header fields, with almost no restrictions (It might be a bit challenging to get an IP claiming to come from 127.0.0.1 past a router)
Therefore, ICMP is not suitabel for verification tasks. You need a challenge/response protocol. TCP works reasoanbly well as long as you can trust the network but not necessarily all hosts on it (a reasonable assumption for the Internet. Not strong enough for financial transactions, which is why they use SSL)

Resources