--- title: YubiKey date: 2020-05-14 --- {% extends 'templates/base.html' %} {% block body %}

{{ title }}

{% markdown %} This article contains tips & tricks for using [YubiKeys](https://www.yubico.com) for authentication. [TOC] ## `sudo` over SSH using YubiKey Remembering root passwords for machines is annoying and error-prone. You can reuse the same passwords and be insecure. You can use different passwords and forget them. You can type them into IRC and then have to reset them. But there is a better way. In modern Linux & Unix systems, [Pluggable Authentication Modules (PAM)](https://en.wikipedia.org/wiki/Pluggable_authentication_module) can provide multiple ways of authenticating a user. The most common one is "asking for a password", but they can also query external network services or require a second factor. The module `pam_ssh_agent_auth` authenticates users by checking against SSH keys from a connected SSH agent, which means that we can have passwordless `sudo` when logged in remotely. Using `pam_ssh_agent_auth` with a YubiKey is both more convenient and more secure than passwords: you only need to tap the YubiKey, and because you _need_ to tap the YubiKey, becoming root requires a physical action on your part. NB: Technically this allows all SSH keys loaded into the SSH Agent to be used to become root. If you have a mixture of YubiKey keys and on-disk SSH keys, I would recommend using `ssh-askpass` / `SSH_ASKPASS` to require confirmation. ### Debian & Ubuntu TL;DR: - Install `pam_ssh_agent_auth`. - Enable `pam_ssh_agent_auth` for use with `sudo`. - Allow `sudo` to maintain access to `SSH_AUTH_SOCK`. - Connect to our remote machine with _SSH agent forwarding_ and never have to remember a server password again. On your remote machine, first install the SSH agent authentication PAM: ```sh $ apt install libpam-ssh-agent-auth ``` Then, enable and configure the PAM module for use with `sudo`: ```sh $ cat /etc/pam.d/sudo #%PAM-1.0 # Allow users to use their regular authorized SSH keys for sudo, # and allow them to manage the keys themselves. auth sufficient pam_ssh_agent_auth.so file=~/.ssh/authorized_keys allow_user_owned_authorized_keys_file # # Alternatively, have a single central key file, owned by root. # # This is useful if you only want a subset of SSH keys to grant root permissions. # auth sufficient pam_ssh_agent_auth.so file=/etc/ssh/sudo_authorized_keys @include common-auth @include common-account @include common-session-noninteractive ``` Allow `sudo` to maintain access to the SSH agent by keeping `SSH_AUTH_SOCK`: ```sh $ cat /etc/sudoers Defaults env_keep += SSH_AUTH_SOCK Defaults env_reset Defaults mail_badpass Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # User privilege specification root ALL=(ALL:ALL) ALL # Allow members of group sudo to execute any command %sudo ALL=(ALL:ALL) ALL ``` To test it, connect to the machine with `ssh -A server.example.com`, and try using `sudo`: it should _not_ ask for a password, and the YubiKey should flash for a tap. For convenience, add `ForwardAgent yes` to the relevant hosts your SSH config to set `-A` by default: ```sh $ cat ~/.ssh/config Host server.example.com ForwardAgent yes Host 192.168.16.* ForwardAgent yes ``` ### NixOS On [NixOS](https://nixos.org), the configuration for the server is much simpler: ```sh $ cat /etc/nixos/configuration.nix { config, pkgs, ... }: { . . . security.pam.enableSSHAgentAuth = true; security.pam.services.sudo.sshAgentAuth = true; users.users.eth.openssh.authorizedKeys.keys = [ "ssh-rsa . . .", "ssh-rsa . . .", ]; } ``` To test it, connect to the machine with `ssh -A server.example.com`, and try using `sudo`: it should _not_ ask for a password, and the YubiKey should flash for a tap. For convenience, add `ForwardAgent yes` to the relevant hosts your SSH config to set `-A` by default: ```sh $ cat ~/.ssh/config Host server.example.com ForwardAgent yes Host 192.168.16.* ForwardAgent yes ``` {% endmarkdown %}
{% endblock %}