Round Robin to 2 Proxy's and Leastconn to 2 FTP Servers possible?

Hi all,

We are trying to create a HA FTP setup with one Cisco ASA 5516 Firewall, two HA Proxy’s and two FTP servers.
The thought was to let incoming messages on the Cisco ASA be forwarded (Round Robin Style) to one of the two HA Proxy servers and after that the Ha Proxy server would forward it (Leastconn style) to one of the two FTP servers.

This does look like it could work except for one point. If John Doe is creating a FTP connection it might go to ASA>Proxy02>FTP01 and after sending files while still connected the traffic might go with another route like ASA>Proxy01>FTP02. I don’t know if this could really happen and that is my real question. Could it reroute the traffic to the other FTP server? If this happens it will lose it’s connections which is what I’m trying to prevent.

The setup that I would like to implement has been attached to this post.

Regards,

Nathan

This is difficult, for multiple reasons.

Proxying FTP is the first difficulty. You’d have to proxy a range of PASV ports, and make sure the backend can exit through the ASA for active FTP traffic, using the same external IP address as incoming FTP control data on port 21.

The second difficulty is the fact that sticky sessions really only work with HTTP (to insert a cookie), so here we would have to use source IP hashing, not roundrobin or leastconn.

Source IP hashing will fail unless both haproxy instance have exactly the same configuration (server and server weight), due to the round robin load balancing on the ASA.

Then, very likely the ASA will get confused with this configuration; I’d suggest to disable FTP connection helpers and configure the incoming ports statically (port 21 + the PASV range of ports).

This is not a simple configuration, you have to understand the dirty little details of FTP very well.

Hi Lukas,

Thanks for your reply.

I’ll put some research into this “Source IP hashing” that you suggested.
The big problem that I’m thinking of is that when in the middle of a FTP session the session switches to the other FTP server which gives me a broken sessions as the other FTP server doesn’t know if that sessions has used it’s FTP credentials or not.

I’m going to try it and if it fails then I’ll make the second HA Proxy a cold standby proxy.

Regards,

Nathan

Its more about the PASV data channel which needs to be opened to the same FTP server than the control channel (on port 21) was.

Well I do already bind to my self defined passive ports as you can see in the config below that now works for me when I use one proxy server instead of two.
But if I understand you correctly than I should look for a way to route the traffic via the passive ports origin FTP server.

#---------------------------------------------------------------------
# DEFAULTS CONFIG
#---------------------------------------------------------------------
defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http

#---------------------------------------------------------------------
# HAPROXY DASHBOARD CONFIG
#---------------------------------------------------------------------
listen  stats
        bind            192.168.1.1:1936
        mode            http
        log             global

        maxconn 10

        clitimeout      100s
        srvtimeout      100s
        contimeout      100s
        timeout queue   100s

        stats enable
        stats hide-version
        stats refresh 30s
        stats show-node
        stats auth admin:password
        stats uri  /haproxy?stats

#---------------------------------------------------------------------
# POOL CONFIG
#---------------------------------------------------------------------
listen ftp-pool
        bind :21
        bind :40000-40049
        mode tcp
        maxconn 2000
        option tcplog
        option tcp-check
        balance roundrobin
        server ftp01 192.168.1.11 check port 21
        server ftp02 192.168.1.12 check port 21

listen sftp-pool
        bind :22
        mode tcp
        maxconn 2000
        option tcplog
        option tcp-check
        balance roundrobin
        server ftp01 192.168.1.11:22 check
        server ftp02 192.168.1.12:22 check

Your configuration is pretty much what I would’ve suggested, expect for the load balancing alghoritm:

Remove roundrobin, and configure source IP hashing:

# balance roundrobin
balance source
1 Like

Hi Lukas,

It seems to work although I’m getting the below message:

227 Entering Passive Mode (192,168,1,11,195,105)
Server sent passive reply with unroutable address. Using server address instead.

The FTP server seems to send it’s own internal ip instead of it’s external ip.

When I looked at the documentation for the balance source it says:

This algorithm hashes the source IP and divides it by the total weight of running servers. The same client IP always reaches the same server as long as no server goes down or up. If the hash result changes due to the changing number of running servers, clients are directed to a different server. This algorithm is generally used in TCP mode where cookies cannot be inserted. It’s also static by default.

The default weight of each server is 1 if I’m not mistaken so does this mean it will send every client with a new source ip in a round-robin like way, but will stick to the same ftp server if it has a known source ip?

Regards,

Nathan

Correct, you need to configure the FTP server to send the public IP instead.

For Filezilla Server, see:
https://wiki.filezilla-project.org/Network_Configuration#Passive_mode_2

You can also use ftptest.net to test your configuration.

Not round-robin, no. It is a hash, so its a mathematical calculation (and also stateless). That means haproxy does not remember the source IP, instead the mathematical calculation is deterministic, so one source IP always hits the same backend server because the result of the mathematical calculation is always the same.