diff --git a/configs/ssh.nix b/configs/ssh.nix index 49617f3..d2afe22 100644 --- a/configs/ssh.nix +++ b/configs/ssh.nix @@ -60,6 +60,7 @@ user = "kfm"; port = pkgs.lib.niveum.sshPort; }; + "*.onion".proxyCommand = "nc -xlocalhost:9050 %h %p"; }; }; } diff --git a/configs/tor.nix b/configs/tor.nix index 1813cb6..371bec8 100644 --- a/configs/tor.nix +++ b/configs/tor.nix @@ -1,4 +1,7 @@ -{ pkgs, ... }: +{ config, lib, pkgs, ... }: +let + sshPort = pkgs.lib.niveum.machines.${config.networking.hostName}.sshPort; +in { services.tor.enable = true; services.tor.client.enable = true; @@ -6,4 +9,15 @@ pkgs.tor pkgs.torsocks ]; + + services.tor.relay.onionServices = { + "ssh" = { + version = 3; + map = [{ + port = sshPort; + target.port = sshPort; + target.addr = "127.0.0.1"; + }]; + }; + }; } diff --git a/flake.nix b/flake.nix index 56c3e08..fe4f785 100644 --- a/flake.nix +++ b/flake.nix @@ -320,6 +320,7 @@ swallow = prev.callPackage packages/swallow.nix { }; tocharian-font = prev.callPackage packages/tocharian-font.nix { }; ttspaste = prev.callPackage packages/ttspaste.nix { }; + niveum-ssh = prev.callPackage packages/niveum-ssh.nix { }; unicodmenu = prev.callPackage packages/unicodmenu.nix { }; vg = prev.callPackage packages/vg.nix { }; vim-kmein = prev.callPackage packages/vim-kmein { }; diff --git a/lib/default.nix b/lib/default.nix index 3ff4da6..d2b8867 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -81,6 +81,9 @@ in myceliumAddresses = lib.mapAttrs (_: v: v.mycelium.ipv6) ( lib.filterAttrs (_: v: v ? "mycelium") machines ); + torAddresses = lib.mapAttrs (_: v: v.torAddress) ( + lib.filterAttrs (_: v: v ? "torAddress") machines + ); syncthingIds = lib.mapAttrs (_: v: { id = v.syncthingId; }) ( lib.filterAttrs (_: v: v ? "syncthingId") machines ); diff --git a/lib/machines.nix b/lib/machines.nix index 4e2cd3b..1d29784 100644 --- a/lib/machines.nix +++ b/lib/machines.nix @@ -31,6 +31,7 @@ in ipv6 = "42:0:3c46:aa73:82b0:14d7:7bf8:bf2"; ipv4 = "10.243.2.77"; }; + torAddress = "uoe7poyeliuaudf4x5nrwvs3t55ldcdpfqfyeqsadbs77ttjx7upquyd.onion"; mycelium.ipv6 = "463:a0d4:daa3:aa8d:a9b1:744a:46a5:7a80"; inherit sshPort; system = "x86_64-linux"; @@ -45,6 +46,7 @@ in ipv6 = "42:0:3c46:2c8b:a564:1213:9fb4:1bc4"; }; mycelium.ipv6 = "5bf:d60e:bebf:5163:f495:8787:880c:6d41"; + torAddress = "ll3k2akcpwuo562hlbr452yvzhi6kmpjzcnjgw6z4nege2yftspgjjad.onion"; inherit sshPort; system = "aarch64-linux"; }; @@ -54,6 +56,7 @@ in ipv6 = "42:0:3c46:156e:10b6:3bd6:6e82:b2cd"; }; mycelium.ipv6 = "5c5:49e0:7793:f017:59e1:1715:9e0e:3fc8"; + torAddress = "hurgxlejplh7lj2hyaj4gk2fuearibst6axdxl2ekfohiivyiab3gkad.onion"; inherit sshPort; system = "x86_64-linux"; }; @@ -64,6 +67,7 @@ in ipv6 = "42:0:3c46:f7a9:1f0a:1b2b:822a:6050"; }; mycelium.ipv6 = "43f:ad4f:fa67:d9f7:8a56:713c:7418:164b"; + torAddress = "gnaoacvkhovpllpiwi4a4mbnx4awpdcufwtsj365tiweybdeec7thuyd.onion"; inherit sshPort; system = "x86_64-linux"; }; diff --git a/packages/niveum-ssh.nix b/packages/niveum-ssh.nix new file mode 100644 index 0000000..e6425d4 --- /dev/null +++ b/packages/niveum-ssh.nix @@ -0,0 +1,66 @@ +{ + symlinkJoin, + writers, + lib, + netcat, + openssh, +}: +let + inherit (lib.niveum) machines; + sshableMachines = lib.filterAttrs (name: value: value ? "sshPort") machines; + systemAddresses = + system: + lib.optionals (system ? "internalIp") [ system.internalIp ] + ++ lib.optionals (system ? "externalIp") [ system.externalIp ] + ++ lib.optionals (system ? "retiolum") [ + system.retiolum.ipv6 + system.retiolum.ipv4 + ] + ++ lib.optionals (system ? "mycelium") [ system.mycelium.ipv6 ] + ++ lib.optionals (system ? "torAddress") [ system.torAddress ]; + addresses = lib.listToAttrs ( + map (name: { + inherit name; + value = systemAddresses (machines.${name}); + }) (builtins.attrNames sshableMachines) + ); +in +symlinkJoin { + name = "niveum-ssh"; + paths = lib.mapAttrsToList ( + hostname: _: + writers.writeBashBin "niveum-ssh-${hostname}" '' + targets=( + ${lib.concatStringsSep " " (map (addr: "\"root@${addr}\"") addresses.${hostname})} + ) + + for target in "''${targets[@]}"; do + host="$(echo $target | cut -d'@' -f2)" + + # Check if it's an onion address + if [[ "$host" == *.onion ]]; then + # For onion addresses, try connecting through Tor + if ${netcat}/bin/nc -z localhost 9050 2>/dev/null; then + echo "Trying $target via Tor..." >&2 + if echo | ${netcat}/bin/nc -x localhost:9050 -w 5 "$host" ${ + toString machines.${hostname}.sshPort + } 2>/dev/null; then + exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} \ + -o ProxyCommand="${netcat}/bin/nc -x localhost:9050 %h %p" \ + "$target" "$@" + fi + fi + else + # For regular addresses, try direct connection + echo "Trying $target..." >&2 + if ${netcat}/bin/nc -z -w 2 "$host" ${toString machines.${hostname}.sshPort} 2>/dev/null; then + exec ${openssh}/bin/ssh -p ${toString machines.${hostname}.sshPort} "$target" "$@" + fi + fi + done + + echo "No reachable target found for ${hostname}" >&2 + exit 1 + '' + ) sshableMachines; +}