A customer recently asked if the Azure Load Balancer (ALB) allowed for FTP traffic? The answer is, yes it can be done! But to make it possible, I had to use F5 BIG-IP and it made a nice use case to demonstrate some typical cloud limitations, and how BIG-IP can help.
Customer uses a commmercial, enterprise-level FTP server on-prem today. They want to "lift-n-shift" this FTP server to Azure. Today, they support both Active and Passive FTP connections, and their Passive FTP data ports are locked down to a range of 5000 ports. That's a lot, but not uncommon on-premises.
Some initial chellenges to overcome:
Tiered architecture. They intend to have an internet-facing firewall in front of their BIG-IP tier. This is due to legacy on-prem architectures and a desire to replicate for consistency in Azure. So inbound FTP client traffic will traverse their FW, and then needs to be served via Azure LB.
Ports. If you've ever worked with FTP, you'll know that FTP uses a control channel (usually port 21) and data channels (usually a random high port and sometimes locked down to a range).
Active FTP requires the server to connect back to the client. Then the client communicates with server on (usually) destination port 20.
Passive FTP (more common today) requires the client to make these connections to the server, and port ranges vary.
ALB rules allow for a single port each. With a range of 5000 ports, opening ports in separate ALB rules would break the (current) Azure limit of 1500.
ALB limitations. While an internal ALB can have a rule that listens on all ports, an external ALB cannot. They intend to have an external ALB in front of firewall appliances, and their clients will access the FTP server from Internet.
Legacy IT. They cannot easily reduce this port range to something manageable, under Azure's limit. There's legacy reasons for this.
High Availability requirement. They have load-balanced Active/Active FTP servers on-prem and would like to continue this in Azure with Active/Active FTP servers.
Click here to see the GitHub repo and deploy to Azure:
Let's analyze this!
As part of the design for this demo, I drew out the diagram below.
There are some simplifications to the diagram above, but in short, the intent is to show:
An external tier of firewall appliances. In my demo I have made these F5 appliances, but the customer (or you) may choose to use a 3rd party firewall vendor for their external tier.
An internal tier of BIG-IP devices. These devices secure and proxy FTP traffic with an FTP profile.
An application tier. I have pictured only a single FTP app server for this demo, but obviously you can put many servers behind F5 BIG-IP devices. Making the last layer Active/Active is somewhat arbitrary, as is multiple tiers of the app itself (like adding a database). I used vsftp on Linux, not the commercial product my customer uses.
Here's how we overcome the challenges in the problem statement above.
The external tier shown just has FastL4 Virtual Servers that accept traffic and pass it through on TCP ports 20, 21, 22, 80, 443, and 5000-5003.
These are just providing traffic to be proxied on Layer 4. There is no app-layer inspection.
The internal tier of BIG-IP devices uses an LTM FTP profile.
It uses an iRule which I wrote based off an example here. This allows us to re-write the data ports used from the 5000 ports used to a more manageable number.
ALB rules are set up, as are Network Security Group (NSG) rules, to allow our defined port ranges. This meets our requirements for ALB's and overcomes port-range-related challenges.
High Availability is easily gained by creating additional app servers and load-balancing within F5. F5 itself has HA via the Device Service Cluster.
The internal tier also proxy ports 22 (SSH) and 80 and 443 (HTTP and HTTPS) for the sake of a demo web app. These aren't needed for FTP to work, but are nice to have set up for demo purposes.
In my demo I reduce the port range to 4 data ports (tcp/5000-5003) but for busier sites you may want more. Just stay under the limit of 1500.
Real world scenarios
FYI, I started creating this demo by starting with this F5 Networks demo template here. If I was to do this again, I would use linked templates, instead of 1 large template, but this demo works.
Remember a few points in your production environment:
Never expose your management interfaces to the public Internet. This demo is intended to show the mgmt interface for demo purposes.
Use your own SSL certificates that are valid and signed by a public CA.
For deploying cloud resources
I have created one large ARM template, but if I was to do this again, I would make child templates
Alternatively, I would use a deployment tool like Ansible or Terraform to deploy my cloud resources, and then configure them
This demo requires EVAL keys, and don't forget to revoke your eval keys before blowing away the environment. If you don't, you'll need to call F5 Support to have them release your key.
In this demo, you'll need to revoke the internal tier devices first, and then external tier. This is due to the default routes and inline devices.
Why do you need F5?
What's the difference between a basic load balancer, and a full proxy? One reason you use F5 in this scenario is for the enterprise-level features available. For example, when traffic traverses the BIG-IP in this scenario, we aren't just performing load-balancing. We're re-writing ports, dynamically opening new ports when required, optionally performing security, and a host of other app services are available. I'm often asked to differentiate F5 from basic load balancing services, and this is a good example of functionality you just cannot get from a basic loadbalancer.
I hope this demo environment helps you see that you CAN run FTP servers in Azure, via an Azure Load Balancer, if you use BIG-IP and configure your application services to provide security, availability, and performance!