nix-git/modules/nitrokey-gpg-smartcard.nix

191 lines
6.7 KiB
Nix
Raw Normal View History

2023-10-20 14:56:07 +02:00
{ config, pkgs, lib, ... }:
2023-08-31 14:07:09 +02:00
{
2023-09-06 14:00:57 +02:00
# Use NitroKey USB smartcard with SSH.
# https://nixos.wiki/wiki/Nitrokey
2023-09-11 13:23:55 +02:00
# Test suite. TODO: Check all of this after config changes!
2024-01-01 16:29:36 +01:00
# - pinentry should be in $PATH.
# Note: Since NixOS 23.11 (and maybe earlier) this is no longer the case.
# Yet, all other tests still work!
# echo GETPIN | pinentry
2023-09-11 13:23:55 +02:00
# - smartcard should be listed
2024-01-01 16:29:36 +01:00
# gpg --card-status
2024-01-01 16:22:15 +01:00
# - encryption should work (graphical pinentry should pop-up)
2024-01-01 16:29:36 +01:00
# gpg -d ./passphrase.txt.gpg
2024-01-01 16:22:15 +01:00
# - ssh should work (graphical pinentry should pop-up)
2024-01-01 16:29:36 +01:00
# ssh yodaNas
2023-09-11 13:23:55 +02:00
# - signed git commits should work in IntelliJ
2024-01-01 16:29:36 +01:00
# IntelliJ IDE -> Make a Git commit -> Graphical pinentry should pop-up
2023-09-11 13:23:55 +02:00
2023-09-06 14:00:57 +02:00
# Restart gpg-agent after config change.
# Otherwise there might be a gpg error about "no pinentry".
# https://discourse.nixos.org/t/cant-get-gnupg-to-work-no-pinentry/15373/19
2023-09-11 14:24:28 +02:00
#
# But how to restart it?
# https://superuser.com/a/1150399
# gpgconf --kill gpg-agent
2023-09-11 13:17:49 +02:00
# killall gpg-agent
2023-09-11 13:06:20 +02:00
# systemctl --user restart gpg-agent
2023-09-06 14:00:57 +02:00
# Not sure if this is needed: Reload udev rules.
# sudo -- udevadm control --reload-rules && udevadm trigger
2023-08-31 14:07:09 +02:00
2023-09-06 14:00:57 +02:00
# TODO: gpg-agent pinentry problem
# https://github.com/NixOS/nixpkgs/issues/97861
#
# gpgconf --check-programs
#=> gpgconf: error running '/nix/store/lvsbmqy4dmlri22145hbr6799hgbnpnf-gnupg-2.4.0/bin/pinentry': probably not installed
#
# ssh -v nas
#=> OpenSSH_9.3p2, OpenSSL 3.0.10 1 Aug 2023
#=> debug1: Reading configuration data /home/yoda/.ssh/config
#=> debug1: /home/yoda/.ssh/config line 67: Applying options for nas
#=> debug1: /home/yoda/.ssh/config line 180: Applying options for *
#=> debug1: Reading configuration data /etc/ssh/ssh_config
#=> debug1: Executing command: '/nix/store/8fv91097mbh5049i9rglc73dx6kjg3qk-bash-5.2-p15/bin/bash -c '/nix/store/lvsbmqy4dmlri22145hbr6799hgbnpnf-gnupg-2.4.0/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1''
#
#=> USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
#=> yoda 2752 0.0 0.0 444812 3040 ? SLsl 16:09 0:00 /nix/store/lvsbmqy4dmlri22145hbr6799hgbnpnf-gnupg-2.4.0/bin/gpg-agent --supervised --pinentry-program /nix/store/8cvidvpwnwyxixlhqfaa5jlfndh2vir5-pinentry-1.2.1-curses/bin/pinentry
# NITROKEY SSH WORKAROUND (I): Do all of this in one shell!
# CREDITS: https://unix.stackexchange.com/a/250045/315162
#
# BEFORE: SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
# AFTER: SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh
#
# systemctl --user stop gpg-agent
# systemctl --user stop gpg-agent.socket
# systemctl --user stop gpg-agent-ssh.socket
# ps -aux | grep -v grep | grep gpg-agent
# => NONE
2023-09-11 13:06:20 +02:00
# eval $(gpg-agent --daemon --pinentry-program /nix/store/5j87jnmfh19xlq9ij0v3rh7cwssr4586-pinentry-1.2.1-curses/bin/pinentry --enable-ssh-support --sh)
2023-09-06 14:00:57 +02:00
# echo $SSH_AUTH_SOCK
#=> /run/user/1000/gnupg/S.gpg-agent.ssh
# gpg -d ./passphrase.txt.gpg
#=> Works!
# ssh nas
#=> Works!
# NITROKEY SSH WORKAROUND (II)
#
# export SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh
# ssh nas
#=> Works!
2023-09-11 13:23:55 +02:00
# TODO:
# What is the difference between programs.gnupg.agent.enableSSHSupport and
# services.gpg-agent.enableSshSupport = true;
2023-09-06 14:57:11 +02:00
2023-09-06 14:00:57 +02:00
services.udev.packages = [ pkgs.nitrokey-udev-rules ];
programs = {
ssh.startAgent = false;
gnupg.agent = {
enable = true;
2023-10-19 15:10:05 +02:00
# Sets SSH_AUTH_SOCK environment variable.
2023-09-06 14:00:57 +02:00
enableSSHSupport = true;
2024-08-13 14:46:55 +02:00
#pinentryPackage = pkgs.pinentry-curses;
pinentryPackage = pkgs.pinentry-gnome3;
2023-09-06 14:00:57 +02:00
};
};
2023-10-19 15:10:05 +02:00
# GNOME Keyring: Disable SSH agent.
#
# Without this,
# export SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh
# is required before ssh can use the smartcard (through gpg-agent).
#
# GNOME Keyring will override the SSH_AUTH_SOCK variable
# if it starts its own SSH agent. The docs suggest to disable
# SSH agent support in GNOME Keyring if using another SSH agent:
# https://wiki.gnome.org/Projects/GnomeKeyring/Ssh
#
# Here are related issues:
# https://github.com/NixOS/nixpkgs/issues/8356
# https://github.com/NixOS/nixpkgs/issues/42291
# https://wiki.archlinux.org/title/GnuPG#GNOME_on_Wayland_overrides_SSH_agent_socket
#
# Solution 1: https://github.com/NixOS/nixpkgs/issues/42291#issuecomment-399630199
2023-10-20 14:56:07 +02:00
# Works for me.
2023-10-19 15:10:05 +02:00
# Solution 2: https://github.com/NixOS/nixpkgs/issues/42291#issuecomment-687979733
2023-10-20 14:56:07 +02:00
# Works for me, but on each login, nextcloud-desktop asks for credentials ...
2023-10-19 15:10:05 +02:00
2023-09-11 13:17:49 +02:00
# Adds the pinentry binary to the PATH so that e.g.
# echo GETPIN | pinentry
# works.
2023-09-11 14:13:13 +02:00
# This is not required for
# - gpg --card-status
# - ssh nas
# - signed git commits in IntelliJ
#environment.systemPackages = with pkgs; [
# #pinentry-curses
# pinentry-gnome
#];
2023-09-06 14:00:57 +02:00
2023-09-11 13:23:55 +02:00
#users.users.yoda = {
# packages = with pkgs; [
# #pinentry-curses
# pinentry-gnome
# ];
#};
2023-09-11 17:14:06 +02:00
# https://docs.nitrokey.com/nitrokey3/windows/troubleshooting.html#gnupg-openpgp-card-not-available
#
# There are two common smartcard services on Linux systems
# - scdaemon (gpg) with two drivers:
# - ccid: directly accesses smartcard
# - pcsc: uses the pcscd daemon to access smartcard
# - pcscd (generic smartcard daemon)
#
# `pcscd` might lock the card before `scdaemon` tries to access it
# using the internal `ccid` driver
#
# Either uninstall `pcscd` **or**
# use the `pcscd` driver for `scdaemon`
# by adding `disable-ccid` to `~/.gnupg/scdaemon.conf`
2023-09-06 14:00:57 +02:00
# Smartcard daemon.
services.pcscd.enable = true;
home-manager.users.yoda = { osConfig, config, pkgs, ... }: {
2023-09-06 14:57:11 +02:00
2023-10-20 14:56:07 +02:00
# Disable GNOME Keyring. See comment above.
#
# Prevent clobbering SSH_AUTH_SOCK
home.sessionVariables.GSM_SKIP_SSH_AGENT_WORKAROUND = "1";
# Disable gnome-keyring ssh-agent
xdg.configFile."autostart/gnome-keyring-ssh.desktop".text = ''
2024-12-03 22:16:26 +01:00
${lib.fileContents "${pkgs.gnome-keyring}/etc/xdg/autostart/gnome-keyring-ssh.desktop"}
2023-10-20 14:56:07 +02:00
Hidden=true
'';
2023-09-06 14:57:11 +02:00
# GnuPG configuration.
programs.gpg = {
enable = true;
2023-09-11 17:14:06 +02:00
scdaemonSettings = {
disable-ccid = true;
};
publicKeys = [{
source = "${../assets/gpg/pubkey_nitrokey.asc}";
# ultimate
trust = 5;
}];
# Examples:
# https://github.com/ioerror/duraconf
# https://gist.github.com/graffen/37eaa2332ee7e584bfda
2023-09-06 14:57:11 +02:00
settings = {
# Display long key IDs
keyid-format = "0xlong";
# List all keys (or the specified ones) along with their fingerprints
with-fingerprint = true;
# Display the calculated validity of user IDs during key listings.
list-options = "show-uid-validity";
verify-options = "show-uid-validity";
};
};
2023-09-11 14:05:02 +02:00
2023-08-31 14:07:09 +02:00
};
}