Setting Up FTPS (FTP with SSL) on Windows Server 2012 on Windows Azure

I had a little bit of a struggle getting FTPS to connect and list the directory when logged in.  I was getting errors 550, connect aborted by remote server on FileZille, error 162 PORT FAILED on Transmit.  The regular FTP, port 21, was working fine, but moving to a more secure method, FTPS, that uses random passive ports, caused me a bunch of headache.

Although I won’t go into setting up FTP users for your IIS FTP site, or creating the SSL certificate, the other steps here will allow you to successfully use FTPS on your Windows Server virtual machine hosted on Windows Azure.  If you want instructions for the first 2 steps, leave a commend and I can create additional blog posts!

The FTP “site” should be created at this point. Go into IIS and at the server level, click on FTP Firewall Support. Choose a range, I chose 5000-5100, that’s 101 passive connections, more than enough. Whatever range you choose, you’ll need to remember because you’ll need that when we set firewall rules. For Windows Azure (and maybe other cloud providers) specifically, you need to put the public IP address of your server in the External IP Address of Firewall1! This is what was causing me so many problems! Since Windows Azure has its own firewall (separate from the built-in VM firewall)…so does AWS…you need to let IIS know.

For your Windows Firewall, go set an inbound AND outbound rule (not sure if you need both) to the port range 5000-5100 and to allow. I called it “FTPS Passive”.

Now, specific to Windows Azure, we need to set the passive port range on the Azure firewall…however you can’t set a range, you have to set one record for each port. That would take a while manually, so let’s use a Powershell script. First, we’ll need to get the Windows Azure Powershell commandlets. This ultimately opened in the web installer thing. And this link might not be the right one because after it installed, I also installed the Windows Azure Powershell from the web installer.
https://go.microsoft.com/?linkid=9828653&clcid=0x409

Now in Powershell, run this so we know our ServiceName and Name when we run this script for adding records to the firewall.

Get-AzureVM

This lists the ServiceName and Name we’ll need.

Run this in Powershell. A web browser will open where you can download your .publishsettings file for the virtual machine. I shortened the name to “credentials.publishsettings” and saved it to my desktop.

Get-AzurePublishSettingsFile

Now when you run this in Powershell, update your file location and name

Import-AzurePublishSettingsFile C:\Users\ClientCenter\Desktop\credentials.publishsettings
$VM = Get-AzureVM -ServiceName "fsiclientcenter2" -Name "windows2012r2"
for ($Port = 5000; $Port -le 5100; $Port++) { $VM = $VM | Add-AzureEndpoint -Name "FTP-Data-$Port" -Protocol 'TCP' -LocalPort $Port -PublicPort $Port } $VM | Update-AzureVM

I put the for loop in one line so it copied nicely in RDP…with multi-line I was having trouble. Anyway, you’ll see the port range here again. Also, the double quotes around “FTP-Data-$Port” are necessary to have the script replace $Port with the value of the variable.

Also, add port 20 and 21, the FTP data and FTP ports. You can do that in Powershell, or in the Azure console, under Endpoints.

$VM = $VM | Add-AzureEndpoint -Name "FTP-Data" -Protocol 'TCP' -LocalPort 20 -PublicPort 20
$VM = $VM | Add-AzureEndpoint -Name "FTP" -Protocol 'TCP' -LocalPort 21 -PublicPort 21
$VM | Update-AzureVM

Lastly, in the command window (not Powershell), run this:

netsh advfirewall set global StatefulFtp enable
net stop ftpsvc && net start ftpsvc