Providing FTPS with vsftpd behind forwarding firewall

by Thomas Urban

The Setup

Consider running vsftpd in virtual machine to be hosted on physical server accessible over some public IP. Here we try to give some basic information on how to configure this setup for provding passive-mode FTPS on physical server's public IP to be transparently forwarded into the VM running vsftpd.

In addition vsftpd is to be enforced to support passive mode, only. This is best practice for users mostly accessing the web from intranets hidden behind firewalls/routers by masquerading the client's actual IP for it's local to the particular intranet, only.

The setup is for providing encrpyted FTP - FTP over SSL or FTPS. The encryption is working explicitly supporting either SSL or TLS.

Prerequisites

The physical host should be available by some public hostname. That hostname should resolve into public IP of physical server's netword interface card. This is required for using proper SSL certificate.

This is what we assume in following excerpts of commands and configuration files accordingly:

  • eth0 is the name of network interface card server is receiving incoming traffic from public network.
  • 123.45.67.89 is the server's public IP routed to the network interface card meant before.
  • my.server.com is the public hostname resolved into the public IP of server mentioned before.
  • 10.0.3.1 is the local-only IP of virtual machine hosted on physical server and running instance of vsftpd.

There is a file containing public X.509 certificate on common name my.server.com, the related private key and any chain certificate of CA optionally required by clients for validating authenticity of that certificate. We call this file /etc/ssl/certs/my.server.com.pem.

 

The Forwarding Firewall

On physical host some rules of net filter must be set for properly forwarding incoming traffic to virtual machine.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 21 -j DNAT --to 10.0.3.1
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 10000:49999 -j DNAT --to 10.0.3.1

Checking Forward Policy

These two rules presume to have an accepting  policy on chain FORWARD in table filter of iptables. You may check your case by invoking

sudo iptables -t filter -L | grep "Chain FORWARD"

The output must be

Chain FORWARD (policy ACCEPT)

If your policy is different don't change it without inspecting reasons for having different policy first. Policy may be adjusted using

sudo iptables -t filter -P FORWARD ACCEPT

Checking IPv4 Forwarding

In addition our forwarding rules require IPv4 forwarding to be enabled basically. Check if output of command

sudo cat /proc/sys/net/ipv4/ip_forward

is reading

1

Using Conntrack

Quite several posts found on the internet require to insert ftp conntrack module of netfilter. However, due to using accepting policy in chain FORWARD there is no actual need for conntrack here. I haven't double-checked the way conntrack is working, but due to using encrypted connections there is no opportunity for conntrack to monitor FTP traffic for detecting data connections related to the control connection. Without inspecting FTP control traffic conntrack won't be able to properly detect valid related data conntections to be enabled on forwarding.

So don't care for not using conntrack here ...

Configuring vsftpd in Virtual Machine

Enter the virtual machine and install vsftpd. In Ubuntu this is achieved by running

sudo apt-get install vsftpd

Add some user named ftpsecure

sudo useradd ftpsecure
sudo usermod -L ftpsecure

Assure your certificate file is available as /etc/ssl/certs/my.server.com.pem or as any pathname you prefer instead. Next adjust your /etc/vsftpd.conf to read like this:

listen=YES
anonymous_enable=NO
local_enable=YES
chroot_local_user=YES
write_enable=YES

dirmessage_enable=YES
nopriv_user=ftpsecure
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd

ssl_enable=YES
ssl_tlsv1=YES
ssl_sslv2=YES
ssl_sslv3=YES

rsa_cert_file=/etc/ssl/certs/my.server.com.pem
ca_certs_file=/etc/ssl/certs/my.server.com.pem

# promote public IP of physical host on starting passive mode
pasv_address=123.45.67.89
pasv_enable=YES
pasv_min_port=10000
pasv_max_port=49999

# disable active mode FTP
port_enable=NO

# this is required obviously
seccomp_sandbox=NO

Finally restart the vsftpd service in VM by invoking

sudo service vsftpd restart

 

Configuration In Detail

What is configuration doing? Of course it's customizing vsftpd in quite several aspects.

  • It is configuring vsftpd to run in standalone mode.
    listen=YES
  • It is disabling any anonymous logins.
    anonymous_enable=NO
  • It is enabling login of local users.
    local_enable=YES
  • It is enabling chrooting of local users on log in to prevent either user from accessing files not residing in its own home directory.
    chroot_local_user=YES
  • It is permitting file upload.
    write_enable=YES
  • It is enabling explicit SSL supporting TLS, SSLv2 and SSLv3.
    ssl_enable=YES
    ssl_tlsv1=YES
    ssl_sslv2=YES
    ssl_sslv3=YES
  • It is selecting certificate to use.
    rsa_cert_file=/etc/ssl/certs/my.server.com.pem
    ca_certs_file=/etc/ssl/certs/my.server.com.pem
  • It is enabling support for passive mode with promiting the physical hosts IP rather than VM's local-only IP for the latter isn't available on public network.
    pasv_address=123.45.67.89
    pasv_enable=YES
    pasv_min_port=10000
    pasv_max_port=49999
  • It is disabling support for active mode FTP.
    port_enable=NO
  • It is finally fixing some issues with loosing connection right after logging in.
    seccomp_sandbox=NO

Fixing Home Directories

Due to some vulnerabilities vsftpd requires home directories not to be writable by its related owner's account unless either switching off chroot or disabling upload. Usually a user's website or similar is found in a subfolder like public_html that might be writable to the user.

  1. Add that folder to all users' home directory and make it writable to the particular user.
    mkdir -p /home/user/public_html
    chown user /home/user/public_html
    chmod u+rwx /home/user/public_html
  2. Ensure the declared home folder isn't writable by default.
    chmod a-w /home/user

Testing Connectivity

This setup has been successfully tested with recent versions of WinSCP and FileZilla. If your FTPS is properly logging in, but fails to transfer any data (e.g. directory listings or files), This might be due to current releases of vsftpd requiring reuse of ssl sessions. If an FTP client isn't supporting this requirement you might wish to disable it by adding rule

require_ssl_reuse=NO 

to configuration file in /etc/vsftpd.conf and restart vsftpd afterwards. However, disabling this option has and impact on security described here. Thus, take care!

Go back