I've tried the suggestions on a number of sites (http://blogs.thesitedoctor.co.uk/tim/Trackback.aspx?guid=e81a4682-0851-490b-a3d2-adf254a701e7 and http://www.itq.nl/blogs/post/Walkthrough-Hosting-FTP-on-IIS-75-in-Windows-Azure-VM.aspx, and Passive FTP on Windows Azure Virtual Machine) and it won't work.
FTP active and passive both work from the VM to itself. FTP active works from the outside world. FTP passive fails with the server responding back with "550 The network connection was aborted by the local system" (this message returns on the control channel/port 21 immediately after the SYN packet is sent to one of the dynamic ports).
What I've done:
1) Configured IIS on the VM with an FTP site
2) Set the FTP firewall support IP address to the public IP address of the Azure VM instance (for what it's worth, I've also tried with this field empty and tried with the private IP address, none of them work)
3) Set up endpoints for FTP control (TCP/21), FTP data (TCP/20), and FTP dynamic ports (7000 through 7003)
4) Used appcmd.exe to set the port range for FTP (i.e. %windir%\system32\inetsrv\appcmd set config /section:system.ftpServer/firewallSupport /lowDataChannelPort:7000 /highDataChannelPort:7003)
5) Restarted the FTP server (net stop ftpsvc and net start ftpsvc)
6) Tried with the firewall both enabled and disabled (netsh advfirewall set global StatefulFtp enable)
Any ideas? I've verified with Wireshark that the client is trying to use the dynamic port, and that the dynamic ports are being used when I try locally.