The following is the GNU All-permissive License as recommended in https://www.gnu.org/licenses/license-recommendations.en.html
Copyright (C) 2024 Free Software Foundation sysadmin@fsf.org
Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.
Contributions are welcome. See https://savannah.gnu.org/maintenance/fsf/.
[[!toc levels=2]]
The following instructions should work for devices like Yubikey or Nitrokey. Note that some packages or settings use the name yubikey but should be vendor-neutral for U2F devices.
Yubikey specific settings
First, configure the key as a OTP/U2F/CCID composite device (mode 6)
ykpersonalize -m6 -y
The integration with LUKS, PAM, and Abrowser requires the device to be set in Challenge/response mode. To set up the yubikey configuration slot 2 for that use, run:
$ ykpersonalize -v -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible -ochal-btn-trig
This setting makes the key wait for you to touch it before replying to the challenge. Save the output of the command, as the secret can be used to recreate the key if you lose it. Slot 1 is still available to be configured in any other setting you may need (by default, OTP).
You should set the access code to the key, you can do it with these commands:
$ CODE=$(openssl rand -hex 6)
$ echo $CODE
$ ykpersonalize -2 -oaccess=$CODE
Note, save $CODE somewhere safe. If you do this step, you then should add -c $CODE to any future ykpersonalize commands, or you will get a write error.
Integration with LUKS
Mostly taken from https://web.archive.org/web/*/https://www.howtoforge.com/ubuntu-two-factor-authentication-with-yubikey-for-harddisk-encryption-with-luks
This will add a key in slot 7 that requires using a password in combination with the key. You can have other passwords in the other slots that don't require a key, but they should be very strong.
# apt-get install yubikey-luks
# # Edit /usr/bin/yubikey-luks-enroll and set $DISK to the appropriate path
# yubikey-luks-enroll
# update-initramfs -u
If you need to wipe the key in slot 7, you can run cryptsetup luksKillSlot /dev/sdXX 7
You should replace your original slot 1 with a very strong password, write that down and keep it in a safe place, for recovery in case of losing the key. This is the command to change the password:
# cryptsetup luksChangeKey /dev/XXXX
Integration with login (PAM / lightdm / gdm)
Mostly taken from:
- https://web.archive.org/web/*/https://support.yubico.com/support/solutions/articles/15000011356-ubuntu-linux-login-guide-u2f
https://metebalci.com/blog/using-u2f-at-linux-login/
# apt-get install libpam-u2f pamu2fcfg $ mkdir ~/.config/Yubico -p $ pamu2fcfg -opam://myhostname -ipam://myhostname > .config/Yubico/u2f_keys
When the key begins blinking, touch to confirm.
If you have a backup key, also run this with each key inserted:
pamu2fcfg -opam://myhostname -ipam://mydhostname -n >> .config/Yubico/u2f_keys
Add the following line:
auth required pam_u2f.so cue nouserok origin=pam://myhostname appid=pam://myhostname
To these files, after “@include common-auth”
- /etc/pam.d/lightdm
- /etc/pam.d/sudo
- /etc/pam.d/login
- /etc/pam.d/mate-screensaver
Note that it is possible to just add that to /etc/pam.d/common-auth to affect all services, but doing so would prevent remote access to the machine (ssh, cups, samba, etc). This is good practice in a laptop that is intended to never be remotely accessed, but would break things on servers.
To be able to log in if you lose the key, you can either create a user with a very strong password and add it to the sudo group, or set a very strong password for root. Keep the password safe! If the disk is also LUKS encrypted, refer to that section.
Passwordless sudo
If you want to replace your sudo password with touching the key, you can use this line in /etc/pam.d/sudo before "@include common-auth"
auth [success=done new_authtok_reqd=done default=die] pam_u2f.so cue origin=pam://myhostname appid=pam://myhostname
Integration with Abrowser
Go to about:config and make sure that security.webauth.u2f is set to true. This allows for the key to be used for two-factor on sites like Gitlab, nextcloud and many others.
You can now go to https://www.yubico.com/genuine/ to verify the key.
Integration with GPG
https://github.com/drduh/YubiKey-Guide https://www.esev.com/blog/post/2015-01-pgp-ssh-key-on-yubikey-neo/
(Ideally you want to do this in a live Trisquel session.)
# apt-get update
# apt-get install -y \
curl gnupg2 gnupg-agent \
cryptsetup scdaemon pcscd \
yubikey-personalization \
dirmngr \
secure-delete \
hopenpgp-tools \
pwgen \
rng-tools
Harden gpg config
$ mkdir .gnupg cat << EOF >> ~/.gnupg/gpg.conf # https://github.com/drduh/config/blob/master/gpg.conf # https://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html # https://www.gnupg.org/documentation/manuals/gnupg/GPG-Esoteric-Options.html # Use AES256, 192, or 128 as cipher personal-cipher-preferences AES256 AES192 AES # Use SHA512, 384, or 256 as digest personal-digest-preferences SHA512 SHA384 SHA256 # Use ZLIB, BZIP2, ZIP, or no compression personal-compress-preferences ZLIB BZIP2 ZIP Uncompressed # Default preferences for new keys default-preference-list SHA512 SHA384 SHA256 AES256 AES192 AES ZLIB BZIP2 ZIP Uncompressed # SHA512 as digest to sign keys cert-digest-algo SHA512 # SHA512 as digest for symmetric ops s2k-digest-algo SHA512 # AES256 as cipher for symmetric ops s2k-cipher-algo AES256 # UTF-8 support for compatibility charset utf-8 # Show Unix timestamps fixed-list-mode # No comments in signature no-comments # No version in signature no-emit-version # Long hexidecimal key format keyid-format 0xlong # Display UID validity list-options show-uid-validity verify-options show-uid-validity # Display all keys and their fingerprints with-fingerprint # Display key origins and updates #with-key-origin # Cross-certify subkeys are present and valid require-cross-certification # Disable putting recipient key IDs into messages throw-keyids # Enable smartcard use-agent EOF
Preload entropy
sudo rngd -r /dev/urandom
Create a private key, only for certifying subkeys, no expiration. Use a very strong password
gpg2 --expert --full-gen-key Select (8) RSA (set your own capabilities) Toggle sign and encryption capabilities off, leave certify only Set lenght to 4096 Set the key to not expire Use your full real name and last name For your main identity, it may be better to use @gnu.org instead of @fsf.org as that email would be kept forever.
Create one key each for signing, encrypting and authenticating (ssh). Set them to expire in a year. 2048 is a good enough size for this and it would have better performance on the yubikey. Use a password you can remember, it will be used in combination with the yubikey
gpg2 --expert --edit-key $KEYID
Select 4 for the signing key, 6 for encryption, and 8 for auth (for this one, toggle capabilities until it only lists authentication)
Verify keys:
gpg2 --list-secret-keys
Add more identities
gpg2 --expert --edit-key $KEYID
> adduid
Export/backup your keys
gpg2 --armor --export-secret-keys $KEYID > ~/.gnupg/mastersub.key
gpg2 --armor --export-secret-subkeys $KEYID > ~/.gnupg/sub.key
Save .gnupg to encrypted storage (LUKS)
dd if=/dev/zero of=encrypted.img bs=1M count=100 cryptsetup luksFormat encrypted.img cryptsetup luksOpen encrypted.img crypt0 mkfs.xfs /dev/mapper/crypt0 mount /dev/mapper/crypt0 /media cp .gnupg /media umount /media cryptsetup luksClose /dev/mapper/crypt0
Transfer the keys into the yubikey. This may ask for your subkey passphrase. Repeat this for keys 1 to 3
gpg --edit-key $KEYID key 1 keytocard 1 save quit
Updating subkeys
Import your secret keys from saved mastersub.key, then change expirations or do any other operations
gpg --import mastersub.key gpg --edit-key $KEYID key x expire keytocard save
Integration with SSH
This requires having set the integration with GPG
Add this to your .gnupg/gpg-agent.conf
enable-ssh-support
pinentry-program /usr/bin/pinentry
default-cache-ttl 60
max-cache-ttl 120
Launch agent with
gpgconf --launch gpg-agent
Add this to your .bashrc
export SSH_AUTH_SOCK=$HOME/.gnupg/S.gpg-agent.ssh
After running that command, you can print your public key with command
ssh-add -L
You can now use that public key the usual way with ssh/scp/etc
Integration with OpenVPN
TODO
openssl pkcs12 -export -out cert_key.p12 -inkey ruben3.key -in ruben3.crt -certfile ca.crt -nodes
yubico-piv-tool -s 9c -i cert_key.p12 -K PKCS12 -a import-key -a import-cert