[SOLVED] HAProxy+Keepalived can't create a FTP session with Virtual IP

Hi all,

FTP doesn’t seem to work when I connect to the Virtual IP (VIP), but when I connect to the local IP of one of the two Proxy’s it works fine.
I see it wants to connect, but when the FTP data port comes up (PASV) it stops.
SFTP works fine without a problem so I think it’s something with the passive FTP ports that aren’t being routed correctly?

Log Filezilla:

Status: Resolving address of lb.example.com
Status: Connecting to 192.168.1.10:21…
Status: Connection established, waiting for welcome message…
Status: Server does not support non-ASCII characters.
Status: Logged in
Status: Retrieving directory listing…
Command: PWD
Response: 257 “/” is current directory.
Command: TYPE I
Response: 200 Type set to I.
Command: PASV
Error: Disconnected from server: ECONNABORTED - Connection aborted
Error: Failed to retrieve directory listing
Status: Disconnected from server
Status: Resolving address of lb.example.com
Status: Connecting to 192.168.1.10:21…
Status: Connection established, waiting for welcome message…
Status: Server does not support non-ASCII characters.
Status: Logged in
Status: Retrieving directory listing…
Command: PWD
Response: 257 “/” is current directory.
Command: TYPE I
Response: 200 Type set to I.
Command: PASV
Error: Disconnected from server: ECONNABORTED - Connection aborted
Error: Failed to retrieve directory listing

My setup:
I have two HAProxy servers with Keepalived on them with a VIP.
Behind the two HAProxy servers are two FTP Servers.

Can anyone help me with finding and if possible solving the problem?

You normally need to do the following:

  1. In your FTP server software restrict the PASV port range to something smaller and more controllable.
  2. Include the PASV port range in your VIP
  3. Set the external IP address so the FTP server knows the address of the HAproxy VIP that clients will connect to.

We cover it in a Blog here: https://www.loadbalancer.org/blog/how-to-load-balance-microsoft-windows-ftp-server-with-haproxy/

Hi AaronWest,

Thank you for your reply.

I tried to add the VIP like you and the blog said, but when I restart the HAProxy server with the new config I get the following error in the HAProxy logging:
Starting proxy ftp-pool: cannot bind socket [192.168.1.10:22]
Before the VIP I used the wildcard * , but when the FTP client connects to the VIP the FTP data part seems to fail.
The reason why it can’t bind to that IP is because the VIP is on the other Proxy server (Proxy01). When it’s down Keepalived will bring the VIP to this Proxy (Proxy02), but HAProxy needs to be restarted at this point which defeats the purpose as this should be a hot-standby server.

The passive port range can’t be smaller then this because we have a lot of sessions coming in.
I’m confused about point 3 with the external IP address. Do I need to define this inside the FTP server?


Current HAProxy config is:
#---------------------------------------------------------------------

GLOBAL CONFIG

#---------------------------------------------------------------------
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    # Default ciphers to use on SSL-enabled listening sockets.
    # For more information, see ciphers(1SSL). This list is from:
    #  https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RS$
    ssl-default-bind-options no-sslv3

#---------------------------------------------------------------------

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.32:1936
mode http
log global

    maxconn 100

    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 192.168.1.10:21 transparent
bind 192.168.1.10:50000-50049 transparent
mode tcp
maxconn 2000
option tcplog
option tcp-check
balance source
hash-type consistent
server ftp01 192.168.1.1 check port 21
server ftp02 192.168.1.2 check port 21

listen sftp-pool
bind 192.168.1.10:22
mode tcp
maxconn 2000
option tcplog
option tcp-check
balance source
hash-type consistent
server ftp01 192.168.1.1:22 check port 22
server ftp02 192.168.1.2:22 check port 22


The keepalived config:
global_defs {
notification_email {
system-engineering-department@example.com
}
notification_email_from haproxy02@example.com
smtp_server 192.168.1.50
smtp_connect_timeout 30
}

vrrp_instance VRRP1 {
state BACKUP

Specify the network interface to which the virtual address is assigned

interface ens160
virtual_router_id 41

Add smtp alert

smtp_alert

Set the value of priority lower on the backup server than on the master server

priority 100
advert_int 1
authentication {
    auth_type PASS
    auth_pass xxxxxxxx
}
virtual_ipaddress {
    192.168.1.10/24
}

}

That’s what the “transparent” declaration on the bind line does in the FTP VIP, it allows you to bind the process to an IP not currently on the box.

1 Like

Ha! I just needed to at the transparent part to the SFTP pool too like you said and now HAProxy is running again. Thanks.
Unfortunately I’m still having the same issue with the FTP data connection. Am I missing something in the config?

Can I check that you did point 3 already?

That part was confusing for me. Where do i set this and do you mean the WAN IP?
We use Serv-U FTP server on Windows and can’t put the external IP address anywhere.

as per ServU KB 1044:

next step is to configure the IP address Serv-U uses for its response to the PASV command so that it uses the actual IP address and not the internal IP that Serv-U sees

  • Navigate to Domain Details | Listeners
  • Select your FTP/FTPS listener(s) and click Edit
  • Enter the external IP address

Hi Lukastribus,

Thanks! I already had put the external IP address there. To troubleshoot further I tried the DNS name which Serv-U also allows, but without success. The FTP sessions keeps stopping after the PASV command. This also happends when on the LAN so I tried enabling the “Use with LAN connections” option, but also without success.
screen07

You are trying from a different Internet connection, not the same Internet connection as the FTP server, right?

Please login via https://ftptest.net/ and share the complete output.

Hi,

It seems I made a mistake with the Cisco Firewall.
I created the nat to the VIP, but forgot to add the VIP to the ACL list.
The ftptest.net website gave me enough info to figure this out.
Thank you both for helping out!