DevOps for Node.js Engineers: Secure Shell (SSH)

DevOps for Node.js Engineers: Secure Shell (SSH)


Accessing remote computers securely!




Use cases for SSH

Common cases are:

  • copy files to a server
  • install software on a server
  • take control of the device of some poor fellow…

SSH stands for Secure Shell.

It is a network protocol that gives you a secure way to access a computer over the internet. It also refers to the suite of tools that implement that network protocol.

Two ways to authenticate on a remote server:

  • username + password
  • - server admin creates a user on a remote server 
  • - users can then connect with the username + password
  • -
  • SSH key pair
  • - more secure than username + password
  • - the client device creates a SSH key pair (public and private keys)
  • - private key = secret key (stored securely on client machine)
  • - public key = public (can be shared, on remote server for example).

By installing the public key on the remote server, you can tell that server that the client device that the public key belongs to is safe to allow connections from. The client can unlock the public key with its private key. The combination of these associated two keys proves authentication.

Each user creates its own key pair on their machine and the admin of the remote server adds the public key to that server. After that, they can connect to the remote server from their machine by providing the SSH private key when connecting.

If the public key of a user is not registered on the remote server, that user cannot connect to it.




SSH for services

You can use SSH authentication not just for users but also for other services connecting to a remote server.

For example, Jenkins (continuous delivery server) may access a server via SSH to copy files from it or to execute some script there, for example. For that, you create a Jenkins user on an application server, then create a SSH key pair on that Jenkins server. Finally, you add the public SSH key to the authorized_keys file on the target remote server.




Firewall and port 22

In order to connect via SSH, the firewall must allow connections to the port 22 which is the standard port for the SSH network protocol.

DevOps for Node.js Engineers: Linux Networking

Basic concepts of networking with practical examples!itnext.io

By default, access o the port 22 is blocked.

SSH authentication comes after the connection to the remote server. First, the connection to the port 22 must be allowed in the firewall before the authentication can be processed.

Most operating systems have a SSH service listening by default on port 22 for SSH requests. Again, the SSH server listens on port 22.

There must be a firewall rule o allow access on port 22 otherwise every SSH requests to that server will fail. This is a common error when attempting to SSH into a virtual machine on a cloud provider and you forgot to open the port 22 for your IP address.

In the firewall rule to allow requests on port 22, the source (which IP address or IP range can access the server on this port) should be restricted to specific IP addresses and NOT open to the entire world. SSH connections give you access to the entire remote system.




SSH in practice

I will give you an example with Digital Ocean. You don need to create an account, just understand the principles. On Digital Ocean, by default, all ports are open (zero security…you need to close them explicitly) so no need to create a firewall rule to open port 22. On AWS, by default, all port are closed and you will need to create rule in a security group to allow SSH access. Also on AWS, you are prompted to generate a key pair when creating virtual machines.

Create a Droplet (virtual server) with the default settings (choose the Ubuntu OS and the cheapest CPU option).

In the authentication section, select password and type it in the create root password field. That password will be used to connect to the server.

Finally, click on create droplet.

Select the created droplet (Ubuntu-xyz-abc), you will its public IPv4 address, copy it.

Connect via SSH using password

To connect to the remote server, in your local terminal:

ssh <USER>@<SSH_SERVER_IP_ADDRESS_OR_HOSTNAME>
# example
ssh root@158.88.15.91
ssh user2@toto.com

You will be asked if you are sure you want to connect to that server, type yes. As a general rule avoid connecting via SSH to server you don’t know, they might be malicious.

Next, you will be asked to enter the password defined during droplet creation.

You will then see that your command prompt will change and display information about the remote server:

root@ubuntu-xyz-abc: ~#
# note that # indicates that you are logged in with the root user ($ with non-root user)
# command prompt on server:
#   <USER>@<REMOTE_SERVER_NAME>:<CURRENT_PATH><PROMPT_DELIMITER>

In real projects, you should NEVER log in as root into a virtual server because that user has all power on the machine. If you local computer or the remote server is compromised…you get the point.

In some real world circumstances, it is also prohibited to SSH into remote machines (port 22 is closed) and you use IaC (Infrastructure as Code) tools to configure your remote machines.

Anyways back to our droplet.

Generate SSH key pair

Open a new terminal tab and keep the terminal window with the SSH connection open.

That new tab is a local terminal. Let’s create a SSH key pair to avoid entering a password when connecting via SSH. The password authentication (symmetric cryptography) should be your last resort, always prefer SSH key pair (asymmetric cryptography). Again, if you don’t need SSH, close the port 22.

Now look at the content of the $HOME/.ssh directory:

ls -l ~/.ssh

you will see a file named known_hosts, it was created when first connecting to the remote server.

Now, to create the SSH key pair:

ssh-keygen -t rsa
# creating a key pair of type (-t) RSA (cryptographic algorithm)

the default location where the key pair is stored is $HOME/.ssh. When prompted, give a meaningful name to your key pair. For additional security, you are asked to create a passphrase, leave it blank if you don’t want to set it.

Your key pair is now generated. Of course, a pair means that two things are created in the .ssh directory, a private key and a public key.

happy_bot_rsa 
# private key (no sharing, stays on your local machine)
happy_bot_rsa.pub         
# public key

Add public key to authorized_keys

In order to connect using SSH, on the remote server, locate the authorized_keys file in the .ssh folder (if it does not exist, create it)

vim ~/.ssh/authorized_keys     # on the remote server

The authorized_keys file (on the remote server) is where you add the public key generated on your local machine. This is a list of public keys of devices allowed to connect via SSH to the server.

Copy the content of the file with the .pub extension (on your local machine) and paste it into the authorized_keys file of the server and save the modification.

Now stop the SSH connection by typing exit .

When you reconnect to the server, you will not be asked for a password (unless you set a passphrase when generating the SSH key pair).

If you have multiple SSH key pairs in .ssh, you need to indicate which one to choose to connect to the server, you do this like so:

ssh -i <PATH_TO_PRIVATE_KEY> <USER>@<IP_OR_HOSTNAME>
# example
ssh -i ~/.ssh/happy_bot_rsa ubuntu@168.43.55.23



Copy files to remote server

To copy local files to the remote server, use:

scp -i <PATH_TO_PRIVATE_KEY> <LOCAL_PATH> <USER>@<IP>:<REMOTE_PATH>
# example
export PRIV_KEY_PATH=~/.ssh/happy_bot_rsa
export L_PATH=~/Documents/file1.sh
export R_USER=ubuntu
export SERVER_URL=168.43.55.23
export R_PATH=~/scripts
scp -i $PRIV_KEY_PATH $L_PATH_$R_USER@$SERVER_URL:$R_PATH
# scp stands for secure copy, allows to copy files and directories, using encryption



SSH with Node.js

Yes, you can actually establish SSH connections using Node!

It can be useful to automate all the things you do interactively at the command prompt.

You can use packages like:

GitHub - mscdex/ssh2: SSH2 client and server modules written in pure JavaScript for node.js

SSH2 client and server modules written in pure JavaScript for node.js - GitHub - mscdex/ssh2: SSH2 client and server…github.com

You can see an example here:

How to SSH using Node.js

Quick tip on how to build an application that will SSH to servers and run commands using Node.js.medium.com




That’s it

See you in the next article.

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics