# How to configure SSH

In order to use {{SSH_Monitor}},
you will have to configure the {{SSH}} connection between the {{target}} computer(s) you want to monitor
(e.g. with IP `192.168.2.3`)
and the computer who will {{host}} the {{EPICS}} {{IOC_machine}} running {{SSH_Monitor}}
(e.g. with IP `192.168.1.1`).

As a prerequisite,
[openssh](https://repology.org/project/openssh/versions) should be installed on the {{target}}(s) and the {{host}}:

* E.g. with `emerge`: `$ sudo emerge -a net-misc/openssh`
* E.g. with `pacman`: `$ sudo pacman -S openssh`
* E.g. with `apt`: `$ sudo apt install openssh openssh-server`
* E.g. with `yum`: `$ sudo yum install openssh`
* E.g. with `dnf`: `$ sudo dnf install openssh`

Then, configure {{SSH}} by following the below steps:

* Make sure `sshd` is running on the {{target}}(s), e.g. on `systemd` based distro:

    ```{code} bash
    target-pc $ systemctl status sshd
    ```

    If `sshd` is not active and running, execute the following commands, e.g. on `systemd` based
    distro:

    ```{code} bash
    target-pc $ sudo systemctl enable sshd
    target-pc $ sudo systemctl start sshd.service
    ```

* It is recommended to create a dedicated user for monitoring
  (e.g. `sshmonitor-user`) on the {{target}}(s):

    ```{code} bash
    target-pc $ sudo useradd --create-home sshmonitor-user # don't miss the `--create-home` option
    target-pc $ sudo passwd sshmonitor-user
    ```

```{important}
The user you want for monitoring should have a home directory 
(thus the `--create-home` option).
This is needed because `$HOME/.ssh/authorized_keys` is the default location\
-- the `AuthorizedKeysFile` location --\
used by `sshd` to manage key-based authentifications
(the authentification method used here).\
So, if you are creating a dedicated user
(e.g. `sshmonitor-user`)\
then don't miss the `--create-home` option
in order to create a dedicated home directory,\
and if you are using an existing user then make sure this user has a `$HOME`.
```

```{warning}
If you can't or don't want to create a home directory,\
it is still possible to configure `sshd` in order to change the `AuthorizedKeysFile` location\
(and move it away from `$HOME`).
Like described [here](https://unix.stackexchange.com/a/136681).\
**But beware: this will affect every other user on the system!**
```

* Create a dedicated {{SSH}} key pair on the {{host}}
  (with the user that will run the monitoring {{IOC}}):

    ```{code} bash
    host-pc $ cd $HOME
    host-pc $ mkdir .ssh
    host-pc $ ssh-keygen -o -t ed25519 -f "/home/host-username/.ssh/host_to_target_ssh_monitor_ed25519_key" -N ""
    ```

```{important}
**Remember the path where is located the private key\
(i.e. `/home/host-username/.ssh/host_to_target_ssh_monitor_ed25519_key`),\
you will need this path when configuring the {{cmd}} file\
during the upcoming [`.cmd` and `.substitutions` configuration how to](./cmd_and_sub_how_to.md).\
More specifically,
you will need it when setting the `SSH_OPTS_AND_ARGS` {{macro}}\
(with the `-i /home/host-username/.ssh/host_to_target_ssh_monitor_ed25519_key` {{SSH}} option).**
```

```{seealso}
The `SSH_OPTS_AND_ARGS` {{macro}} will be introduced in the
[`.cmd` and `.substitutions` how-to](./cmd_and_sub_how_to.md#substitutions-creation-and-configuration),\
and more details can be found about it in the
[`.cmd`, `.template` and `.substitutions` explanations](../../explanations/cmd_and_template_and_sub_explanations.md#the-global----part).

But briefly, it allows you to configure your {{SSH}} connection the way you want,\
i.e. with the {{SSH_opts_and_args}}
described by `man ssh` on the {{host}} machine\
(the same options and arguments that you would use for a {{SSH_command}} on the {{host}}).
```

```{note}
If the remote user (the one you are connecting to) has an empty password,\
then you actually don't need to setup a key-based {{SSH}} connection.\
A regular {{SSH}} connection will be enough\
because there will be no password prompt interrupting the {{SSH_Monitor}} {{IOC_program}}.

**However, It is strongly recommended to not allow empty passwords for your users\
(for obvious security reasons)\
and to setup a key-base {{SSH}} connection (like described here).**
```

* Copy and authorize the public key from {{host}} to the
  {{target}}(s):

    ```{code} bash
    host-pc $ ssh-copy-id -i $HOME/.ssh/host_to_target_ssh_monitor_ed25519_key.pub sshmonitor-user@192.168.2.3
    ```

    ```{admonition} Troubleshooting
    If the above command doesn't work for whatever reason, and you have to copy the public key manually,\
    then refer to <web-archive:20220223140333/https://linuxhandbook.com/add-ssh-public-key-to-server/>.
    ```

* Make sure you don't have to enter a password in order to execute a {{SSH_command}}\
  (e.g. with the `uname -a` {{shell_instruction}}):

    ```{code} bash
    host-pc $ ssh -i $HOME/.ssh/host_to_target_ssh_monitor_ed25519_key sshmonitor-user@192.168.2.3 "uname -a"
    ```

    ```{admonition} Troubleshooting
    If you still have to enter a password, make sure the {{target}} `sshd` server is well configured,\
    i.e. check the `/etc/ssh/sshd_config` file,\
    and make sure the following options are configured appropriately:
    * `PubkeyAuthentication` should **not** be set to `no` (default is `yes`).
    * `ChallengeResponseAuthentication` should be set to `no`.
    * `AuthorizedKeysFile` should be set to `.ssh/authorized_keys`.
    * If `StrictModes` is set to `yes` (which is a sane default), then please make sure that:
      * The {{target}} `$HOME/.ssh` folder has the following permissions:\
        `drwx------`\
        if not, run: `$ chmod 700 $HOME/.ssh`.
      * The {{target}} `~/.ssh/authorized_keys` file has the following permissions:\
        `-rw-------`\
        if not, run: `$ chmod 600 $HOME/.ssh/authorized_keys`.
      * The {{target}} `$HOME/.ssh` folder is own only by `sshmonitor-user`\
        (or whatever {{target}} username)\
        if not, run:\
        `$ chown -R target-username:target-username /home/target-username/.ssh`
    * `MaxSessions` is set to `10` by default,\
      it should be enough\
      but you might need to allow more concurrent {{SSH}} sessions if you have specific needs.
    * `MaxStartups` is set to `10:30:100` by default\
      (see <https://stackoverflow.com/questions/4812134/in-sshd-configuration-what-does-maxstartups-103060-mean>),\
      it should be enough\
      but you might need to allow more concurrent unauthenticated {{SSH}} connections if you have specific needs.
    
      And don't forget to restart the `sshd` service if `/etc/ssh/sshd_config` has been modified,\
      e.g. on `systemd` based distro:

            target-pc $ sudo systemctl restart sshd.service
    ```

    ```{admonition} Troubleshooting
    If you still have to enter a password, try to run {{SSH}} with the `-v` (verbose) option, like so:
    
        host-pc $ ssh -v -i $HOME/.ssh/host_to_target_ssh_monitor_ed25519_key sshmonitor-user@192.168.2.3 "uname -a"
    
    * If you come across messages like: 

        > send_pubkey_test: no mutual signature algorithm

      this is probably because your {{host}} has a more recent SSH server than your {{target}},\
      and that you are still using RSA keys instead of ED25519.\
      See
      <web-archive:20231215141621/https://confluence.atlassian.com/bitbucketserverkb/ssh-rsa-key-rejected-with-message-no-mutual-signature-algorithm-1026057701.html>
      for more details.
    
      In this case you can either upgrade your keys to ED25519\
      (like described in this how-to, which is the recommended solution for security reasons),\
      or you can add the `-oPubkeyAcceptedKeyTypes=+ssh-rsa` option to explicitly accept RSA keys like so:
    
            host-pc $ ssh -oPubkeyAcceptedKeyTypes=+ssh-rsa -i $HOME/.ssh/ssh_monitor_rsa_key sshmonitor-user@192.168.2.3 "uname -a"`
    
    * If you come across messages like: 

        > no matching host key type found. Their offer: ssh-dss

      this is probably because you have a "legacy" {{target}}
      (i.e. it is way too old!).\
      See <web-archive:20231215142327/http://www.openssh.com/legacy.html> for more
      details.
    
      In this case you can either update the {{SSH}} server of your {{target}} to a more modern one\
      (which is the recommended solution for security reasons),\
      or you can add the `-oHostKeyAlgorithms=+ssh-dss` option like so:
    
            host-pc $ ssh -oHostKeyAlgorithms=+ssh-dss -i $HOME/.ssh/host_to_target_ssh_monitor_ed25519_key sshmonitor-user@192.168.2.3 "uname -a"`
    
    * If you come across messages like:

        > no matching key exchange method found. Their offer: diffie-hellman-group1-sha1

      this is probably because you have a "legacy" {{target}}
      (i.e. it is way too old!).\
      See
      <web-archive:20231215142327/http://www.openssh.com/legacy.html> for more
      details.
    
      In this case you can either update the {{SSH}} server of your {{target}} to a more modern one\
      (which is the recommended solution for security reasons),\
      or you can add the `-oKexAlgorithms=+diffie-hellman-group1-sha1` option like so:
    
            host-pc $ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 -i $HOME/.ssh/host_to_target_ssh_monitor_ed25519_key sshmonitor-user@192.168.2.3 "uname -a"`
    ```

---

## Sources

* <https://wiki.archlinux.org/title/OpenSSH>
* <https://wiki.archlinux.org/title/SSH_keys>
* <https://wiki.archlinux.org/title/SSH_keys>

