diff --git a/ansible/roles/sshd/files/keys/yubikey.pub b/ansible/roles/sshd/files/keys/yubikey.pub index 36b8f22..6970620 100644 --- a/ansible/roles/sshd/files/keys/yubikey.pub +++ b/ansible/roles/sshd/files/keys/yubikey.pub @@ -1 +1 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGu+k5lrirokdW5zVdRVBOqEOAvAPlIkG/MdJNc9g5ky cardno:000611194908 +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID0+4zi26M3eYWnIrciR54kOlGxzfgCXG+o4ea1zpzrk openpgp:0x7FF123C8 diff --git a/nix/configuration/configuration.nix b/nix/configuration/configuration.nix index 4b06ff2..63e5113 100644 --- a/nix/configuration/configuration.nix +++ b/nix/configuration/configuration.nix @@ -47,6 +47,7 @@ ./roles/nix_index ./roles/nix_worker ./roles/nvme + ./roles/openpgp_card_tools ./roles/optimized_build ./roles/pcsx2 ./roles/podman @@ -55,6 +56,7 @@ ./roles/reset ./roles/rpcs3 ./roles/rust + ./roles/sequoia ./roles/shadps4 ./roles/shikane ./roles/shipwright @@ -74,6 +76,7 @@ ./roles/wasm ./roles/waybar ./roles/wireguard + ./roles/yubikey ./roles/zfs ./roles/zrepl ./roles/zsh @@ -120,7 +123,7 @@ # Generate with `mkpasswd -m scrypt` hashedPassword = "$7$CU..../....VXvNQ8za3wSGpdzGXNT50/$HcFtn/yvwPMCw4888BelpiAPLAxe/zU87fD.d/N6U48"; openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGu+k5lrirokdW5zVdRVBOqEOAvAPlIkG/MdJNc9g5ky" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID0+4zi26M3eYWnIrciR54kOlGxzfgCXG+o4ea1zpzrk openpgp:0x7FF123C8" "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEI6mu6I5Jp+Ib0vJxapGHbEShZjyvzV8jz5DnzDrI39AAAABHNzaDo=" "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAFNcSXwvy+brYTOGo56G93Ptuq2MmZsjvRWAfMqbmMLAAAABHNzaDo=" ]; diff --git a/nix/configuration/hosts/odo/default.nix b/nix/configuration/hosts/odo/default.nix index f0800ba..fc347c4 100644 --- a/nix/configuration/hosts/odo/default.nix +++ b/nix/configuration/hosts/odo/default.nix @@ -86,12 +86,14 @@ me.lvfs.enable = true; me.media.enable = true; me.nix_index.enable = true; + me.openpgp_card_tools.enable = true; me.pcsx2.enable = true; me.podman.enable = true; me.python.enable = true; me.qemu.enable = true; me.rpcs3.enable = true; me.rust.enable = true; + me.sequoia.enable = true; me.shadps4.enable = true; me.shikane.enable = true; me.sops.enable = true; @@ -113,6 +115,7 @@ "colo" ]; me.wireguard.deactivated = [ "wgf" ]; + me.yubikey.enable = true; me.zrepl.enable = true; me.zsh.enable = true; diff --git a/nix/configuration/hosts/quark/default.nix b/nix/configuration/hosts/quark/default.nix index c1bf327..fb27f79 100644 --- a/nix/configuration/hosts/quark/default.nix +++ b/nix/configuration/hosts/quark/default.nix @@ -82,12 +82,14 @@ me.media.enable = true; me.nix_index.enable = true; me.nix_worker.enable = true; + me.openpgp_card_tools.enable = true; me.pcsx2.enable = true; me.podman.enable = true; me.python.enable = true; me.qemu.enable = true; me.rpcs3.enable = true; me.rust.enable = true; + me.sequoia.enable = true; me.shadps4.enable = true; me.shikane.enable = true; me.sops.enable = true; @@ -109,6 +111,7 @@ "colo" ]; me.wireguard.deactivated = [ "wgf" ]; + me.yubikey.enable = true; me.zrepl.enable = true; me.zsh.enable = true; diff --git a/nix/configuration/roles/git/files/gitconfig_home b/nix/configuration/roles/git/files/gitconfig_home index de30c30..4045fc3 100644 --- a/nix/configuration/roles/git/files/gitconfig_home +++ b/nix/configuration/roles/git/files/gitconfig_home @@ -1,7 +1,7 @@ [user] email = tom@fizz.buzz name = Tom Alexander - signingkey = D3A179C9A53C0EDE + signingkey = 36C99E8B3C39D85F [push] default = simple # (default since 2.0) [alias] @@ -53,3 +53,6 @@ autoStash = true # updateRefs was annoying when you want to split a branch in two by rebasing away from commits from one branch and rebasing away some commits from another branch. updateRefs = false +# Disabled because ephemeral pin storage is not yet ready in openpgp-card-state +# [gpg] +# program = oct-git diff --git a/nix/configuration/roles/gpg/default.nix b/nix/configuration/roles/gpg/default.nix index eeab4d3..b59ea11 100644 --- a/nix/configuration/roles/gpg/default.nix +++ b/nix/configuration/roles/gpg/default.nix @@ -29,9 +29,7 @@ in lib.mkMerge [ { # Fetch public keys: - # gpg --locate-keys tom@fizz.buzz - # - # gpg -vvv --auto-key-locate local,wkd --locate-keys tom@fizz.buzz + # gpg --locate-external-keys tom@fizz.buzz hardware.gpgSmartcards.enable = true; services.udev.packages = [ @@ -47,15 +45,6 @@ in }) ]; services.pcscd.enable = true; - # services.gnome.gnome-keyring.enable = true; - - # services.dbus.packages = [ pkgs.gcr ]; - - # services.pcscd.plugins = lib.mkForce [ ]; - - # programs.gpg.scdaemonSettings = { - # disable-ccid = true; - # }; me.install.user.talexander.file = { ".gnupg/scdaemon.conf" = { @@ -63,16 +52,57 @@ in }; }; - # programs.gnupg.dirmngr.enable = true; programs.gnupg.agent = { enable = true; enableSSHSupport = true; pinentryPackage = pkgs.pinentry-qt; + # Settings block populates /etc/gnupg/gpg-agent.conf # settings = { - # disable-ccid = true; # }; }; + # Disabled because it breaks signing git commits because gpg wants to copy pubring.kbx. Unfortunately, this makes the install of scdaemon.conf do nothing since this mount of the full .gnupg directory goes over it. + # + # environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) { + # hideMounts = true; + # users.talexander = { + # files = [ + # { + # file = ".gnupg/trustdb.gpg"; + # parentDirectory = { + # mode = "u=rwx,g=,o="; + # }; + # } + # { + # file = ".gnupg/pubring.kbx"; + # parentDirectory = { + # mode = "u=rwx,g=,o="; + # }; + # } + # { + # file = ".gnupg/tofu.db"; + # parentDirectory = { + # mode = "u=rwx,g=,o="; + # }; + # } + # ]; + # directories = [ + # { + # directory = ".gnupg/crls.d"; + # user = "talexander"; + # group = "talexander"; + # mode = "0700"; + # } + # { + # directory = ".gnupg/private-keys-v1.d"; + # user = "talexander"; + # group = "talexander"; + # mode = "0700"; + # } + # ]; + # }; + # }; + environment.persistence."/persist" = lib.mkIf (!config.me.buildingIso) { hideMounts = true; users.talexander = { @@ -82,7 +112,7 @@ in user = "talexander"; group = "talexander"; mode = "0700"; - } # Local keyring + } ]; }; }; @@ -90,8 +120,6 @@ in environment.systemPackages = with pkgs; [ pcsclite pcsctools - yubikey-personalization - yubikey-manager glibcLocales ccid libusb-compat-0_1 diff --git a/nix/configuration/roles/gpg/files/gpg_test_wkd.bash b/nix/configuration/roles/gpg/files/gpg_test_wkd.bash index 6b79a8b..1a1fef5 100644 --- a/nix/configuration/roles/gpg/files/gpg_test_wkd.bash +++ b/nix/configuration/roles/gpg/files/gpg_test_wkd.bash @@ -6,3 +6,6 @@ IFS=$'\n\t' DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" gpg --no-default-keyring --keyring /tmp/gpg-$$ --auto-key-locate clear,wkd --locate-keys "${@}" + +# To generate files for the WKD: +# gpg-wks-client --directory ./pgp/.well-known/openpgpkey --install-key diff --git a/nix/configuration/roles/gpg/files/scdaemon.conf b/nix/configuration/roles/gpg/files/scdaemon.conf index bcc356d..e0bfda2 100644 --- a/nix/configuration/roles/gpg/files/scdaemon.conf +++ b/nix/configuration/roles/gpg/files/scdaemon.conf @@ -1,5 +1,6 @@ #reader-port Yubico Yubi disable-ccid +pcsc-shared #log-file /home/talexander/scd.log #verbose diff --git a/nix/configuration/roles/kodi/default.nix b/nix/configuration/roles/kodi/default.nix index d67e3fd..93380e4 100644 --- a/nix/configuration/roles/kodi/default.nix +++ b/nix/configuration/roles/kodi/default.nix @@ -51,7 +51,7 @@ # Generate with `mkpasswd -m scrypt` hashedPassword = "$7$CU..../....VXvNQ8za3wSGpdzGXNT50/$HcFtn/yvwPMCw4888BelpiAPLAxe/zU87fD.d/N6U48"; openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGu+k5lrirokdW5zVdRVBOqEOAvAPlIkG/MdJNc9g5ky" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID0+4zi26M3eYWnIrciR54kOlGxzfgCXG+o4ea1zpzrk openpgp:0x7FF123C8" "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEI6mu6I5Jp+Ib0vJxapGHbEShZjyvzV8jz5DnzDrI39AAAABHNzaDo=" "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAFNcSXwvy+brYTOGo56G93Ptuq2MmZsjvRWAfMqbmMLAAAABHNzaDo=" ]; diff --git a/nix/configuration/roles/nix_worker/default.nix b/nix/configuration/roles/nix_worker/default.nix index 9cc73c7..97164b3 100644 --- a/nix/configuration/roles/nix_worker/default.nix +++ b/nix/configuration/roles/nix_worker/default.nix @@ -43,7 +43,7 @@ hashedPassword = "$7$CU..../....VXvNQ8za3wSGpdzGXNT50/$HcFtn/yvwPMCw4888BelpiAPLAxe/zU87fD.d/N6U48"; openssh.authorizedKeys.keys = [ # Normal keys: - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGu+k5lrirokdW5zVdRVBOqEOAvAPlIkG/MdJNc9g5ky" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID0+4zi26M3eYWnIrciR54kOlGxzfgCXG+o4ea1zpzrk openpgp:0x7FF123C8" "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEI6mu6I5Jp+Ib0vJxapGHbEShZjyvzV8jz5DnzDrI39AAAABHNzaDo=" "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAFNcSXwvy+brYTOGo56G93Ptuq2MmZsjvRWAfMqbmMLAAAABHNzaDo=" # Key for nix to connect: diff --git a/nix/configuration/roles/openpgp_card_tools/default.nix b/nix/configuration/roles/openpgp_card_tools/default.nix new file mode 100644 index 0000000..262cc12 --- /dev/null +++ b/nix/configuration/roles/openpgp_card_tools/default.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + imports = [ + ./openpgp-card-ssh-agent.nix + ]; + + options.me = { + openpgp_card_tools.enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Whether we want to install openpgp-card-tools."; + }; + }; + + config = lib.mkIf config.me.openpgp_card_tools.enable ( + lib.mkMerge [ + { + environment.systemPackages = with pkgs; [ + openpgp-card-tools + openpgp-card-tool-git + openpgp-card-ssh-agent + ]; + + nixpkgs.overlays = [ + (final: prev: { + openpgp-card-tool-git = (final.callPackage ./package/openpgp-card-tool-git/package.nix { }); + openpgp-card-ssh-agent = (final.callPackage ./package/openpgp-card-ssh-agent/package.nix { }); + }) + ]; + + me.install.user.talexander.file = { + ".config/openpgp-card-state/config.toml" = { + source = ./files/openpgp-card-state.toml; + }; + }; + + # The current openpgp-card-ssh-agent has an outdated dependency on openpgp-card-state which makes it not handle my current openpgp-card-state.toml + # services.openpgp-card-ssh-agent.enable = true; + } + ] + ); +} diff --git a/nix/configuration/roles/openpgp_card_tools/files/openpgp-card-state.toml b/nix/configuration/roles/openpgp_card_tools/files/openpgp-card-state.toml new file mode 100644 index 0000000..13ce937 --- /dev/null +++ b/nix/configuration/roles/openpgp_card_tools/files/openpgp-card-state.toml @@ -0,0 +1 @@ +default_pin_storage = "Pinentry" diff --git a/nix/configuration/roles/openpgp_card_tools/openpgp-card-ssh-agent.nix b/nix/configuration/roles/openpgp_card_tools/openpgp-card-ssh-agent.nix new file mode 100644 index 0000000..c620b6b --- /dev/null +++ b/nix/configuration/roles/openpgp_card_tools/openpgp-card-ssh-agent.nix @@ -0,0 +1,94 @@ +# Upstream to nixpkgs/nixos/modules/services/networking/ssh/openpgp-card-ssh-agent.nix +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + mkIf + mkOption + mkEnableOption + mkPackageOption + mkDefault + types + concatMapStringsSep + generators + ; + cfg = config.services.openpgp-card-ssh-agent; +in +{ + options.services.openpgp-card-ssh-agent = { + + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Whether to start openpgp-card-ssh-agent when you log in. + Also sets SSH_AUTH_SOCK to point at openpgp-card-ssh-agent. + ''; + }; + + package = mkPackageOption pkgs "openpgp-card-ssh-agent" { }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + + systemd.user.sockets.openpgp-card-ssh-agent = { + wantedBy = [ "sockets.target" ]; + description = "A simple ssh-agent backed by OpenPGP card authentication keys"; + documentation = [ + "https://codeberg.org/openpgp-card/ssh-agent" + "man:ssh-add(1)" + "man:ssh-agent(1)" + "man:ssh(1)" + ]; + socketConfig = { + ListenStream = "%t/openpgp-card/ssh-agent.sock"; + SocketMode = "0600"; + DirectoryMode = "0700"; + }; + }; + + systemd.user.services.openpgp-card-ssh-agent = { + description = "A simple ssh-agent backed by OpenPGP card authentication keys"; + documentation = [ + "https://codeberg.org/openpgp-card/ssh-agent" + "man:ssh-add(1)" + "man:ssh-agent(1)" + "man:ssh(1)" + ]; + after = [ "local-fs.target" ]; + requires = [ + "openpgp-card-ssh-agent.socket" + # "gnome-keyring-daemon.service" + ]; + + serviceConfig = { + ExecStart = '' + ${cfg.package}/bin/openpgp-card-ssh-agent -H fd:// + ''; + }; + }; + + environment.extraInit = '' + if [ -z "$SSH_AUTH_SOCK" ] && [ -n "$XDG_RUNTIME_DIR" ]; then + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/openpgp-card/ssh-agent.sock" + fi + ''; + + assertions = [ + { + assertion = cfg.enable -> !config.programs.ssh.startAgent; + message = "You can't use ssh-agent and GnuPG agent with SSH support enabled at the same time!"; + } + { + assertion = cfg.enable -> !config.programs.gnupg.agent.enableSSHSupport; + message = "You can't use GnuPG agent with SSH support enabled and openpgp-card-ssh-agent at the same time!"; + } + ]; + }; +} diff --git a/nix/configuration/roles/openpgp_card_tools/package/openpgp-card-ssh-agent/package.nix b/nix/configuration/roles/openpgp_card_tools/package/openpgp-card-ssh-agent/package.nix new file mode 100644 index 0000000..d76e14a --- /dev/null +++ b/nix/configuration/roles/openpgp_card_tools/package/openpgp-card-ssh-agent/package.nix @@ -0,0 +1,52 @@ +{ + lib, + rustPlatform, + fetchFromGitea, + pkg-config, + pcsclite, + dbus, + openssl, + testers, + openpgp-card-ssh-agent, +}: + +rustPlatform.buildRustPackage rec { + pname = "openpgp-card-ssh-agent"; + version = "0.3.4"; + + src = fetchFromGitea { + domain = "codeberg.org"; + owner = "openpgp-card"; + repo = "ssh-agent"; + rev = "v${version}"; + hash = "sha256-nWbvEsVa7YJsBtVZfLQDB4CiaHP3GEYeYS32+WZv8PE="; + }; + + cargoHash = "sha256-nG7xebypXv7UAfu7sWbcp4DIhLv4lfzMrQUY6m2iDmw="; + + nativeBuildInputs = [ + pkg-config + ]; + + buildInputs = [ + openssl + pcsclite + dbus + ]; + + passthru = { + tests.version = testers.testVersion { + package = openpgp-card-ssh-agent; + }; + }; + + meta = with lib; { + description = "An ssh agent that uses OpenPGP cards for your key"; + homepage = "https://codeberg.org/openpgp-card/ssh-agent"; + license = with licenses; [ + asl20 # OR + mit + ]; + mainProgram = "openpgp-card-ssh-agent"; + }; +} diff --git a/nix/configuration/roles/openpgp_card_tools/package/openpgp-card-tool-git/package.nix b/nix/configuration/roles/openpgp_card_tools/package/openpgp-card-tool-git/package.nix new file mode 100644 index 0000000..c366a73 --- /dev/null +++ b/nix/configuration/roles/openpgp_card_tools/package/openpgp-card-tool-git/package.nix @@ -0,0 +1,54 @@ +{ + lib, + rustPlatform, + fetchFromGitea, + pkg-config, + pcsclite, + dbus, + openssl, + sqlite, + testers, + openpgp-card-tool-git, +}: + +rustPlatform.buildRustPackage rec { + pname = "openpgp-card-tool-git"; + version = "0.1.6"; + + src = fetchFromGitea { + domain = "codeberg.org"; + owner = "openpgp-card"; + repo = "oct-git"; + rev = "v${version}"; + hash = "sha256-38/JHzCkL3+0IbOacH54A5Hj03oDe9jDzcwp672a8LE="; + }; + + cargoHash = "sha256-j1Osj2rjLxrSKh82ym6PiIHVO1wLE7Ax2/5+pdRcv+E="; + + nativeBuildInputs = [ + pkg-config + ]; + + buildInputs = [ + openssl + pcsclite + dbus + sqlite + ]; + + passthru = { + tests.version = testers.testVersion { + package = openpgp-card-tool-git; + }; + }; + + meta = with lib; { + description = "Tool for using OpenPGP cards with git"; + homepage = "https://codeberg.org/openpgp-card/oct-git"; + license = with licenses; [ + asl20 # OR + mit + ]; + mainProgram = "oct-git"; + }; +} diff --git a/nix/configuration/roles/sequoia/default.nix b/nix/configuration/roles/sequoia/default.nix new file mode 100644 index 0000000..a69e0f8 --- /dev/null +++ b/nix/configuration/roles/sequoia/default.nix @@ -0,0 +1,29 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + imports = [ ]; + + options.me = { + sequoia.enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Whether we want to install sequoia."; + }; + }; + + config = lib.mkIf config.me.sequoia.enable ( + lib.mkMerge [ + { + environment.systemPackages = with pkgs; [ + sequoia-sq + ]; + } + ] + ); +} diff --git a/nix/configuration/roles/yubikey/default.nix b/nix/configuration/roles/yubikey/default.nix new file mode 100644 index 0000000..257388a --- /dev/null +++ b/nix/configuration/roles/yubikey/default.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + imports = [ ]; + + options.me = { + yubikey.enable = lib.mkOption { + type = lib.types.bool; + default = false; + example = true; + description = "Whether we want to install yubikey."; + }; + }; + + config = lib.mkIf config.me.yubikey.enable ( + lib.mkMerge [ + { + environment.systemPackages = with pkgs; [ + yubikey-personalization + yubikey-manager + ]; + } + ] + ); +}