SSH, short for Secure Shell, is a protocol for secure network communications. It is widely used for executing commands on remote servers, and for file uploads or downloads. If you are working with servers, or use Git version control, you surely are using SSH.
Secure Shell is using private and public key pairs. You can either use automatically generated private and public keys combined with a password, or manually generated private and public keys. In the latter case, you need to keep your private key on your computer and upload the public key to the remote server.
Manually creating a pair of SSH keys
If you are using GitHub, EC2, Bitbucket, AWS, Gitlab, DigitalOcean, or some other service, you might have seen the possibility to upload public SSH keys for direct access to remote servers.
Here is how you usually create the SSH keys on the computer from which you want to establish a secure connection (your local machine or one of your servers that has access to other servers or services). In the Terminal you would execute these commands:
$ ssh-keygen
$ ssh-add ~/.ssh/id_rsa
The id_rsa
is the name of the default SSH private key. The public key would be id_rsa.pub
. And by default they both will be located under ~/.ssh/
.
When running ssh-keygen
you can choose different key names and even add a passphrase. For instance, you could have github_id_rsa
and github_id_rsa.pub
keys for communication with GitHub. My recommendation would be for each new service to create a new private-public key pair so that in case you need to transfer your computer's data to a different machine, you could selectively transfer the access to the remote servers.
Also, if you are not using the passphrase for the SSH key pair, I would recommend having your disk encrypted and a secure user password for your computer. If your laptop gets stolen, the thief wouldn't be able to get to your remote servers without knowing your computer's password.
Creating an access to a remote server by SSH key
In the case of GitHub, Bitbucket, and other online services with SSH communication, you usually have to copy the contents of the public key into a text field in a web form.
If you want to create a secure communication by manually generated private-public keys with a server where your Django project is deployed, you should append the contents of the public key to the ~/.ssh/authorized_keys
file on the remote server.
To get the content of the public key in the Terminal, you can use:
$ cat ~/.ssh/id_rsa.pub
Then copy the output to the clipboard.
Or on different Unix you can run pbcopy
as follows:
$ pbcopy < ~/.ssh/id_rsa.pub
To append the contents of the public key to the remote server, you can do this:
$ echo "...pasted public key...">>~/.ssh/authorized_keys
Creating authorization at a remote server by password
If you want to establish an SSH connection with a password and automatically generated private-public keys, you would need to create/edit /etc/ssh/sshd_config
and ensure these two settings:
PasswordAuthentication yes
PermitEmptyPasswords no
After the change, you would restart the ssh server with the following command:
$ sudo service ssh restart
Also, make sure that the user you are connecting with has a password:
$ sudo passwd the_user
Connecting to a remote server
The default way to connect via SSH to a remote server with a password is executing the following in the Terminal:
$ ssh usernamehere@example.com
To connect with a private key, you would execute this:
$ ssh -i ~/.ssh/sitecom_id_rsa usernamehere@example.com
Next, let's see how we can simplify this using some local SSH configuration.
Configuring local SSH client
Edit ~/.ssh/config
and add the following lines for each SSH connection that you want to define:
Host sitecom
HostName sitecom.com
User usernamehere
IdentityFile ~/.ssh/sitecom_id_rsa
If the domain of the website is not yet pointing to the IP address of the server, you can also connect by IP address:
Host sitecom
HostName 1.2.3.4
User usernamehere
IdentityFile ~/.ssh/examplecom_id_rsa
The following allows you to login to your remote servers by manually generated private-public key with just these lines:
$ ssh sitecom
To request for password instead of using the manually generated keys, you would need to modify the snippet as follows:
Host examplecom
HostName example.com
User the_user
PubkeyAuthentication=no
When you connect via SSH and wait don't type anything for 30 minutes or so, the connection gets lost. But you can require your client to connect to the server every 4 minutes or so by adding the following lines to the beginning of the ~/.ssh/config
on your local computer:
Host *
ServerAliveInterval 240
ssh-copy-id
ssh-copy-id
installs an SSH key on a server as an authorized key. Its purpose is to provision access without requiring a password for each login. This facilitates automated, password-less logins and single sign-on using the SSH protocol.
Copy the key to a server
Once an SSH key has been created, the ssh-copy-id
command can be used to install it as an authorized key on the server. Once the key has been authorized for SSH, it grants access to the server without a password.
Use a command like the following to copy SSH key:
ssh-copy-id -i ~/.ssh/mykey user@host
This logs into the server host, and copies keys to the server, and configures them to grant access by adding them to the authorized_keys file. The copying may ask for a password or other authentication for the server.
Only the public key is copied to the server. The private key should never be copied to another machine.
Test the new key
Once the key has been copied, it is best to test it:
ssh -i ~/.ssh/mykey user@host
The login should now complete without asking for a password. Note, however, that the command might ask for the passphrase you specified for the key.
Uploading and downloading files using SSH connection (SCP, RSync, SFTP, FTP)
Typically, Secure Shell allows you to execute terminal commands on the remote server using bash, zsh, sh, or another shell. But very often, you also need to transfer files securely to and from the server. For that, you have these options: scp
command, rsync
command, or FTP client with SFTP
support.
SFTP
FTP clients like Transmit allow you to have SFTP connections either by username and password or by username and private key. You can even generate the private-public keys directly in the app there.
SFTP works like FTP, but all communication is encrypted there.
SCP
The scp
stands for Secure Copy.
This is how you would copy the .env
file from the remote server to your local development environment:
$ scp userhere@example.com:~/codes/laravel/.env ./myproject/codes/laravel/.env
Here is an example of the same, but with custom ~/.ssh/config
configuration:
$ scp examplecom:~/codes/laravel/.env ./myproject/codes/laravel/.env
To copy the file from the local computer to the remote server, you would switch the places of source and target:
$ scp ./myproject/codes/laravel/.env examplecom:~/codes/laravel/.env
rsync
To synchronize directories on the server and locally, you can use the rsync
command. This is how to do it for downloading the media/
directory (note that the trailing slashes matter):
$ rsync --archive --compress --partial --progress userhere@example.com:~/codes/project/media/ ./myproject/media/
Here is an example of the same with a custom ~/.ssh/config
configuration:
$ rsync --archive --compress --partial --progress examplecom:~/codes/project/media/ ./myproject/media/
To upload the media/
directory to the remote server, you would again switch places for the source and target:
$ rsync --archive --compress --partial --progress ./myproject/media/ examplecom:~/codes/project/media/
Only use encrypted connections for your network communications, encrypt your hard disk, and use strong passwords.
Bookmark this page so you can easily pick it up and read it again. :)