This commit is contained in:
2026-06-25 14:58:20 +09:00
parent 089e185bd8
commit 1ca5febd8e
4 changed files with 140 additions and 43 deletions
+1
View File
@@ -16,6 +16,7 @@ in
PermitRootLogin = "no";
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
AllowAgentForwarding = true;
PubkeyAuthentication = "yes";
};
};
+54 -15
View File
@@ -3,6 +3,7 @@
config,
...
}:
let
cfg = config.my.applications.ssh;
in
@@ -13,33 +14,71 @@ in
];
options.my.applications.ssh = {
enable = lib.mkEnableOption "OpenSSH client";
enable = lib.mkEnableOption "OpenSSH client and agent configuration";
defaultIdentityFile = lib.mkOption {
defaultIdentityFiles = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"~/.ssh/id_ed25519"
];
description = ''
Default local SSH identity files.
These are used as the normal fallback identities when no agent key
is accepted, or when no forwarded agent is available.
'';
};
fidoIdentityFile = lib.mkOption {
type = lib.types.str;
default = "~/.ssh/id_ed25519";
description = "Default SSH identity file";
default = "~/.ssh/id_ed25519_sk_rk";
description = ''
Local FIDO2 resident-key SSH identity handle.
This file is only added to SSH identity candidates when a FIDO2
device is actually visible. Do not use file existence to decide
whether this key is usable.
'';
};
githubIdentityFiles = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Extra GitHub-specific SSH identity files.
Leave this empty if GitHub should use the normal agent, FIDO key,
and default identity fallback order.
'';
};
addKeysToAgent = lib.mkOption {
type = lib.types.str;
default = "no";
description = "Add keys to SSH agent";
example = "1h";
description = ''
Value for OpenSSH AddKeysToAgent.
Recommended default is "no" for this setup, because FIDO resident-key
handle files should not be added to the agent accidentally.
'';
};
matchBlocks = lib.mkOption {
type = lib.types.attrs;
type = lib.types.attrsOf lib.types.anything;
default = { };
description = "SSH match blocks";
};
description = ''
Additional Home Manager OpenSSH settings blocks.
githubIdentityFiles = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [
"~/.ssh/id_ed25519_sk_rk"
"~/.ssh/id_ed25519"
];
description = "SSH identity files for GitHub (tried in order)";
Use this for host-specific options such as ForwardAgent = true.
'';
example = lib.literalExpression ''
{
"proxmox-* *.home.arpa *.internal" = {
ForwardAgent = true;
};
}
'';
};
};
+78 -26
View File
@@ -4,9 +4,40 @@
config,
...
}:
let
cfg = config.my.applications.ssh;
hmCfg = config.my.applications.ssh.homeManager;
hasFidoDevice = pkgs.writeShellScript "ssh-has-fido-device" ''
${pkgs.libfido2}/bin/fido2-token -L 2>/dev/null \
| ${pkgs.gnugrep}/bin/grep -q .
'';
userMatchBlockNames = lib.attrNames (cfg.matchBlocks or { });
userMatchBlocks = lib.mapAttrs (
_name: value: lib.hm.dag.entryBefore [ "my-github" "my-default" ] value
) (cfg.matchBlocks or { });
githubBlock = {
header = "Host github.com";
HostName = "github.com";
User = "git";
IdentityAgent = "SSH_AUTH_SOCK";
IdentitiesOnly = false;
ForwardAgent = false;
AddKeysToAgent = cfg.addKeysToAgent;
}
// lib.optionalAttrs (cfg.githubIdentityFiles != [ ]) {
IdentityFile = cfg.githubIdentityFiles;
};
in
{
options.my.applications.ssh.homeManager = {
@@ -14,40 +45,61 @@ in
};
config.home-manager.sharedModules = [
{
config = lib.mkIf hmCfg.enable {
home.packages = [
pkgs.openssh
];
(
{ lib, ... }:
{
config = lib.mkIf hmCfg.enable {
systemd.user.sockets.gcr-ssh-agent.Install.WantedBy = lib.mkForce [ ];
programs.ssh = {
enable = true;
enableDefaultConfig = false;
services.ssh-agent.enable = true;
settings = userMatchBlocks // {
"my-local-fido-sk-rk" =
lib.hm.dag.entryBefore
(
[
"my-github"
"my-default"
]
++ userMatchBlockNames
)
{
header = ''Match exec "${hasFidoDevice}"'';
IdentityFile = cfg.fidoIdentityFile;
};
home.sessionVariables = {
SSH_AUTH_SOCK = "\${XDG_RUNTIME_DIR}/ssh-agent";
};
"my-github" = lib.hm.dag.entryBefore [ "my-default" ] githubBlock;
programs.ssh = {
enable = true;
enableDefaultConfig = false;
"my-default" =
lib.hm.dag.entryAfter
(
[
"my-local-fido-sk-rk"
"my-github"
]
++ userMatchBlockNames
)
{
header = "Host *";
settings = cfg.matchBlocks // {
"github.com" = {
IdentityFile = cfg.githubIdentityFiles;
AddKeysToAgent = cfg.addKeysToAgent;
};
IdentityAgent = "SSH_AUTH_SOCK";
IdentitiesOnly = false;
"*" = {
IdentityFile = cfg.defaultIdentityFile;
AddKeysToAgent = cfg.addKeysToAgent;
SetEnv = {
TERM = "xterm";
};
ForwardAgent = false;
IdentityFile = cfg.defaultIdentityFiles;
AddKeysToAgent = cfg.addKeysToAgent;
SetEnv = {
TERM = "xterm";
};
};
};
};
};
};
}
}
)
];
}
+7 -2
View File
@@ -15,9 +15,14 @@ in
config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
openssh # OpenSSH client and server
libfido2 # FIDO2 support for SSH
];
programs.ssh.startAgent = false;
services.gnome.gcr-ssh-agent.enable = false;
programs.ssh = {
startAgent = true;
agentTimeout = "24h";
};
programs.gnupg.agent.enableSSHSupport = lib.mkForce false;
services.gnome.gcr-ssh-agent.enable = lib.mkForce false;
};
}