How to setup YubiKey SSH authentication for Synology NAS under DSM 7: advanced users only

Synology DSM 7 supports YubiKey logins to the Synology NAS console. Because SSH access results in an equivalent, if not greater, security exposure, it makes sense to lock that door with the same level of security (it would be silly to have YubiKey secured console login but password secured SSH access with port 22 for example). Ideally, the access should only be via FIDO U2F using ed25519-sk public keys and certificates on the YubiKey to permit password-less entry and thus attain the highest security. This blog entry is aimed at recent YubiKey users that can take full advantage of ed25519-sk, such as the 5C NFC.

Debian and Android permit this setup. It works seamlessly and even handles multiple YubiKeys with the use of config files in Debian and key selection in Android. Sadly, Windows and iOS are not in the same state.

WARNING: this blog entry is not for beginners and it is very easy to lock yourself out of any SSH access and cause untold damage to your Synology NAS setup (or files). You take full responsibility for anything you do to your NAS or YubiKey and cannot rely on the contents herein. My general suggestion is to wait until it is foolproof and not use SSH until then on your Synology NAS (YubiKey sign-in on the console is foolproof and works well for example). Password protection is generally considered inadequate in this day and age.

There are instructions on the internet generally for Linux setup but the point is that they don’t fully apply to the Synology NAS–with the potential that you can damage your Synology access by blindly following the Linux instructions. This blog entry attempts to document my personal experience with my equipment and is not advice: your setup may be different and thus inapplicable. Understand what each command is doing before executing it because you can irreparably damage your setup with no easy way to recover.

Debian setup

A good starting point is here: https://bash-prompt.net/guides/bash-ssh-yubikey/.

In summary:

`ssh-keygen -t ed25519-sk`

`cat ~/.ssh/id_ed25519_sk.pub`

`ssh [username]@[synologyNAS.ip] -p [portnumber]`

`nano ~/.ssh/authorized_keys`

# prompted default file location is fine passphrase is not usually needed

# copy SSH public key string

# SSH into your Synology NAS

# edit the authorized keys list

paste the public key line, save and exit.

For the backup YubiKey: `ssh-keygen -t ed25519-sk -f ~/.ssh/id_ed25519_sk2` to ensure a different name and then copy and paste the public key string into ~/.ssh/authorized_keys as before.

Caveats:

  1. I don’t think the “Configure the SSH Server” section in the article is necessary with the Synology NAS. Everything seemed to work without adding the `PubkeyAcceptedKeysTypes` line for Synology (it may already be setup elsewhere by Synology). Altering anything in `/etc/ssh/sshd_config` on the Synology NAS is fraught with danger and it is unpredictable as to which line will work and which line will disable SSH access entirely. You have to install `nano` from the Synology community repository (see (https://think.unblog.ch/en/how-to-install-nano-on-synology-nas/)). Finally, restarting SSH seems to work only through the Synology NAS console, by unchecking SSH under the terminal panel. `systemctl restart ssh` on the SSH command line did not work for me.
  2. creating the key par with ed25519-sk works in Debian but not Windows.
  3. loading the public key to the server should be done via the SSH session to guarantee that the file permissions will not be mindlessly overwritten (which can happen when the file is edited from another operating system for example). Adding the public key via `nano ~/.ssh/authorized_keys` works well (and does not require sudo or even a restart of SSH as far as I could tell despite the instructions).
  4. There was one issue after I duplicated the steps and loaded the second public key to my backup YubiKey. I would get “sign_and_send_pubkey: signing failed for ED25519-SK ”/home/[user]/.ssh/id_ed25519_sk” from agent: agent refused operation.” Eventually it would sign in, with another touch of the YubiKey, but clearly there was something not quite right. Fortunately, there is a solution: use config files in ~/.ssh to identify each key. With a config file you can type an easy to remember shortcut you define to distinguish the keys, such as “ssh yubi1” or “ssh yubi2”, instead of “ssh [username]@[host.ip] -p [port of host]”. Read:(https://www.freecodecamp.org/news/how-to-manage-multiple-ssh-keys/). Make sure to name each YubiKey with its own id_ed25519_sk file (such as id_ed25519_sk and id_ed25519_sk2) and refer to the correct file for each key. Now SSH login works for both YubiKeys without error. Also, switching keys does not bring up any complaints from the operating system (see Windows WSL2 experience below where it is not as smooth). This ease of use for the end user may be one advantage of using FIDO or OpenPGP over PIV for YubiKey in the SSH context.
The key file to multi YubiKey existence for SSH

Android setup

From the same developers of the excellent OpenKeychain app for Android, the TermBot app supports YubiKeys in SSH (https://play.google.com/store/apps/details?id=org.sufficientlysecure.termbot&hl=en_US&gl=US). Public keys for the YubiKey are easy to add and manage and the hosts experience is fine. Of course you need to copy the public key into ~/.ssh/authorized_users just as you did in Debian (make sure to use SSH and not an external file manager to preserve the vital permissions state of all the files). Switching between YubiKeys is simply a matter of selecting which pubkey authentication you wish to use (and the app will save multiple pubkey authentications). A nice keypad opens up when the SSH session connects to unlock the YubiKey and then a NFC or USB plugin prompt shows up to use the YubiKey. The advantage of YubiKey SSH on Android is that if the phone is lost or otherwise out of your possession there is no connection with the host without both the YubiKey and the pin for the YubiKey. Then again, because you cannot access the host on your phone without the YubiKey make sure to have at least two YubiKeys set up and able to connect via SSH.

iOS setup

iOS does not support the YubiKey as far as I can tell but Termius (https://www.termius.com/) is a wonderful SSH terminal app that can use the privacy enclave in the iOS device to generate and store a private SSH key and seamlessly export a generated public SSH key to the host (so the iPad in essence acts like a YubiKey). Being able to export your SSH key to the host without having to edit the host’s authorized_user file manually is a wonderful refinement and Termius implements it well. Although not perfect, it is still better than a password.

However, should you lose your iPhone (which is an obvious risk), anyone who can access the Termius app and breach the iPhone biometrics can access your Synology NAS until you can delete the SSH key from ~/.ssh/authorized_keys. I still look forward to parity with Android in iOS as the YubiKey solution seems more robust.

Windows setup (WSL2 at any rate)

Windows OpenSSH has not reached the critical version 8.2 level, which added support for FIDO U2F hardware (and setting up SSH in Windows is a bit of a shambles in any event). To add to the confusion, there is a git OpenSSH version and a Windows OpenSSH version. You can image the gallimaufry of merriment which is possible with two different versions. My experience was that nothing was working despite a day of effort.

There are some older workarounds and guides but they look nightmarish. Fortunately, WinCryptSSHAgent, which uses the PIV function in the YubiKey, supports the YubiKey in WSL2 and Hyper-V, which is more than enough access in Windows to qualify for my purposes (https://github.com/buptczq/WinCryptSSHAgent/blob/master/doc/wsl_tutorial.md). Although organisations prefer PIV over OpenPGP, I do look forward to when OpenSSH is updated and WSL2 is on par with Debian because the current implementation using WinCryptSSHAgent still requires a few manual steps (rather than being seamless). But, WinCryptSSHAgent does work and does provide SSH with YubiKey support for the first time in Windows (at least in my experience).

I would caution that if you have already changed your pin, puk and management key the first part of the instructions should not be followed (I almost managed to mess that up before I realised that the pin I reset from default long ago was in fact the PIV pin they were referring to).

Secondly, the instructions for generating the keys seem to be outdated. Instead of `ykman piv keys generate` and `certificates generate`, the current commands that worked were `generate-key` and `generate-certificate` (notice the change from plural to singular just to add to the confusion).

Third, the whole process of using ykman was a hassle. I had to change the current directory to “c:\Program Files\Yubico\Yubikey Manager” just to get ykman to run. With YubiKey Manager directory set as my current directory, my command was:

`ykman piv generate-key --algorithm ECCP384 --format PEM --pin-policy ONCE --touch-policy CACHED 9a “%UserProfile%\Desktop\%username%_public_key_Yubikey1.pem”`

and

`ykman piv generate-certificate --valid-days 365 --subject “SSH Key” 9a “%UserProfile%\Desktop\%username%_public_key_Yubikey1.pem”`

I amended the touch policy to CACHED due to personal preference from ALWAYS and I added more detail to the filename as I was using 2 Yubikeys.

The rest of the instructions were fine and I repeated the procedure, with a different file name, for the backup YubiKey. But when I tested out both keys there was a problem in that switching back to the original YubiKey threw up a popup complaint about the YubiKey being the wrong smartcard. The joys of PIV over OpenPGP.

To solve this, I re-ran the second ykman command generating the SSH Key with the original YubiKey, unplugged the YubiKey and plugged it back in and everything was back to normal. Even with the popup the SSH sessions would still work but obviously removing these error messages makes things smoother on a daily basis (and the backup key will likely never be used).

So, if I were to do this again I would generate the backup key first so that I am left with the main key certificate in Windows when I am done. I would also probably rename the subject “SSH Key YubiKey backup” and “SSH Key YubiKey main” because now I just have two “SSH Key” entries in `certmgr.msc` and it is difficult to tell which is which.

Configuring YubiKey for SSH in WSL2 with WinCryptSSHAgent went according to the instructions. Installing WinCryptSSHAgent in Windows with `choco install wincrypt-sshagent` was very Debian-like. Installing Chocolatey if the `choco` command does not work is easy (https://chocolatey.org/install).

Finally, you need to ensure WinCryptSSHAgent is running each time Windows boots (put a shortcut of the program into the Windows startup folder), prep WSL2 with the WSL2 settings each time (right click the WinCryptSSHAgent icon on the taskbar and select the WSL2 menu option) and then finally you can SSH into your Synology NAS from WSL2.

It asked for the PIN (the YubiKey hardware PIN, not the Windows PIN for YubiKey) the very first time. You then touch the YubiKey (twice?). In subsequent sessions, you only need to touch the YubiKey. So, clearly, the WSL2 PIV experience is not as refined as the Debian FIDO experience and it is less smooth when handling multiple YubiKeys. But, after much bother and many dead ends, it does work. Still, I look forward to parity with Debian soon.

Commentary

The main reason I wanted to get this blog entry out is that my experience following the Linux install instructions was somewhat counterproductive because the Synology NAS is different from a Linux server and imposes an additional layer of control over the extremely dangerous and fragile `/etc/ssh/sshd_config` file. Synology is not kidding when they warn against sudo use, particularly in the context of Synology. Some edits to `sshd_config` were fine. Others caused the NAS console to throw an error message about how it could not restart SSL service because the network was too busy or unstable (suggesting a DNS type error when it really wasn’t). I think what is going on is that the `sshd_config` file is conflicting with Synology’s higher priority control settings and throwing a fit. For example, uncommenting the Port entry will blow up SSL and stop it from running. You must change the port number from the NAS console, not in the config file. Fortunately, you can remove password use in the `sshd_config` file and improve security that way. It ended up being a matter of trial and error. When I was locked out of SSH I had to revert back to the quaint and insecure telnet service (which is unusable in Windows). If you do need telnet, I would suggest Termius in iOS as it works nicely and at least displays a full page of readable text in nano (unlike Windows). Obviously, once you have finished repairing the `sshd_config` file you must turn telnet off for security reasons. Equally obvious, Synology probably does not want its users rooting about on the command line because so many things can be broken and finding out why would incur massive support costs. You really must know what you are doing or you can easily break things and find it difficult to repair them.

The process of setting all this up is time consuming, requires quite a bit of research for those unfamiliar with SSH, PIV and the Synology NAS, and exposes the NAS to considerable damage if you mess up—with no obvious way to recover. You can also mess up your YubiKey setup if you are blindly following directions (I nearly overrode my pin and yes, the pin being asked with the PIV function is the YubiKey hardware pin, not the usual Windows pin–I really wish YubiKey had three distinct and consistent terms for each of these “pins”).

Even when you have everything set up, if you make the mistake of adding another authorised user incorrectly, say via the Synology share in Windows file explorer (because it was convenient at the time), you can still manage to lock yourself out of SSH (because Windows disrupts the very specific permissions requirements imposed on these files by SSH–thank you (https://phoenixnap.com/kb/ssh-with-key) for the critical information on permissions: set permissions to `chmod 700 ~/.ssh` and `chmod 600 ~/.ssh/authorized_keys` if you are getting permission denied (publickey) SSH errors). Traps like this are annoying and require quite a bit of Linux knowledge to avoid.

I think Synology is imposing an additional layer on top of the usual Linux bits and this, while good for security, can also render SSH inoperable with no obvious way to recover.

So yes, this blog entry is not for beginners. Instead, it is aimed at those generally proficient but as a warning so hopefully some reader can avoid the traps I fell into when setting up SSH for the Synology NAS with YubiKeys. It is a pity because SSH is foundational to so many services and securing SSH should be bog standard. Each individual user will have to confront a choice of either not using SSH at all (the safe choice), using SSH because they must but with passwords (risky eventually) or rooting about with SSH and YubiKeys (which can blow up easily and unpredictably depending on your skill and knowledge because the Synology part is not the same as Linux even if it is similar and the proprietary bits are what blow up when they conflict with the Linux parts).

2 thoughts on “How to setup YubiKey SSH authentication for Synology NAS under DSM 7: advanced users only”

  1. Hi 👋
    Great article but despite all my efforts I still got a sign_and_send_pubkey: signing failed for ED25519-SK error.

    I’m on macOS using the brew build of OpenSSH since macOS version doesn’t come with the –with-security-key-builtin flag

    Like

Leave a comment