How to set up SFTP on your Arch Linux VPS

Updated 18 Nov 2013

FTP bad * SFTP good * SFTP in ten seconds


FTP bad

Now that you've got your VPS up and running, with Apache serving up your websites on multiple domains, the next logical thing to do is implement a way to easily manage your remote files and directories.

FTP (File Transfer Protocol) dates back to the 1970's. In its original form called 'Plain FTP' (which is still widely used today), it doesn't support encryption and is a security nightmare. Everything, even usernames and passwords, is transmitted in plain text via FTP.

Another major problem with FTP has to do with how it uses two channels - one to establish the connection and issue commands and receive responses, and one to transfer data. An FTP client program will connect to the FTP server on a specific port, but the actual transfer of data happens on other, random ports. The sheer frustration of trying to get FTP to work from behind a firewall or gateway may result in taking shortcuts that result in security holes.

Many website administrators are still most comfortable using FTP client software to upload files and webpages to the server. But FTP is an outdated and insecure technology for the modern Internet.


SFTP good

FTP can however be secured by channeling the connection through an encrypted tunnel. This is called FTP over SSL/TLS, or FTPS for short. However, most of plain old FTP's other drawbacks are inherited.

SFTP, or Secure Shell FTP, is actually unrelated to FTP in any way other than name. Big smileys all round. SFTP is a protocol in its own right, based on the SSH family of protocols that were developed to secure remote access to UNIX systems. Remember SSH? You've already used it to log on to your VPS. SSH FTP, or SFTP for short, is an extension to the SSH protocol specifically designed for secure file transfers and remote directory administration.

With SFTP, you can be up and running in literally seconds. Setup is easy-peasy because SSH and its extensions are built right into the heart of Linux. No builds or installs required. Luvly.


SFTP in ten seconds

Open the SSH config file:

sudo nano /etc/ssh/sshd_config

Check that the following line is in there somewhere (and has no hash # preceding it). If not, add it.

Subsystem sftp /usr/lib/ssh/sftp-server

If you had to add it, save (CTRL+o followed by ENTER) and exit nano (CTRL+x), then restart the SSH daemon:

sudo systemctl restart sshd

And that's it! Log on using your favourite SFTP client. Most modern FTP clients, such as FileZilla and Cyberduck, support Plain FTP, FTPS and the big one, SFTP. In your connection preferences, choose SFTP as the protocol to use, the port number as the one you use to log in to your VPS via SSH, and your system username and password.

SFTP should be all you ever require for file transfer and remote directory purposes. Note that the SSH library also supports chrooting for multiple SFTP-only users (without giving them SSH login). But that's for another time.

If for some unfathomable reason you insist on setting up old school FTP, read on. Bear in mind that you will likely suffer when you eventually come to set up your VPS' firewall.


Install vsftpd

FTP and FTPS require that an FTP server be installed. The FTP server of choice is vsftpd (Very Secure FTP Daemon). This is available direct from Arch's official repositories, so you can just pacman -sync it (no building required) through the command line of your SSH terminal:

sudo pacman -S vsftpd

And there you have it, it's installed.


Configure vsftpd as a Plain FTP server

An example vsftpd configuration file called vsftpd.conf can now be found in Arch's /etc directory (why?). Open it using Nano:

sudo nano /etc/vsftpd.conf

Edit the following lines as below, uncommenting them by removing any preceding hashes # as required:


anonymous_enable=NO: don't allow anyone to access FTP on your VPS.

local_enable=YES: allow local users to use FTP. (A local user is one whose username, password, etc. reside on your VPS.)

write_enable=YES: allow users to write (upload, update, etc.) files.


When a file or directory is created under Linux, it is created with a default set of permissions that allow an end user to read, write and/or execute the file.

local_umask=077 is the default setting in vsftpd. No other end user can read or write your data if umask remains set to 077. In other words, if you upload a webpage file under umask 077, no-one will be able to see that webpage.

local_umask=022 allows only you to write data, but anyone can read it.

Save (CTRL+o then ENTER), quit (CTRL+x) Nano back to the command line and start the FTP server:

sudo systemctl restart vsftpd

Test it's working by FTPing your VPS' IP address from your local machine. Open a new terminal (but don't log into your VPS) and enter:

ftp 123.456.78.90

You should get something like this:

Connected to 220 (vsFTPd 3.0.2)

If you get the following:

500 OOPS: priv_sock_get_cmd

it's because there's a bug in vsftpd which hasn't been fixed in the version you've just installed. Just add this line to the end of /etc/vsftpd.conf:


Don't forget to restart vsftpd and then try again.

Success? You can close the localhost terminal window now.


Create a unique FTP user

vsftpd recommends that you define on your system a unique user which the ftp server can use as a totally isolated and unprivileged user.

So, create a user just for FTPing, who can't do anything else such as login via SSH to your VPS. In this way, should the user be compromised, your VPS is not left wide open. This user should have his or her own unique password.

useradd -g ftp -d /srv/http -s /sbin/nologin userftp

In the above command, the user is named userftp.

-s puts userftp into the no-login shell list.

-d is the home directory where the user logging in as userftp will automatically start the FTP session in. In this case, the /srv/http directory. If this directory seems familiar to you, it's because it's the default directory where Apache serves up webpages from.

The -g option adds userftp to the ftp group of users.

Set the password for userftp using:

passwd userftp

Using Nano, enable the nopriv_user option in vsftpd.conf:


Save, quit Nano, then restart vsftpd.

Now that you have a unique user and password just for FTPing, try logging in as userftp to your VPS from your local machine using your preferred FTP client software, e.g. FileZilla or Cyberduck. You can use your VPS' IP address as the remote hostname, userftp as the username and of course the password you just created. If all goes well, you should be able to see the remote directories and files in /srv/http that you created for Apache to serve up.

Just to be clear, you've now connected to your FTP server through Filezilla or Cyberduck as userftp with only FTP privileges, but in your terminal you're still logged into your VPS as you, with all administrator privileges.

At this point, you will need to change the permissions for any files and directories created prior to creating userftp. userftp must be able to edit and delete those directories and files through FTP, which would currently be denied. From the command line, use chown to change the owner of the /srv/http directory to userftp:

sudo chown -R userftp /srv/http

-R means "recursive" and changes any contained subdirectories and files too.

Now change the permissions for all files and subdirectories so that userftp (now their owner) can both read and write to them, and anyone else can only read them:

sudo chmod -R 644 /srv/http

You should now be able to transfer files using Filezilla, Cyberduck, etc. and these files, be they webpages or whatever, can be read by the internet public.


Some terminal commands to keep handy

chownchange a file's owner and group
chmodchange a file's access permissions


Configure vsftpd as an FTPS server

Up to now, vsftpd has been functioning as a Plain FTP server. To encrypt your FTP sessions over SSL/TLS, create an SSL certificate on your VPS in the /etc/ssl/certs directory by issuing the following commands:

cd /etc/ssl/certs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout vsftpd.pem -out vsftpd.pem

You will be asked some questions about your company, etc. As your certificate is not a trusted one, it doesn't really matter what you fill in. The certificate will only be used to encrypt the connection. (If you plan to use a certificate for trust, you can get one from a Certificate Authority like Thawte or Verisign.)

Open the vsftpd configuration file again in Nano:

sudo nano /etc/vsftpd.conf

Change the following options (some options aren't on the example configuration file, so add them):


Here you're telling vsftpd to require SSL and only use the TLS protocol (SSLv2 and v3 have been superseded by TLS, but most people still refer to TLS as SSL), the location of your SSL certificate and key (same file) and which ciphers to use.

CTRL+o then ENTER to save, and then CTRL+x to quit Nano. Restart the service:

sudo systemctl restart vsftpd

Now connect to your FTPS server through your FTP client that supports FTPS (Filezilla, Cyberduck, among others). In your connection preferences, select FTP as the protocol and "Require explicit FTP over TLS". Authentication should be "Ask for password" and the username should be userftp as before.

If you have a firewall already up and running, this is where things get tricky.


FTP and firewalls

FTP supports two different modes of operation: active and passive.

In active mode, the client establishes the command channel from port X of its own choosing to server port 21, but the server establishes a data channel from its port 20 to client port X+1.

In passive mode, the client establishes both channels, first by initiating the command channel from port X to port 21 on the server. The server then replies to the client from port 21 to port X and tells it to use port number Y as a data channel. The client then establishes the data channel from port X+1 to the server on port Y.

Passive mode is used most of the time nowadays due to the prevalence of NAT routers, i.e. most computers are behind network firewalls. While your FTP client can FTP to a remote server, the server can't open a data channel through the network firewall that your client is on. This must be done by the client.

If you are using iptables for firewalling, you will need to open up a port to allow the FTP server to listen on (usually port 21). There are some kernel modules needed for proper FTP connection handling by iptables, especially ip_conntrack_ftp and maybe ip_nat_ftp. As previously explained, FTP uses the given listen_port for commands only; all the data transfer is done over different ports. These ports are chosen by the FTP daemon at random and for each session (also depending on whether active or passive mode is used). To tell iptables that packets on certain ports should be accepted, ip_conntrack_ftp is required. Read more about kernel modules here. Good luck!