This example will setup sshd to accept soft-certificates (~/.ssh/id_rsa.pub). If a cert is not presented during login, PAM is used and both password and Yubikey are required.

  1. Install yubico:

    • Fedora 26/27: sudo dnf install pam_yubico
    • FreeBSD: pkg install -y pam_yubico
  2. SSHd config (/etc/ssh/sshd_config):

    SyslogFacility AUTHPRIV
    
    PermitRootLogin no
    MaxAuthTries 3
    LoginGraceTime 2m
    Protocol 2
    
    RSAAuthentication no
    PubkeyAuthentication yes
    PasswordAuthentication no
    ChallengeResponseAuthentication yes
    
    GSSAPIAuthentication no
    GSSAPICleanupCredentials no
    
    UsePAM yes
    
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no
    GatewayPorts no
    
    Banner /etc/issue.ssh
    
    AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
    AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
    AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
    AcceptEnv XMODIFIERS
    
    Subsystem	sftp	/usr/libexec/openssh/sftp-server
    
    AllowGroups wheel
    Match Group wheel
        X11Forwarding yes
        AllowTcpForwarding yes
        AllowAgentForwarding yes
        GatewayPorts yes
    
  3. Modify pam (/etc/pam.d/sshd):

    • Fedora 26/27:
      #%PAM-1.0
      auth	   required	pam_yubico.so id=[Your API Client ID] authfile=/etc/ssh/yubico
      auth	   required	pam_sepermit.so
      auth       substack     password-auth
      auth       include      postlogin
      -auth      optional     pam_reauthorize.so prepare
      
      account    required     pam_nologin.so
      account    include      password-auth
      
      password   include      password-auth
      
      session    required     pam_selinux.so close
      session    required     pam_loginuid.so
      session    required     pam_selinux.so open env_params
      session    required     pam_namespace.so
      session    optional     pam_keyinit.so force revoke
      session    include      password-auth
      session    include      postlogin
      -session   optional     pam_reauthorize.so prepare
      
    • FreeBSD:
      auth		required	/usr/local/lib/security/pam_yubico.so id=[Your API Client ID] authfile=/etc/ssh/yubico
      auth		sufficient	pam_opie.so		no_warn no_fake_prompts
      auth		requisite	pam_opieaccess.so	no_warn allow_local
      auth		required	pam_unix.so		no_warn try_first_pass
      
      account		required	pam_nologin.so
      account		required	pam_login_access.so
      account		required	pam_unix.so
      
      session		required	pam_permit.so
      session		optional	pam_exec.so		/root/ssh_email.sh
      
      password	required	pam_unix.so		no_warn try_first_pass
      

    Get your API Client ID here.

  4. Create a file (/etc/ssh/yubico) with your username and all Yubikey public IDs on one line:

    username1:ccccccaidjfls:ccccccdfajiojo
    username2:ccccccikdlksd
    
  5. Create a file in each user's home directory (/usr/home/.yubico/authorized_yubikeys) containing the user's name and all Yubikeys on one line:

    username:ccccccaidjfls:ccccccdfajiojo
    
  6. Restart sshd:

    • Fedora: systemctl restart sshd
    • FreeBSD: service sshd restart

For further reading, Michael W. Lucas's PAM Mastery is a good source.