Add keep-alive to ssh connections.

This commit is contained in:
Tom Alexander 2026-01-26 19:13:20 -05:00 committed by Tom Alexander
parent 43f3c1f955
commit e75c4087c3
Signed by: talexander
GPG Key ID: 36C99E8B3C39D85F
6 changed files with 277 additions and 99 deletions

View File

@ -47,5 +47,9 @@
source = ./files/ssh_config;
};
};
programs.ssh.extraConfig = ''
Include ${./files/ssh_config_global}
'';
};
}

View File

@ -37,6 +37,3 @@ Host hydra
Host i_only_boot_zfs
HostName 127.0.0.1
Port 60022
Host *
Compression yes

View File

@ -0,0 +1,4 @@
Host *
Compression yes
# ServerAliveInterval 240
# TCPKeepAlive yes # Default is yes

View File

@ -4,6 +4,3 @@ Host hydra
User nixworker
IdentitiesOnly yes
IdentityFile /persist/manual/ssh/root/keys/id_ed25519
Host *
Compression yes

View File

@ -22,6 +22,9 @@
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
# ClientAliveInterval = 120;
# ClientAliveCountMax = 3;
# TCPKeepAlive = "yes"; # Default is yes
};
hostKeys = [
{

View File

@ -11,7 +11,7 @@ let
attrNames
;
get_shell_values =
get_user_shell_values =
target:
let
homedir = config.users.users."${target.username}".home;
@ -25,6 +25,19 @@ let
username = lib.strings.escapeShellArg "${target.username}";
group = lib.strings.escapeShellArg "${group}";
};
get_global_shell_values =
target:
let
group = config.users.users."${target.username}".group;
in
{
source = lib.strings.escapeShellArg "${target.source}";
destination = lib.strings.escapeShellArg "${target.target}";
mode = lib.strings.escapeShellArg "${target.mode}";
dir_mode = lib.strings.escapeShellArg "${target.dir_mode}";
username = lib.strings.escapeShellArg "${target.username}";
group = lib.strings.escapeShellArg "${group}";
};
install_user_file =
let
constructors = {
@ -33,12 +46,20 @@ let
};
in
stage: target: (constructors."${target.method}"."${stage}" target);
install_global_file =
let
constructors = {
"overwrite" = install_global_file_overwrite;
"symlink" = install_global_file_symlink;
};
in
stage: target: (constructors."${target.method}"."${stage}" target);
install_user_file_overwrite = {
"check" = (target: "");
"install" = (
target:
let
inherit (get_shell_values target)
inherit (get_user_shell_values target)
source
destination
mode
@ -79,7 +100,7 @@ let
"uninstall" = (
target:
let
inherit (get_shell_values target)
inherit (get_user_shell_values target)
source
destination
;
@ -107,7 +128,7 @@ let
"install" = (
target:
let
inherit (get_shell_values target)
inherit (get_user_shell_values target)
source
destination
mode
@ -151,7 +172,7 @@ let
"uninstall" = (
target:
let
inherit (get_shell_values target)
inherit (get_user_shell_values target)
source
destination
;
@ -174,21 +195,148 @@ let
]
);
};
in
{
imports = [ ];
options.me.install = {
user = lib.mkOption {
default = { };
type = lib.types.attrsOf (
lib.types.submodule (
{ name, config, ... }:
install_global_file_overwrite = {
"check" = (target: "");
"install" = (
target:
let
username = name;
inherit (get_global_shell_values target)
source
destination
mode
dir_mode
username
group
;
flags = lib.strings.concatStringsSep " " [
(if mode != "" then "-m ${mode}" else "")
(if username != "" then "-o ${username}" else "")
(if group != "" then "-g ${group}" else "")
];
dir_flags = lib.strings.concatStringsSep " " [
(if dir_mode != "" then "-m ${dir_mode}" else "")
(if username != "" then "-o ${username}" else "")
(if group != "" then "-g ${group}" else "")
];
in
{
options = {
if target.recursive then
[
''
find ${source} -type f -print0 | while read -r -d "" file; do
relative_path=$(realpath -s --relative-to ${source} "$file")
full_dest=${destination}/"$relative_path"
create_containing_directories "$full_dest" ${dir_flags}
$DRY_RUN_CMD install $VERBOSE_ARG --compare ${flags} "$file" "$full_dest"
done
''
]
else
[
''
create_containing_directories ${destination} ${dir_flags}
$DRY_RUN_CMD install $VERBOSE_ARG --compare ${flags} ${source} ${destination}
''
]
);
"uninstall" = (
target:
let
inherit (get_global_shell_values target)
source
destination
;
in
if target.recursive then
[
''
find ${source} -type f -print0 | while read -r -d "" file; do
relative_path=$(realpath -s --relative-to ${source} "$file")
full_dest=${destination}/"$relative_path"
$DRY_RUN_CMD echo rm -f "$full_dest"
done
''
]
else
[
''
$DRY_RUN_CMD echo rm -f ${destination}
''
]
);
};
install_global_file_symlink = {
"check" = (target: "");
"install" = (
target:
let
inherit (get_global_shell_values target)
source
destination
mode
dir_mode
username
group
;
owner = lib.strings.concatStringsSep ":" (
filter (val: val != "") [
username
group
]
);
dir_flags = lib.strings.concatStringsSep " " [
(if dir_mode != "" then "-m ${dir_mode}" else "")
(if username != "" then "-o ${username}" else "")
(if group != "" then "-g ${group}" else "")
];
in
if target.recursive then
[
''
find ${source} -type f -print0 | while read -r -d "" file; do
relative_path=$(realpath -s --relative-to ${source} "$file")
full_dest=${destination}/"$relative_path"
create_containing_directories "$full_dest" ${dir_flags}
$DRY_RUN_CMD ln $VERBOSE_ARG -s "$file" "$full_dest"
$DRY_RUN_CMD chown $VERBOSE_ARG -h ${owner} "$full_dest"
done
''
]
else
[
''
create_containing_directories ${destination} ${dir_flags}
$DRY_RUN_CMD ln $VERBOSE_ARG -s ${source} ${destination}
$DRY_RUN_CMD chown $VERBOSE_ARG -h ${owner} ${destination}
''
]
);
"uninstall" = (
target:
let
inherit (get_global_shell_values target)
source
destination
;
in
if target.recursive then
[
''
find ${source} -type f -print0 | while read -r -d "" file; do
relative_path=$(realpath -s --relative-to ${source} "$file")
full_dest=${destination}/"$relative_path"
$DRY_RUN_CMD echo rm -f "$full_dest"
done
''
]
else
[
''
$DRY_RUN_CMD echo rm -f ${destination}
''
]
);
};
install_target_options = username: {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
@ -198,6 +346,7 @@ in
};
file = lib.mkOption {
default = { };
type = lib.types.attrsOf (
lib.types.submodule (
{ name, config, ... }:
@ -274,11 +423,29 @@ in
);
};
};
in
{
imports = [ ];
options.me.install = (
{
user = lib.mkOption {
default = { };
type = lib.types.attrsOf (
lib.types.submodule (
{ name, config, ... }:
let
username = name;
in
{
options = (install_target_options username);
}
)
);
};
};
}
// (install_target_options "root")
);
config =
let
@ -288,11 +455,17 @@ in
builtins.map (user: (builtins.map (path: user.file."${path}") (attrNames user.file))) enabled_users
);
enabled_file_targets = filter (target: target.enable) all_file_targets;
check_commands = lib.flatten (builtins.map (install_user_file "check") enabled_file_targets);
install_commands = lib.flatten (builtins.map (install_user_file "install") enabled_file_targets);
uninstall_commands = lib.flatten (
builtins.map (install_user_file "uninstall") enabled_file_targets
);
all_global_file_targets = (builtins.map (path: cfg.file."${path}") (attrNames cfg.file));
enabled_global_file_targets = filter (target: target.enable) all_global_file_targets;
check_commands =
(lib.flatten (builtins.map (install_global_file "check") enabled_global_file_targets))
++ (lib.flatten (builtins.map (install_user_file "check") enabled_file_targets));
install_commands =
(lib.flatten (builtins.map (install_global_file "install") enabled_global_file_targets))
++ (lib.flatten (builtins.map (install_user_file "install") enabled_file_targets));
uninstall_commands =
(lib.flatten (builtins.map (install_global_file "uninstall") enabled_global_file_targets))
++ (lib.flatten (builtins.map (install_user_file "uninstall") enabled_file_targets));
in
{
systemd.services.me-install-file = {