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.
- 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 - 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!