Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/carniz/ubuntu-yubikey-setup

A guide for setting up Yubikey support on an Ubuntu 18.04 / 20.04-based distribution (such as elementaryOS 5.x / 6.x)
https://github.com/carniz/ubuntu-yubikey-setup

elementaryos ubuntu yubikey

Last synced: about 1 month ago
JSON representation

A guide for setting up Yubikey support on an Ubuntu 18.04 / 20.04-based distribution (such as elementaryOS 5.x / 6.x)

Awesome Lists containing this project

README

        

# ubuntu-yubikey-setup

This is a guide for configuring an Ubuntu 18.04/20.04-based distribution (such as elementaryOS 5.0 "Juno" / elementaryOS 6.0 "Odin") with:
* Yubikey-backed full disk encryption (using challenge-response mode)
* System wide Yubikey login (graphical lightdm + non-graphical TTYs)
* Yubikey challenge-response mode for SUDO
* FIDO U2F authentication
* Yubikey for SSH authentication

## Prerequisites
- An existing installation of an Ubuntu 18.04/20.04-based distro with full-disk encryption
- A 2-pack of Yubikeys (version 5 NFC), if you only have one Yubikey you can skip the steps for the second key.

### Add the Yubico APT repository (NOTE: not needed for Ubuntu 20.04)
```
sudo apt install software-properties-common # provides add-apt-repository
sudo add-apt-repository ppa:yubico/stable && sudo apt-get update
```

### Install required packages
```
sudo apt install libpam-yubico yubikey-manager
```

### For each yubikey:
If you require that the Yubikey must be touched for each challenge-response operation, pass `--touch` to `ykman otp chalresp`. This greatly enhances the security of the challenge-response mode since it needs a physical confirmation.
```
ykman otp chalresp --touch --generate 2
ykpamcfg -2
```
If you on the other hand want the key to automatically send a response to each challenge, omit the `--touch`. **Note that this is less secure since a malicious script could get a response from the key without your permission.**
```
ykman otp chalresp --generate 2
ykpamcfg -2
```

### Require yubikey for system-wide authentication
This will require a yubikey present for graphical (lightdm) logins, non-graphical logins on TTYs, as well as `sudo`:

```
echo "auth required pam_yubico.so mode=challenge-response" | sudo tee -a /etc/pam.d/common-auth
```

### Full disk encryption setup

Install the `yubikey-luks` package:
```
sudo apt install yubikey-luks
```
If you are unsure of which device that contains your LUKS partition, run `lsblk`. In the below example, the device is `/dev/sda3`:
```
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 1 119,3G 0 disk
├─sda1 8:1 1 512M 0 part /boot/efi
├─sda2 8:2 1 732M 0 part /boot
└─sda3 8:3 1 118G 0 part
└─sdb3_crypt 253:0 0 118G 0 crypt
├─elementary--vg-root 253:1 0 117G 0 lvm /
└─elementary--vg-swap_1 253:2 0 976M 0 lvm [SWAP]
nvme0n1 259:0 0 953,9G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part
├─nvme0n1p2 259:2 0 937,5G 0 part
└─nvme0n1p3 259:3 0 15,9G 0 part
```
List key slots for your LUKS device (only slot 0 should be used by default)
```
sudo cryptsetup luksDump /dev/sda3
```
Configure slot 1 for yubikey number 1:
```
sudo yubikey-luks-enroll -d /dev/sda3 -s 1
```
Configure slot 2 for yubikey number 2:
```
sudo yubikey-luks-enroll -d /dev/sda3 -s 2
```
*Hint: You will be asked to enter the `yubikey challenge password`. This is a password you can choose, which will be used for unlocking the yubikey prior to unlocking the FDE.*

Now restart your computer. Once verified that the yubikey can be used to unlock the disk, remove the default slot for the static password (slot 0):
```
sudo cryptsetup -q luksKillSlot /dev/sda3 0
```

**Update for Ubuntu 20.04:**
The Yubikey won't get used for unlocking the disk with Ubuntu 20.04 / elementaryOS 6 unless you first run the below:
```
sudo sed -i 's|none luks|none luks,keyscript=/usr/share/yubikey-luks/ykluks-keyscript,discard|' /etc/crypttab
sudo update-initramfs -u
```

### Lock the screen when yubikey is removed
Install the `finger` package:
```
sudo apt install -y finger
```
**NB: For elementaryOS 6.x you'll also need to install gnome-screensaver:**
```
sudo apt install -y gnome-screensaver
```

Create the `yubikey-removed-script`:
```
cat << 'EOF' | sudo tee /usr/local/bin/yubikey-removed-script
#!/usr/bin/env bash
# Locks the screen if a Yubikey is not plugged in

if ! env | grep DEVNAME; then
exit 0;
fi

getXuser() {
user=`finger | grep -m1 ":$displaynum " | awk '{print $1}'`
if [ x"$user" = x"" ]; then
user=`finger| grep -m1 ":$displaynum" | awk '{print $1}'`
fi
if [ x"$user" != x"" ]; then
userhome=`getent passwd $user | cut -d: -f6`
export XAUTHORITY=$userhome/.Xauthority
else
export XAUTHORITY=""
fi
}

if [ -z "$(lsusb | grep Yubico)" ] ; then
for x in /tmp/.X11-unix/*; do
displaynum=`echo $x | sed s#/tmp/.X11-unix/X## | sed s#/##`
getXuser
if [ x"$XAUTHORITY" != x"" ]; then
# extract current state
export DISPLAY=":$displaynum"
fi
done

enable_timer=true

if [ "${enable_timer}" == "true" ]; then
for i in {1..5}; do
sleep 1;
echo $(( $i*20 ));
done | zenity --title "Yubikey removed" --text "Locking the screen\n(Press Escape to cancel)" --width 400 --progress --no-cancel --auto-close
answer=$?
fi

LOCKER="light-locker"
LOCKER_COMMAND="${LOCKER}-command"
if [ -z "$(which ${LOCKER_COMMAND})" ]; then
LOCKER="gnome-screensaver"
LOCKER_COMMAND="${LOCKER}-command"
fi

if [[ "${enable_timer}" != "true" ]] || [[ ${answer} -eq 0 ]]; then
export grep -z DBUS_SESSION_BUS_ADDRESS /proc/$(pidof ${LOCKER})/environ
logger "YubiKey Removed - Locking Workstation"
su $user -c "/usr/bin/${LOCKER_COMMAND} -l"
fi

fi

EOF
```

Make it executable:
```
sudo chmod +x /usr/local/bin/yubikey-removed-script
```

Create a udev rule to trigger the `yubikey-removed-script`:
```
cat < | cut -c -12)
key2=$(echo | cut -c -12)
echo "vagrant:${key1}:${key2}" | sudo tee /etc/ssh/authorized_yubikeys
```
### Configure the SSH daemon
Note: get API keys from https://upgrade.yubico.com/getapikey/ (Needed for configuring the server side)
```
Yubikey 1
Client ID:
Secret key:

Yubikey 2
Client ID:
Secret key:
```
Using the API keys above, add an entry to the `key_map` for each Yubikey. If you want
1-factor authentication with only the Yubikey present instead of 2-factor authentication (SSH key + YubiKey present), set REQUIRED_OR_SUFFICIENT
to "sufficient" instead of "required".
```
declare -A key_map
key_map[""]="secret key 1>"
key_map[""]="secret key 2>"
REQUIRED_OR_SUFFICIENT="required"
FILE="/etc/pam.d/sshd"
for key in ${!key_map[@]}; do
secret=${key_map[${key}]}
LINE="auth $REQUIRED_OR_SUFFICIENT pam_yubico.so id=$key key=$secret authfile=/etc/ssh/authorized_yubikeys"
sudo sed -i "1s|^|$LINE \n|" $FILE
done
```

### Links:
https://support.yubico.com/support/solutions/articles/15000011355-ubuntu-linux-login-guide-challenge-response

https://dgunter.com/2018/09/30/securing-linux-full-disk-encryption-with-a-multi-factor-hardware-token/

https://blog.programster.org/yubikey-cheatsheet

https://www.linode.com/docs/security/authentication/how-to-use-yubikey-for-two-factor-ssh-authentication/

https://newbedev.com/yubikey-two-factor-authentication-full-disk-encryption-via-luks