{ config, pkgs, ... }: { # Enable SSH server. services.openssh = { enable = true; # Forbid root login through SSH. settings.PermitRootLogin = "no"; # Use authorized keys only. settings.PasswordAuthentication = false; }; # Use NitroKey USB smartcard with SSH. # https://nixos.wiki/wiki/Nitrokey # # 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 # Not sure if this is needed: Reload udev rules. # sudo -- udevadm control --reload-rules && udevadm trigger # # Not sure if this is needed: # killall gpg-agent # 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 # eval $(gpg-agent --daemon --pinentry-program /nix/store/8cvidvpwnwyxixlhqfaa5jlfndh2vir5-pinentry-1.2.1-curses/bin/pinentry --enable-ssh-support --sh) # 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! services.udev.packages = [ pkgs.nitrokey-udev-rules ]; programs = { ssh.startAgent = false; gnupg.agent = { enable = true; # ... Also sets SSH_AUTH_SOCK environment variable correctly. enableSSHSupport = true; pinentryFlavor = "curses"; }; }; # users.users.yoda = { # packages = with pkgs; [ # pinentry-curses # ]; # }; # environment.systemPackages = with pkgs; [ # pinentry-curses # ]; # Smartcard daemon. services.pcscd.enable = true; home-manager.users.yoda = { osConfig, config, pkgs, ... }: { programs.ssh = { enable = true; userKnownHostsFile = "~/.ssh/known_hosts ${../assets/ssh/known_hosts}"; matchBlocks = { "nas" = { hostname = "p1st.de"; user = "yoda"; port = 2222; compression = true; #identityFile = "pubkey_nitrokey_ssh.pub"; #identitiesOnly = true; }; }; }; }; }