SFTP openssh Secure File Transfer

What is sftp?

sftp is a file transfer program, similar to ftp, which performs all operations over an encrypted ssh transport. sftp also uses many features of ssh, such as public key authentication and compression. sftp has generally replaced the in-secure ftp system that had been in place for many years.

Basic Syntax of sftp

The basic syntax of the sftp command is as follows:


sftp user_id@remote_server

For example, If the user "tux" wanted to copy a file called "sftp_test.txt" to a location of "/tmp" on a server with the IP address of "192.168.122.75", then the commands to be issued would be as follows:


tux@mint01a:~/sftp_test$ ls -l
total 4
-rw-rw-r-- 1 tux tux 150 May 23 13:35 sftp_test.txt

tux@mint01a:~/sftp_test$ sftp tux@192.168.122.75
tux@192.168.122.75's password: 
Connected to 192.168.122.75.

sftp> pwd
Remote working directory: /home/tux

sftp> cd /tmp

sftp> put sftp_test.txt
Uploading sftp_test.txt to /tmp/sftp_test.txt
sftp_test.txt                                                                     100%  150   368.1KB/s   00:00    
sftp> quit

From the above, we can see that the file has been transferred successfully. By default, when you connect to a server for a sftp connection, you will be placed in your users landing zone/home area. To change to a different directory on the remote server, we use the "cd" command (Change Directory).

The command to transfer a file is the "put" command.

Retrieve a file

To retrieve a file from a remote server you will use the "get" command. Below is an example of retrieving a file using "get".

The directory on the remote server where the file is located is "/home/tux/data/".

Using sftp, we will retrieve the file and place it in a directory called "/home/tux/data"

"cd" is used for changing directory on the remote server and "lcd" is used for changing directory on the local server.


$ sftp tux@192.168.122.75
tux@192.168.122.75's password: 
Connected to 192.168.122.75.

sftp> cd /home/tux/data

sftp> pwd
Remote working directory: /home/tux/data

sftp> lcd /home/tux/data

sftp> lpwd
Local working directory: /home/tux/data

sftp> get 50MB_file.img
Fetching /home/tux/data/50MB_file.img to 50MB_file.img
/home/tux/data/50MB_file.img                  100%   50MB 113.5MB/s   00:00    

sftp> ls -l
-rwxrwxrwx    1 tux      tux      52428800 May 23 18:12 50MB_file.img

sftp> lls -l
total 51200
-rwxrwxr-x 1 tux tux 52428800 May 23 18:32 50MB_file.img
-rw-rw-r-- 1 tux tux        0 May 23 18:25 test.txt

sftp> quit

In the above example, the following commands were used:

cd : Change Directory on Remote Server
pwd : Print Remote Server Working Directory
lcd : Changes Local Working Directory
get : get command used for retrieving a file
ls -l : List contents of Remote Directory
lls - l : List contents of Local Directory
quit : Quit is used to terminate connection with remote server

mput and mget

If you wish to transfer or retrieve multiple files that match a specific pattern, you may use the multiple options of "mget" or "mput".

Multiple mput example: mput *.dat


$ sftp tux@192.168.122.75
tux@192.168.122.75's password: 
Connected to 192.168.122.75.

sftp> cd /home/tux/data

sftp> lcd /home/tux/data

sftp> mput *.dat
Uploading file1.dat to /home/tux/data/file1.dat
file1.dat                                                                                               100%  110   284.9KB/s   00:00    
Uploading file2.dat to /home/tux/data/file2.dat
file2.dat                                                                                               100%  158   582.0KB/s   00:00    
Uploading file3.dat to /home/tux/data/file3.dat
file3.dat                                                                                               100%  206   880.1KB/s   00:00    
Uploading file4.dat to /home/tux/data/file4.dat
file4.dat                                                                                               100%  254     1.1MB/s   00:00    
Uploading file5.dat to /home/tux/data/file5.dat
file5.dat                                                                                               100%  302     1.4MB/s   00:00    

sftp> quit

Multiple mget example: mget *.img


$ sftp tux@192.168.122.75
tux@192.168.122.75's password: 
Connected to 192.168.122.75.

sftp> cd /home/tux/data

sftp> lcd /home/tux/data

sftp> mget *.img
Fetching /home/tux/data/file1.img to file1.img
/home/tux/data/file1.img                                                                                100%  110   113.2KB/s   00:00    
Fetching /home/tux/data/file2.img to file2.img
/home/tux/data/file2.img                                                                                100%  158   296.9KB/s   00:00    
Fetching /home/tux/data/file3.img to file3.img
/home/tux/data/file3.img                                                                                100%  206   501.9KB/s   00:00    
Fetching /home/tux/data/file4.img to file4.img
/home/tux/data/file4.img                                                                                100%  254   608.1KB/s   00:00    
Fetching /home/tux/data/file5.img to file5.img
/home/tux/data/file5.img                                                                                100%  302   815.5KB/s   00:00    

sftp> quit

Creating a Public key

As with SSH, the "sftp" command can use "Public Key Authentication" to connect to a server without needing to enter a password. This functionality is very useful if you need to transfer files from a script as you will not need to enter a password to authenticate.

Below is the process required for generating a public key

Generating a public key

Using an utility called "ssh-keygen", you can create a public key that can be distributed to servers that you require access to.

The following key has been generated on a Linux Mint system.


tux@mint01a:~$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/tux/.ssh/id_rsa): 
Created directory '/home/tux/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/tux/.ssh/id_rsa
Your public key has been saved in /home/tux/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:QdfQJfNmO2eixOQOrjKYKcmsVNbPdpJ+C8VGev10BhI tux@mint01a
The key's randomart image is:
+---[RSA 3072]----+
|        . oEo..  |
|       . .  ++   |
|        .. ...+  |
|    .   +..+.o.. |
|   o . .S=..+.+oo|
|  o   o =. +o.o= |
| + . + B .. o.   |
|. = + = +o       |
|.. .   +o..      |
+----[SHA256]-----+

In the above example we chose to use the "rsa" (Rivest, Shamir, Adleman) algorithm to create our digital signature. We could have chosen "dsa". Next we were prompted to supply a directory where we would like the key to be saved. In the example I pressed "Enter" to accept the default location of "/home/tux/.ssh/id_rsa". Next, We were asked to enter a passphrase. I chose not to enter a passphrase. All that is required now is to distribute our public key to our desired remote server.


tux@mint01a:~$ cd /home/tux/.ssh

tux@mint01a:~/.ssh$ ls -l
total 8
-rw------- 1 tux tux 2602 May 23 11:32 id_rsa
-rw-r--r-- 1 tux tux  565 May 23 11:32 id_rsa.pub

Copying Public keys to remote servers

In the above example of the "ssh-keygen -t rsa" command we can see that a public key was created.

My public key has been saved in /home/tux/.ssh/id_rsa.pub

To use the public key, we have to first copy the contents of the file "id_rsa.pub" to a file called "authorized_keys" on the remote server. Whenever copying a new key to a remote servers authorized_keys file, always use the append option. If you copy your files content, you could overwrite the file and destroy any other keys that may be located there. The easiest way to transfer the key to the remote server is to issue a command similar to the one below.

Note, the "authorized_keys" key file must already exist on the remote server under the account you are logging into.

In the example below, I will create the directory structure and authorized_keys file on the remote server as follows:


[tux@centos8a ~]$ pwd
/home/tux

[tux@centos8a ~]$ ls -al
total 12
drwx------. 2 tux  tux   62 May 23 11:31 .
drwxr-xr-x. 4 root root  29 May 23 11:31 ..
-rw-r--r--. 1 tux  tux   18 Jul 21  2020 .bash_logout
-rw-r--r--. 1 tux  tux  141 Jul 21  2020 .bash_profile
-rw-r--r--. 1 tux  tux  376 Jul 21  2020 .bashrc

[tux@centos8a ~]$ mkdir .ssh

[tux@centos8a ~]$ chmod 700 .ssh/

[tux@centos8a ~]$ cd .ssh
[tux@centos8a .ssh]$ touch authorized_keys

[tux@centos8a .ssh]$ chmod 600 authorized_keys 

[tux@centos8a .ssh]$ ls -l
total 0
-rw-------. 1 tux tux 0 May 23 11:46 authorized_keys

Note, I had to create the ".ssh directory first, set its permissions to "700" and then create the empty "authorized_keys" file using the "touch" command. The permissions on the "authorized_keys" file are also set to "600".

Once the above is in place, I can copy the contents of our public key to this file.


$ cat $HOME/.ssh/id_rsa.pub | ssh 192.168.122.75 'cat >> .ssh/authorized_keys && echo "Contents Copied Successfully"'
tux@192.168.122.75's password: 
Contents Copied Successfully

The above command simply appends the key on our local server to the "authorized_keys" file on the remote server. (Amend IP address to match your remote server)

Testing sftp Access with Public Key

Once the public key has successfully been copied to the correct location on the remote server, you should now be able to login to the remote server without specifying a password.


$ sftp tux@192.168.122.75
Connected to 192.168.122.75.
sftp> pwd
Remote working directory: /home/tux
sftp> quit

From the above, we can see that we were able to connect to the remote server without being prompted for a password.

sftp commands - help

For a list of available commands when using "sftp", you can issue a "?" (question mark) at the command prompt for a list of commands:


$ sftp tux@192.168.122.75
Connected to 192.168.122.75.

sftp> ?
Available commands:
bye                                Quit sftp
cd path                            Change remote directory to 'path'
chgrp [-h] grp path                Change group of file 'path' to 'grp'
chmod [-h] mode path               Change permissions of file 'path' to 'mode'
chown [-h] own path                Change owner of file 'path' to 'own'
df [-hi] [path]                    Display statistics for current directory or
                                   filesystem containing 'path'
exit                               Quit sftp
get [-afpR] remote [local]         Download file
help                               Display this help text
lcd path                           Change local directory to 'path'
lls [ls-options [path]]            Display local directory listing
lmkdir path                        Create local directory
ln [-s] oldpath newpath            Link remote file (-s for symlink)
lpwd                               Print local working directory
ls [-1afhlnrSt] [path]             Display remote directory listing
lumask umask                       Set local umask to 'umask'
mkdir path                         Create remote directory
progress                           Toggle display of progress meter
put [-afpR] local [remote]         Upload file
pwd                                Display remote working directory
quit                               Quit sftp
reget [-fpR] remote [local]        Resume download file
rename oldpath newpath             Rename remote file
reput [-fpR] local [remote]        Resume upload file
rm path                            Delete remote file
rmdir path                         Remove remote directory
symlink oldpath newpath            Symlink remote file
version                            Show SFTP version
!command                           Execute 'command' in local shell
!                                  Escape to local shell
?                                  Synonym for help