fix(ssh): make sandboxed ssh work on Linux (#390)

This commit is contained in:
ryan4yin | 二花 authored and GitHub committed 2026-10-06 15:20:53 +08:00
1 parent 187577b2da
commit dc65254511
3 files changed
+27

No files matched your search

+1
View File
@@ -37,6 +37,7 @@ A setting that works around a bug or a hardware quirk.
| WA-010 | Insta360 Link USB reset on S3 resume — `hosts/idols-ai/default.nix` | the camera stays enumerated with a stalled UVC endpoint after resume | Drop after the Insta360 firmware or the kernel `uvcvideo` fixes it | 2026-08-01 | on kernel or firmware change | active |
| WA-011 | Kernel module blacklist (`esp4`, `esp6`, `rxrpc`) — `hardening/kernel-hardening.nix` | attack surface for the Dirty Frag LPE (CVE-2026-43284 / CVE-2026-43500) | Kept as defence in depth; drop only if something needs those modules | 2026-10-03 | rarely | active |
| WA-017 | keyd right-hand modifier passthrough — `modules/nixos/desktop/peripherals.nix` | keyd folds right Ctrl/Shift/Meta into their left keys | Drop once keyd or fcitx5 keeps right-hand modifiers distinct | 2026-10-05 | on keyd bump | active |
| WA-018 | user-owned `~/.ssh/config` + disabled systemd ssh-proxy include — `home/base/tui/ssh.nix`, `modules/nixos/base/ssh.nix` | bwrap exposes root-owned store files as `nobody` | Drop once sandboxes preserve store ownership | 2026-10-06 | when sandbox layout changes | active |
If WA-008 freezes recur, the fallback is to restore
`nvme_core.default_ps_max_latency_us=0 nvme_core.io_timeout=4294967295 pcie_aspm=off`; this is a
+19
View File
@@ -1,5 +1,7 @@
{
config,
lib,
pkgs,
mysecrets,
...
}:
@@ -41,4 +43,21 @@
};
};
};
# Keep ~/.ssh/config a real, user-owned file rather than a /nix/store symlink.
#
# OpenSSH accepts a config owned by root or the invoking user, but
# bubblewrap-based sandboxes (`--unshare-user`) expose root-owned store files
# as `nobody`, which trips the check (`Bad owner or permissions`). Disabling
# the home.file entry keeps Home Manager's linker out of the way; `install`
# writes a fresh 0600 copy on each activation.
#
# Linux only: macOS' Seatbelt sandbox keeps store ownership intact, so the
# normal symlink is fine there.
home.file.".ssh/config".enable = lib.mkIf pkgs.stdenv.hostPlatform.isLinux false;
home.activation.sshConfigRegularFile = lib.mkIf pkgs.stdenv.hostPlatform.isLinux (
lib.hm.dag.entryAfter [ "linkGeneration" ] ''
run install -D -m 600 ${config.home.file.".ssh/config".source} "$HOME/.ssh/config"
''
);
}
+7
View File
@@ -18,6 +18,13 @@
openFirewall = true;
};
# NixOS appends an `Include` of systemd's ssh_config.d drop-in to
# /etc/ssh/ssh_config, and OpenSSH re-applies SSHCONF_CHECKPERM to included
# files. A bubblewrap sandbox (`--unshare-user`) exposes root-owned store
# files as `nobody`, which would abort ssh there. We do not use
# systemd-ssh-proxy (.host, machine/*, unix/*, vsock/*).
programs.ssh.systemd-ssh-proxy.enable = false;
# Terminfo for the terminals we use, so `$TERM` resolves on hosts we SSH into.
environment.systemPackages = [
pkgs.ghostty.terminfo