ftp access from AWS VPC private subnet behind a NAT instance


I have created a VPC with public and private subnets on AWS. All app servers are in private subnets and all outbound requests have to be through an internet-facing NAT instance.

At the moment, our project requires the app servers to access a ftp server provided by a service provider.

I have tried several ways to manage that, but all no luck. What I have done was to open a port range, let’s say (40000 – 60000) on both NAT and APP security groups, also standard ftp ports 20 – 21 as well.

The user authentication can be passed, but I could not list contents from app servers.

I am able to access the ftp server from NAT, not problem at all.

So what should I do to make it work?


@JohnRotenstein is absolutely correct that you should use Passive FTP if you can. If, like me, you’re stuck with a client who insists that you use Active FTP because their FTP site that they want you to connect to has been running since 1990 and changing it now is completely unreasonable, then read on.

AWS’s NAT servers don’t support a machine in a private subnet connecting using Active FTP. Full stop. If you ask me, it’s a bug, but if you ask AWS support they say it’s an unsupported feature.

The solution we finally came up with (and it works) is to:

  • Add an Elastic Network Interface (ENI) in a public subnet on to your EC2 instance in the private subnet
    • So now your EC2 instance has 2 network adapters, 2 internal IPs, etc.
    • Let’s call this new ENI your “public ENI”
  • Attach a dedicated elastic IP to your new public ENI
    • Let’s assume you get and the new public ENI’s internal IP address is
  • Add a route in your operating system’s networking configuration to only use the new public ENI
    • In windows, the command will look like this, assuming the evil active ftp server you’re trying to connect to is at
    • This adds a route for all traffic to the FTP server at using subnet mask (ie. this IP and only this IP) should go to the internet gateway using ethernet adapter 2 (your second NIC)
  • Fed up yet? Yeah, me too, but now comes the hard part. The OS doesn’t know it’s public IP address for the public EIN. So you need to teach your FTP client to send the PORT command with the public IP. For example if using CURL, use the –ftp-port command like so:

And voila! You can now connect to a nightmare active FTP site from an EC2 machine that is (almost entirely) in a private subnet.

Leave a Reply