In this post, I will cover the usages of a Yubikey for:
- Protect local sudo command,
- Protect local gnome login screen,
- Protect local tty screen,
- Protect remote ssh connections.
PROTECTING LOCAL SUDO
sudo apt update && sudo apt upgrade -y sudo apt install libpam-u2f -y mkdir -p ~/.config/Yubico pamu2fcfg > ~/.config/Yubico/u2f_keys sudo nano /etc/pam.d/sudo
Add the line in bold after the mentioned line:
@include common-auth auth required pam_u2f.so
It is complete. Try to use the sudo command with and without the Yubikey connected.
The Yubikey will flash asking to touch its button to allow the command to go through.
PROTECTING LOCAL GNOME LOGIN
sudo nano /etc/pam.d/gdm-password
Add the line in bold after the mentioned line:
@include common-auth auth required pam_u2f.so
PROTECTING LOCAL TTY SCREEN
sudo nano /etc/pam.d/login
Add the line in bold after the mentioned line:
@include common-auth auth required pam_u2f.so
PROTECTING REMOTE SSH
sudo apt update && sudo apt upgrade -y sudo add-apt-repository ppa:yubico/stable sudo apt install libpam-yubico -y sudo nano /etc/ssh/yubikeys
Add one line for each user followed by the first 12 characters of its own Yubikey:
usera:f8v6d6f687d6 userb:df98b67d7b68:adf1n98b7kf5 userc:edf8n98b7nf6
Create API credentials at the Yubikey website. Go to https://upgrade.yubico.com/getapikey.
Edit the PAM configuration file for the SSH server:
sudo nano /etc/pam.d/sshd
Add the following line at the top of the document replacing the ID and KEY from the API:
auth required pam_yubico.so id=ID key=KEY mode=client debug authfile=/etc/ssh/yubikeys
The most popular keyboard-interactive options are:
- required (OTP and Password have to be met),
- sufficient (OTP or Password have to be met).
Then edit the file:
sudo nano /etc/ssh/sshd_config
And make sure both of the following configurations are enabled:
ChallengeResponseAuthentication yes UsePAM yes AuthenticationMethods publickey,keyboard-interactive
It requires both methods to be met:
- publickey (SSH-Key),
- and keyboard-interactive (what comes out of the PAM).
To allow one specific user to connections only with ssh-key append:
Match User userd AuthenticationMethods publickey
Restart the service:
sudo systemctl restart ssh
PROTECTING REMOTE SUDO
sudo nano /etc/pam.d/sudo
Add the following line at the top of the document replacing the ID and KEY from the API:
auth required pam_yubico.so id=ID key=KEY mode=client authfile=/etc/ssh/yubikeys
PROTECTING REMOTE RASPBERRY PI’s SSH
Following the same steps to protect the SSH you may realize that the repo below does not exist for RPi:
sudo add-apt-repository ppa:yubico/stable
But do not let it stop you. It will work the same way.
USING ANSIBLE WITH 2FA
There are many workaround solutions that simply create bypass conditions for the Ansible, such as allowing root from a certain address or network:
Match Address 10.1.1.0/24,192.168.111.222 PermitRootLogin yes
Or to suppress the 2FA for a specific user that only Ansible uses:
Match User ansible_user AuthenticationMethods publickey
But the best way for making the 2FA prompt to the Ansible that will enter the OTP is inserting the following configuration to the /etc/ansible/ansible.cfg:
[ssh_connection] ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey,keyboard-interactive
Note: Ansible executes the requests to many servers in parallel (to improve performance) for each module execution, so consider serializing the execution giving it an order to follow to prevent overlapping of the OTP prompts (if more than one server requires OTP).
serial: 1 order: inventory
The order can be: inventory, reverse_inventory, sorted, reverse_sorted, or shuffle