= Establishing SSH connections

:Author: Seth Kenlon
:Email: <seth@opensource.com>
:Date: 2020-08-25
:Revision: 1.0

One of the most appealing features of Linux is not just the ability to skillfully use a computer with nothing but commands entered into the keyboard, but to do that on computers anywhere in the world.
Thanks to OpenSSH, [POSIX](https://opensource.com/article/19/7/what-posix-richard-stallman-explains) users can open a secure shell on any computer they have permission to access, and use the computer from a remote location.
It's a daily task for many Linux users, but it can be confusing for someone who has yet to try it.
This article explains how to configure two computers for SSH connections, and how to securely connect from one to the other without a password.

== Terminology

When discussing more than one computer, it can be confusing to identify one from the other.
The IT community has well-establish terms to help clarify descriptions of the process of networking computers together.

.Bullet
* service: Software. The term _service_ implies (but does not insist) that it's software without a graphical interface, but runs in the background so it can be used by computers other than the one it's installed on. For instance, a web server hosts a web sharing _service_.
* host: A host is any computer. In IT, computers are called a _host_ because technically any computer can host an application that's useful to some other computer. You might not think of your laptop as a "host", but you're likely running some service that's useful either to yourself, your mobile, or some other computer.
* local: The computer either you or some software are using. Every computer refers to itself as `localhost`, for example.
* remote: A computer you're not physically in front of, or are not physically using. A computer in a _remote_ location.

Now that the terminology is settled, you can begin.

== Activate SSH on each host

For two computers to be connected over SSH, each host must have SSH installed.
SSH has two components: the command you use on your local machine to start a connection, and a _server_ to accept incoming connection requests.
Some computers come with one or both parts of SSH already installed.
The commands vary, depending on your system, to verify whether you have both the command and the server installed, so the easiest method is to look for the relevant configuration files.

[source,bash]
----
$ file /etc/ssh/ssh_config
/etc/ssh/ssh_config: ASCII text
----

Should this return a `No such file or directory` error, then you don't have the SSH command installed.

Do a similar check for the SSH service (note the `d` in the filename):

[source,bash]
----
$ file /etc/ssh/sshd_config
/etc/ssh/sshd_config: ASCII text
----

Install one or the other, as needed:

[source,bash]
----
$ sudo dnf install openssh-clients openssh-server
----

On the remote computer, enable the SSH service with systemd:

[source,bash]
----
$ sudo systemctl enable --now sshd
----

Alternately, you can enable the SSH service from within System Settings on GNOME or System Preferences on MacOS.
On the GNOME desktop, it's located in the *Sharing* panel:

image:remote-login-activate.webp[Activate SSH in System Settings]

== Start a Secure Shell

Now that you've installed and enabled SSH on the remote computer, you can try logging in with a password, as a test.
In order to access the remote computer, you must have a user account and a password.

Your remote user doesn't have to be the same as your local user.
You can log in as any user on the remote machine as long as you have that user's password.
For instance, I'm `sethkenlon` on my work computer, but I'm `seth` on my personal computer.
If I'm on my personal computer (making it my current local machine) and I want to SSH into my work computer, I can do that by identifying myself as `sethkenlon` and using my work password.

To reach the remote computer, you must know its IP address, or else you must be able to reach the remote computer.
To find the IP address of the remote machine, use the `ip` command (on the remote computer):

[source,bash]
----
$ ip addr show | grep "inet "
inet 127.0.0.1/8 scope host lo
inet 10.1.1.5/27 brd 10.1.1.31 [...]
----

If the remote computer doesn't have the `ip` command for whatever reason, try `ifconfig` instead (or even `ipconfig` on Windows).

The address 127.0.0.1 is a special one, and is in fact the address of `localhost`.
It's a "loopback" address, which your system uses to reach itself.
That's not useful when logging into a remote machine, so in this example, the correct IP address of the remote computer is 10.1.1.5.
In real life, I would know that because my local network uses the 10.1.1.0 subnet.
If the remote computer is ona different network entirely, then the IP address could be nearly anything (never 127.0.0.1, though) and some special routing is probably necessary to reach it through various firewalls.
Assume your remote computer is on the same network, but if you're interested in reaching computers more remote than your own network, read my article about http://opensource.com/LINK/TO/MY/ARTICLE[opening ports in your firewall].

If you can ping the remote machine, and you have a login account on it, then you can now SSH into it.

[source,bash]
----
$ ping -c1 10.1.1.5
PING 10.1.1.5 (10.1.1.5) 56(84) bytes of data.
64 bytes from 10.1.1.5: icmp_seq=1 ttl=64 time=4.66 ms
----

That's a success.
Now use SSH to login:

[source,bash]
----
$ whoami
seth
$ ssh sethkenlon@10.1.1.5
bash$ whoami
sethkenlon
----

The test login works, so now you're ready to activate passwordless login.

== Create an SSH key

To login securely to another computer without a password, you must have an SSH key.
You may already have an SSH key, but it doesn't hurt to create a new one.
An SSH key begins its life on your local machine.
It consists of two components: a private key, which you never share with anyone or anything, and a public one, which you copy onto any remote machine you want to have passwordless access to.

Some people create one SSH key and use it for everything from remote logins to Gitlab authentication.
For myself, however, I use different keys for different groups of tasks.
For instance, I use one key at home to authenticate to local machines, a different key to authenticate to web servers I maintain, a different one for Git hosts, another for Git repositories I host myself, and so on.
In this example, I create a unique key for use on computers within my local area network.

To create a new SSH key, use the `ssh-keygen` command:

[source,bash]
----
$ ssh-keygen -t ed25519 -f ~/.ssh/lan
----

The `-t` option stands for _type_, and ensures that the encryption used for the key is higher than the default.
The `-f` option stands for _file_, and sets the key file name and location.
After running this command, you're left with an SSH private key called `lan` and an SSH public key called `lan.pub`.

To get the public key over to your remote machine, use the `ssh-copy-id`.
For this to work, you must have verified that you do have SSH access to the remote machine.
If you can't login to the remote host with a password, you can't set up passwordless login either.

[source,bash]
----
$ ssh-copy-id -i ~/.ssh/lan.pub sethkenlon@10.1.1.5
----

During this process, you're prompted for your login password on the remote host.

Upon success, try logging in, but this time use the `-i` option to point the SSH command to the appropriate key (`lan`, in this example).

[source,bash]
----
$ ssh -i ~/.ssh/lan sethkenlon@10.1.1.5
bash$ whoami
sethkenlon
----

Repeat this process for all computers on your network, and you'll be able to wander through each host without ever thinking about passwords again.
In fact, once you have passwordless authentication set up, you can edit the `/etc/ssh/sshd_config` file to disallow password authentication.
This prevents anyone from using SSH to authenticate to a computer unless they have your private key.
To do this, open `/etc/ssh/sshd_config` in a text editor with `sudo` permissions and search for the string `PasswordAuthentication`.
Change the default line to this:

[source,bash]
----
PasswordAuthentication no
----

Save it and restart the SSH server (or just reboot).


[source,bash]
----
$ sudo systemctl restart sshd && echo "OK"
OK
$ 
----

== Using SSH every day

OpenSSH changes your view of computing.
No longer are you bound to just the computer in front of you.
With SSH, you have access to any computer in your house, or servers you have accounts on, and even mobile and IoT devices.
Unlocking the power of SSH leads to unlocking the power of the Linux terminal.
If you're not using SSH every day, start using it.
Get comfortable with it, collect some keys, live more securely, and expand your world.

