SCP openssh Secure File Copy

What is scp?

scp copies files between hosts on a TCP/IP network. scp uses ssh for data transfer, and uses the same authentication methods and provides the same security as ssh. scp will prompt for passwords or passphrases if they are needed for authentication. However, as with ssh, you can create a public key that can be shared with a remote server to allow transfers between servers without the need for a password to be entered.

Basic Syntax of scp

The basic syntax of the scp command is as follows:


scp source_file user_id@remote_server:destination_path

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


$ ls -l
total 4
-rw-rw-r-- 1 tux tux 758 May 23 12:25 scp_test.txt

$ scp scp_test.txt tux@192.168.122.75:/tmp
tux@192.168.122.75's password: 
scp_test.txt                                                                      100%  758     1.3MB/s   00:00    

From the above, we can see that the file has been transferred successfully, note, we were also asked to provide a password.

Preserve time Stamps

Often when transferring files, it will be important to retain the original time/date stamps of a file. To do this using the "scp" command, we pass the additional parameter of "-p". This parameter is for "Preserve", preserving the original time/date file stamps.

Example without -p


$ ls -l old_file.txt 
-rw-rw-r-- 1 tux tux 200 Jul 12  2018 old_file.txt

$ scp old_file.txt tux@192.168.122.75:/tmp
tux@192.168.122.75's password: 
old_file.txt                                                                      100%  200   366.1KB/s   00:00

Notice, the file "old_file.txt" has a date of "2018", however, when the file is transferred without the "-p" parameter, the current time/date is automatically applied at the receiving end (remote server).

File received at remote server:


$ cd /tmp

$ ls -l old_file.txt
-rw-rw-r--. 1 tux tux 200 May 23 12:35 old_file.txt

Example with -p


$ scp -p old_file.txt tux@192.168.122.75:/tmp
tux@192.168.122.75's password: 
old_file.txt                                                                      100%  200   375.2KB/s   00:00

File received at remote server:


$ cd /tmp

$ ls -l old_file.txt 
-rw-rw-r--. 1 tux tux 200 Jul 12  2018 old_file.txt

Copying Multiple Files

To copy multiple files, you can provide a pattern that matches your files. For example, if you wanted to transfer all files that ended ".txt", then you could use a command similar to:

scp *.txt tux@192.168.122.75:/tmp


$ ls -l
total 16
-rw-rw-r-- 1 tux tux  44 May 23 12:45 list.txt
-rw-rw-r-- 1 tux tux 200 Jul 12  2018 old_file.txt
-rw-rw-r-- 1 tux tux 758 May 23 12:25 scp_test.txt
-rw-rw-r-- 1 tux tux  40 May 23 12:45 test.txt

$ scp *.txt tux@192.168.122.75:/tmp
tux@192.168.122.75's password: 
list.txt                                                                          100%   44    76.7KB/s   00:00    
old_file.txt                                                                      100%  200   482.2KB/s   00:00    
scp_test.txt                                                                      100%  758     1.6MB/s   00:00    
test.txt                                                                          100%   40   107.2KB/s   00:00

Copy a Directory using scp

To copy a directory and its contents to a remote server, we can issue the following command with the "-r" parameter.:


$ pwd
/home/tux/bigfolder

$ scp -r /home/tux/bigfolder tux@192.168.122.75:/tmp/
tux@192.168.122.75's password: 
file3.txt                                                                         100%    6    10.2KB/s   00:00    
scp_test.txt                                                                      100%  758     2.2MB/s   00:00    
list.txt                                                                          100%   44   138.1KB/s   00:00    
file1.txt                                                                         100%    6    15.7KB/s   00:00    
test.txt                                                                          100%   40    94.8KB/s   00:00    
old_file.txt                                                                      100%  200   582.4KB/s   00:00    
file2.txt                                                                         100%    6    16.2KB/s   00:00    

scp -r /home/tux/bigfolder tux@192.168.122.75:/tmp/

From the above, we can see that all files within the directory "bigfolder have been successfully copied to the remote server.

Files received on remote server


[tux@centos8a tmp]$ pwd
/tmp

[tux@centos8a tmp]$ ls -ld bigfolder/
drwxrwxr-x. 2 tux tux 129 May 23 12:52 bigfolder/

[tux@centos8a tmp]$ cd bigfolder/

[tux@centos8a bigfolder]$ ll
total 28
-rw-rw-r--. 1 tux tux   6 May 23 12:52 file1.txt
-rw-rw-r--. 1 tux tux   6 May 23 12:52 file2.txt
-rw-rw-r--. 1 tux tux   6 May 23 12:52 file3.txt
-rw-rw-r--. 1 tux tux  44 May 23 12:52 list.txt
-rw-rw-r--. 1 tux tux 200 May 23 12:52 old_file.txt
-rw-rw-r--. 1 tux tux 758 May 23 12:52 scp_test.txt
-rw-rw-r--. 1 tux tux  40 May 23 12:52 test.txt

Creating a Public key

As with SSH, the "scp" command can use "Public Key Authentication" to connect to a server without needing to enter a password. This functionality is 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 SCP 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.


$ ls -l
total 4
-rw-rw-r-- 1 tux tux 150 May 23 13:05 test_file.txt

$ scp test_file.txt tux@192.168.122.75:/tmp
test_file.txt                                                                     100%  150   225.2KB/s   00:00

From the above, we can see that we were able to transfer our test file successfully without being prompted for a password.