| 6 Mar 2025 |
raitobezarius | From 8d29f82f74491c0e929d7518747d91651fc6e821 Mon Sep 17 00:00:00 2001
From: Raito Bezarius <masterancpp@gmail.com>
Date: Sun, 1 Dec 2024 21:23:06 +0100
Subject: [PATCH] nixos/programs/ssh: support connection to a AF_VSOCK/AF_UNIX
upon demand
Since systemd 256, it's possible to connect to VMs and containers
without using any classical IP networking.
Rather, we can leverage modern AF_VSOCK (for virtual machine
communications) or classical AF_UNIX (for containers).
See
https://www.freedesktop.org/software/systemd/man/256/systemd-ssh-proxy.html
for more documentation.
Change-Id: I2e06a6ebb6d0f34c9cfd69d6dc2aef983b47ed6f
Signed-off-by: Raito Bezarius <masterancpp@gmail.com>
---
nixos/modules/programs/ssh.nix | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/nixos/modules/programs/ssh.nix b/nixos/modules/programs/ssh.nix
index f2ef248d7866..55c2f4d248a0 100644
--- a/nixos/modules/programs/ssh.nix
+++ b/nixos/modules/programs/ssh.nix
@@ -26,6 +26,22 @@ let
knownHostsFiles = [ "/etc/ssh/ssh_known_hosts" ]
++ builtins.map pkgs.copyPathToStore cfg.knownHostsFiles;
+ # Taken from https://www.freedesktop.org/software/systemd/man/256/systemd-ssh-proxy.html
+ sshSystemdProxyConfig = ''
+ # AF_VSOCK / AF_UNIX support for SSH
+ # Built for VMs / containers access without going via the classical networking stack.
+ Host unix/* vsock/*
+ ProxyCommand ${config.systemd.package}/lib/systemd/systemd-ssh-proxy %h %p
+ ProxyUseFdpass yes
+ CheckHostIP no
+
+ # Local host SSH without classical networking
+ Host .host
+ ProxyCommand ${config.systemd.package}/lib/systemd/systemd-ssh-proxy unix/run/ssh-unix-local/socket %p
+ ProxyUseFdpass yes
+ CheckHostIP no
+ '';
+
in
{
###### interface
@@ -33,6 +49,18 @@ in
options = {
programs.ssh = {
+ enableSystemdSshProxySupport = lib.mkOption {
+ type = lib.types.bool;
+ default = false;
+ description = ''
+ Whether to configure `ssh` so that it's possible to perform:
+ - `ssh vsock/<cid>`
+ - `ssh unix/a/path/to/some/container/unix/socket`
+ - `ssh some_name.host` to connect to the local host without involving networking
+
+ See https://www.freedesktop.org/software/systemd/man/256/systemd-ssh-proxy.html for details.
+ '';
+ };
enableAskPassword = lib.mkOption {
type = lib.types.bool;
@@ -295,6 +323,7 @@ in
Host *
GlobalKnownHostsFile ${builtins.concatStringsSep " " knownHostsFiles}
+ ${lib.optionalString (cfg.enableSystemdSshProxySupport) sshSystemdProxyConfig}
${lib.optionalString (!config.networking.enableIPv6) "AddressFamily inet"}
${lib.optionalString cfg.setXAuthLocation "XAuthLocation ${pkgs.xorg.xauth}/bin/xauth"}
${lib.optionalString (cfg.forwardX11 != null) "ForwardX11 ${if cfg.forwardX11 then "yes" else "no"}"}
--
2.47.0
this is almost all what you need IIRC | 19:53:09 |
Arian | E.g. fstab generator. That could be done in nix | 19:53:09 |
@elvishjerricco:matrix.org | I'm so confused | 19:53:53 |
raitobezarius | ok | 19:54:09 |
raitobezarius | maybe don't confuse | 19:54:12 |
raitobezarius | server ssh VSOCK | 19:54:16 |
raitobezarius | and | 19:54:16 |
raitobezarius | client ssh VSOCK | 19:54:18 |
@elvishjerricco:matrix.org | apparently I don't understand socket units | 19:54:46 |
raitobezarius | systemd-ssh-generator is relevant for the server usecase (the one you have in the VM) IIRC, what I dumped is required for the client usecase (the one you have on the hypervisor) if I'm not saying dumb shit | 19:54:48 |
gdamjan | note this is an Accept=yes socket unit, which means pid1 accepts the connection and starts the sshd with the connection file descriptors | 19:56:36 |
@elvishjerricco:matrix.org | oh that makes a lot more sense | 19:57:25 |
@elvishjerricco:matrix.org | so, because the host makes the connection, the socket unit starts the service unit? | 19:58:01 |
@elvishjerricco:matrix.org | do I get that right? | 19:58:09 |
gdamjan | raitobezarius: note 258 will have one more vsock implementation vsock-mux/ https://github.com/systemd/systemd/pull/32941 | 19:58:12 |
gdamjan | or was that in 257? :D | 19:59:03 |
@elvishjerricco:matrix.org | ok a lot more stuff is making a lot more sense | 19:59:07 |
@elvishjerricco:matrix.org | still need to look at the ssh generator pr | 19:59:27 |
gdamjan | yes, one per connection | 20:00:00 |
gdamjan | (in classic inetd mode, so to speak) | 20:00:09 |
@elvishjerricco:matrix.org | thanks | 20:00:21 |
@elvishjerricco:matrix.org | I have a lot to learn about vsock I think | 20:00:29 |
gdamjan | man 7 vsock :D | 20:00:42 |
gdamjan | ugh, I remember it, the man page, was longer | 20:01:13 |
@elvishjerricco:matrix.org | "No manual entry for vsock in section 7" I'm sure it's out there :P | 20:01:13 |
gdamjan | raitobezarius: I think you DO need the vscok module for the AF_VSOCK | 20:02:04 |
gdamjan | * raitobezarius: I think you DO need the vsock module for the AF_VSOCK | 20:02:17 |
@elvishjerricco:matrix.org | this is a tangent but I'm interested in what you mean | 20:03:00 |
@elvishjerricco:matrix.org | I quite like generators | 20:03:12 |
gdamjan | but python -c 'import socket;socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM, 0)' did load the modules automatically | 20:03:26 |