Transferring files between computers can be a pain. FTP is somewhat clunky and old, and using online services isn't direct and is less than ideal for handling sensitive files. Git works well for code and text, but isn't the best for binary files and requires a repository to be configured. So, what's a good solution for sending files directly between computers? SFTP.

SFTP is a secure file transfer protocol that makes use of SSH to send files between computers. It is encrypted and direct. It allows you to use an existing service to send files, thereby reducing your attack surface, and it eliminates the need to rely on potentially vulnerable passwords for file transfers.

Before you go any further, you need to set up SSH keys for the machines you want to work with. If you don't know how, check out our guide on setting up SSH key based authentication.

The Case Against FTP

FTP sucks. There's no way around it. FTP is susceptible to many security exploits, and continues to be a favorite target for would-be attackers. It also relies on password authentication, making for yet another possible way an attacker can destroy your system.

What makes all of this especially bad is the fact that FTPs purpose is to transfer files. That means that the mechanisms are already in place for an attacker to upload and execute malicious code on your machine.

If possible, avoid FTP.


SFTP's syntax is very similar to SSH. Connecting to a server isn't very different using SFTP than it is with SSH.
$ sftp This email address is being protected from spambots. You need JavaScript enabled to view it..1.1
That will establish a connection and drop you into a modified SFTP shell.

You may need to use a different port for SSH/SFTP. In that case, specify it with the -P flag.
$ sftp -P 35000 This email address is being protected from spambots. You need JavaScript enabled to view it..1.1

Sending Files

From the SFTP shell, you can use SFTP's built-in commands to send and receive files. The commands for either direction are similar to cp syntax. To send a file, use the put command.

put will take a local file and place it into the current working directory of the remote machine.
sftp> put localfile
The localfile will be transferred to your current directory. Folders are similar. Like cp, you can use the -r flag to copy a directory and its content.
sftp> put -r localdir

Receiving Files

Pulling files down works nearly the same with the get command. In this case, it's not dependent on your current directory. You can specify a file path to copy and a location which you would like to copy it to.
sftp> get remotefile
This will just get the file and place it in your current directory.
sftp> get remotefile /path/to/localfile
The above will get the same remote file and place it in a specific local directory.

You can also use the -r flag with get to copy an entire directory.
sftp> get -r /path/do/remotedir path/to/localdir
If there is a need to preserve the exact permissions of the directory, add the -P flag in.
sftp> get -Pr /path/do/remotedir path/to/localdir

Closing Thoughts

Once again, command line simplicity comes through. Okay, so you can obviously use FTP from the command line, but most people rely on unnecessarily bulky GUI apps for it. Even still, SFTP provides a simple, clean, and secure way to transfer files. As a bonus, it reduces the number of services you need running, allows you to close up one more port, and reduces the overall attack surface of your servers. That looks like an all around win, if there ever was one.