@JohnRotenstein is absolutely right if you can use Passive FTP. If, like me, you are stuck with a client who insists that you are using Active FTP, because their FTP site with which they want to connect has been working since 1990, and now its change is completely unreasonable, then read on.
AWS NAT servers do not support a machine on a private subnet that connects using Active FTP. Full stop. If you ask me, this is a mistake, but if you ask for AWS support, they will say that this is an unsupported feature.
The solution we finally came up with (and it works):
- Add an Elastic Network Interface (ENI) to your public EC2 instance on your private subnet
- So, now your EC2 instance has 2 network adapters, 2 internal IP addresses, etc.
- Let This New ENI Use Your Public ENI
- Attach a dedicated elastic IP to your new public ENI
- Suppose you received 54.54.54.54 and the new public ENI IP address is 10.1.1.10.
Add a route to the network configuration of your operating system to use only the new public ENI
In the windows, the command will look like this, assuming that the villainous active ftp server you are trying to connect to is in 8.1.1.1:
route add 8.1.1.1 mask 255.255.255.254 10.1.1.1 metric 2
This adds a route for all traffic to the FTP server in 8.1.1.1 using the subnet mask 255.255.255.254 (i.e. this IP address and only this IP address), you should go to the Internet gateway 10.1.1.1 using ethernet adapter 2 (your second network adapter)
Was expected? Yes, me too, but now the hard part is coming. The OS does not know the public IP address for the public EIN. Therefore, you need to teach your FTP client to send the PORT command with an open IP address. For example, if you use CURL, use the -ftp-port command as follows:
curl -v --ftp-port 54.54.54.54 ftp://8.1.1.1 --user myusername:mypass
And voila! Now you can connect to an active FTP site with a nightmare from an EC2 computer, which (almost completely) is on a private subnet.
source share