PART 2.
NAT, much like the city of Phoenix, is a monument to man's arrogance. Fuck NAT and fuck FTP. If your FTP server is listening directly on a public IP address hooked up directly to a proper router, then none of this applies. If you're anything like me, the last company I worked for (a small startup), or my current company (many many thousands of employees making software you know and may or may not hate, making many billions of dollars a year), then the majority of your servers are living in RFC1918 space. Traffic from the internet is making it to them via NAT (or NAT with extra steps, i.e. L4 load balancers).
A request comes in for $PUBLIC_IP TCP port 21 and is forwarded to your failure of a boxen at 10.0.54.187. Your FTP server is a big stupid idiot and doesn't know this. It thinks that it's king shit and has its own public IP address. Therefore, when it's deciding what ADDR:PORT it's going to tell the stupid FTP client to connect to, it just looks at one of the adapters on the box and says "oh, I'll tell this client on the internet to connect to 10.0.54.187:44007" and then I fucking cry. The FTP client is an idiot, but the IP stack on the client's home/business router is not and says "oh, that's an address living in RFC1918 space, I shouldn't send that out over the internet" and they don't get the results of their LIST.
So, how do you fix this? Well, you fix it by not using FTP. Use SFTP USE SFTP USE SFTP FOR GOD'S SAKE. But since this world is a shit fucking place, you have two options. The best option is to configure your FTP server to lie about its IP address. Rather than being honest about what a fool it is, you can tell it to send your public IP address to the client rather than the network adapter IP address. Does your public IP address change? Fuck you, you get to write a daemon that checks for that shit, rewrites your FTP server config, and HUPs the bastard (or SIGTERMs it if your server sucks and can't do a live config reload).
Let's say that you don't want to do that. Let's say you work at a small company with a small business internet plan that gives you static IPs but a shitty modem. Let's say that you don't know what FTP is or how it works and your boss told you to get it set up ASAP and it's not working (because the client over in Bendoverville Arkansas is being told to connect to a 10.x.x.x address) and it surely must be your ISP's fault. So you call up Comcast Business/AT&T/Verizon/Whoeverthefuck and you complain at their technicians for hours and hours, and eventually you get connected to a human that knows what the problem is and tells you how to configure your stupid FTP server to lie like a little sinner. The big telco megacorps don't like that. They don't want to waste all those hours, and they don't want to hire too many people who can figure that shit out because it's expensive. You wanna know what those fucking asshole companies did?
Continued in part 3.
PART 3.
They made their STUPID MODEMS FUCK WITH THE FTP PACKETS. I have personally experienced this with Comcast Business. The stupid piece of shit DOCSIS modem they provide intercepts the FTP packet from your server saying "oh, connect to this address: x.x.x.x:44010" and they rewrite the fucking address to the public IP. There is no way to turn just this horse piss off. Now, for average business customers, this probably saved Comcast a bunch of money in support calls. However, if you're using the so-called bridge mode on that degenerate piece of shit-wrapped-silicon (where rather than allowing the modem to give you a DHCP address, you just configure your system to have one of the addresses in the /29 space and the modem detects that and says oh okay don't NAT traffic when it's going to this address, just rewrite the MAC and shunt it over the right interface), then something funny happens. The modem still rewrites the contents of the packet, but it uses the wrong fucking IP address! Because the public IP that your server is running on is no longer available to the modem, the modem just chooses another fucking address. Then, the client tries to connect to 1.2.3.5 instead of 1.2.3.4 where your server is listening, the modem says "hey I'm 1.2.3.5 and you can fuck off, I'm dropping your SYN for port 44010", and I get an angry call from the client asking why they can't download their files using this worthless protocol. I remember having a conversation like this:
Me: "Just use SFTP on port 22!"
Client: "No! FTP is faster/more secure/good enough for my grandfather good enough for me/corporate won't allow port 22."
Me: "Comcast is fucking me right now. What if we lied and served SFTP over port 21?"
# we try it
Client: "It's not working! I can't even connect!"
I couldn't connect either. I couldn't connect to anything. Trying to do SFTP over port 21 caused the stupid fucking modem to CRASH.
Are you starting to see what the problem is? It's like Microsoft preserving bugs in Windows APIs so that shitty software doesn't break, and then they end up doing crazy gymnastics to accomodate old shit like the Windows 8 -> Windows 10 thing where they couldn't use "Windows 9" because that would confuse software into thinking it was running "Windows 95" or "Windows 98". FTP has some bugfuck crazy design decisions that we've collectively decided to just "work around," and it leads to fucking gymnastics.
Speaking of bugfuck crazy design decisions, FTP's default file transfer mode intentionally mangles data!
Continued in part 4.