Hi all. I’ve spent quite some time setting up GPG with Nitrokey Pro under CentOS 6. I have it working for the application that I need, which is SSH authentication using public keys. Since I have encountered a few issues on the way, I thought I’d share my experience.
This procedure was tested on a clean VirtualBox install of latest 64-bit CentOS 6 (6.9). The system was installed from a live DVD ISO.
- Update the system
yum clean all
yum update
2) We need to add some extra packages, and remove some that would cause conflicts (OpenCT)
yum install gnupg2-smime ccid
yum remove pcsc-lite-openct openct
3) Add IDs for Nitrokey products, as described in Nitrokey docs (Installation/Nitrokey Pro/GNU Linux and then second point; I’d put in a direct link, but being a newbie on the board, it won’t let me). The file to edit is /usr/lib64/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist
- GNOME keyring daemon takes over ssh/gpg-agent functions, but it doesn’t implement smartcard functionality, so we have to disable it. There are many explanations on how to do it nicely (through a GUI) or less nice (by editing /etc/xdg/autostart scripts), but the only thing that actually worked for me is a rather blunt
chmod -x /usr/bin/gnome-keyring-daemon
If anyone knows of a better way to disable the GNOME keyring daemon, that actually works on CentOS 6, I’d love to hear it.
- Add udev rules for Nitrokey products. We need to create the file /etc/udev/rules.d/41-nitrokey.rules and in it we will place what is basically this file but with one addition at the end:
[code]# Nitrokey U2F
KERNEL==“hidraw*”, SUBSYSTEM==“hidraw”, MODE=“0664”, GROUP=“plugdev”, ATTRS{idVendor}==“2581”, ATTRS{idProduct}==“f1d0”
Nitrokey FIDO U2F
KERNEL==“hidraw*”, SUBSYSTEM==“hidraw”, MODE=“0664”, GROUP=“plugdev”, ATTRS{idVendor}==“20a0”, ATTRS{idProduct}==“4287”
SUBSYSTEM!=“usb”, GOTO=“gnupg_rules_end”
ACTION!=“add”, GOTO=“gnupg_rules_end”
USB SmartCard Readers
Crypto Stick 1.2
ATTR{idVendor}==“20a0”, ATTR{idProduct}==“4107”, ENV{ID_SMARTCARD_READER}=“1”, ENV{ID_SMARTCARD_READER_DRIVER}=“gnupg”, GROUP+=“plugdev”, TAG+=“uaccess”
Nitrokey Pro
ATTR{idVendor}==“20a0”, ATTR{idProduct}==“4108”, ENV{ID_SMARTCARD_READER}=“1”, ENV{ID_SMARTCARD_READER_DRIVER}=“gnupg”, GROUP+=“plugdev”, TAG+=“uaccess”
Nitrokey Storage
ATTR{idVendor}==“20a0”, ATTR{idProduct}==“4109”, ENV{ID_SMARTCARD_READER}=“1”, ENV{ID_SMARTCARD_READER_DRIVER}=“gnupg”, GROUP+=“plugdev”, TAG+=“uaccess”
Nitrokey Start
ATTR{idVendor}==“20a0”, ATTR{idProduct}==“4211”, ENV{ID_SMARTCARD_READER}=“1”, ENV{ID_SMARTCARD_READER_DRIVER}=“gnupg”, GROUP+=“plugdev”, TAG+=“uaccess”
Nitrokey HSM
ATTR{idVendor}==“20a0”, ATTR{idProduct}==“4230”, ENV{ID_SMARTCARD_READER}=“1”, ENV{ID_SMARTCARD_READER_DRIVER}=“gnupg”, GROUP+=“plugdev”, TAG+=“uaccess”
RUN+="/bin/bash -c ‘/usr/bin/killall -9 scdaemon’"
LABEL=“gnupg_rules_end”[/code]
I’ve added the RUN line to ensure that the scdaemon will be restarted when the Nitrokey is removed and then reinserted. This is another heavy-handed approach, but without it the key would not work properly (actually, at all) after it is removed and then inserted again. People have also reported that a similar solution is needed when a laptop with the key inserted goes to sleep and then wakes up, but I haven’t tested it.
-
Reboot the system
-
Edit the ~/.bashrc file to add gpg-agent support by appending the following lines:
#GPG Nitrokey
envfile="$HOME/.gnupg/gpg-agent.env"
if [[ -e "$envfile" ]] && kill -0 $(grep SSH_AGENT_PID "$envfile" | cut -d= -f 2) 2>/dev/null; then
eval "$(cat "$envfile")"
else
eval "$(gpg-agent --use-standard-socket --daemon --write-env-file "$envfile")"
fi
export SSH_AUTH_SOCK
GPG_TTY=$(tty)
export GPG_TTY
gpg-connect-agent updatestartuptty /bye >& /dev/null
A few things to note. I’ve had to use the ‘–use-standard-socket’ option with gpg-agent. Without it, it creates temporary sockets in /tmp, but apparently some of the other utilities in CentOS 6 expect the standard one (~/.gnupg/S.gpg-agent). Additionally, if we want to use gpg-agent for SSH, there is an issue of communicating which tty is to be used for displaying PIN queries if a text/curses prompt is needed. The last line lets the agent know which tty to use. Without out, the agent might be unable to display a PIN prompt and respond with somewhat cryptic “Agent admitted failure to sign using the key.”
- Create gpg-agent configuration file ~/.gnupg/gpg-agent.conf and add this to it:
pinentry-program /usr/bin/pinentry
enable-ssh-support
There are various versions of pinentry program, which can be listed with
yum whatprovides /usr/bin/pinentry*
and used as needed.
- Open a new terminal. If the gpg-agent was never configured before, the .bashrc code should output something like:
gpg-agent[2725]: directory `/home/miroslav/.gnupg/private-keys-v1.d' created
gpg-agent[2726]: gpg-agent (GnuPG) 2.0.14 started
You could test it with command gpg-agent, and it should output:
gpg-agent: gpg-agent running and available
- Insert the Nitrokey. If you are using a VM, make sure that the USB device is redirected to the virtual machine (Devices/USB menu in VirtualBox). The lsusb command output should include a line like:
Bus 002 Device 002: ID 20a0:4108 Clay Logic
Bus and Device numbers can be different, but for the ID should be as shown for a Nitrokey Pro device.
Try the gpg command
gpg --card-status
and it should show information about the Nitrokey Pro.
I’ve used a guide from http://xmodulo.com/linux-security-with-nitrokey-usb-smart-card.html to set up the SSH authentication. The guide recommends the use of official Nitrokey application to configure access PINs, but you can do it using gpg commands like so:
[code]gpg --card-edit
(…info about the card…)
Command> admin
Admin commands are allowed
Command> passwd
gpg: OpenPGP card no. … detected
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection?[/code]
Btw, is there a plan to make the official application usable on older distros? CentOS/RHEL 6 are not new by any measure, but will be supported till (I think) 2020 and are in rather broad use.
Anyhow, I hope this might help someone. Any comments on workarounds, ideas on how to do things better with Nitrokey on CentOS 6, etc are welcome!