-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
108 changed files
with
3,182 additions
and
673 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
{ config, lib, pkgs, ... }: | ||
|
||
with lib; | ||
|
||
let | ||
cfg = config.services.uptermd; | ||
in | ||
{ | ||
options = { | ||
services.uptermd = { | ||
enable = mkEnableOption "uptermd"; | ||
|
||
openFirewall = mkOption { | ||
type = types.bool; | ||
default = false; | ||
description = '' | ||
Whether to open the firewall for the port in <option>services.uptermd.port</option>. | ||
''; | ||
}; | ||
|
||
port = mkOption { | ||
type = types.port; | ||
default = 2222; | ||
description = '' | ||
Port the server will listen on. | ||
''; | ||
}; | ||
|
||
listenAddress = mkOption { | ||
type = types.str; | ||
default = "[::]"; | ||
example = "127.0.0.1"; | ||
description = '' | ||
Address the server will listen on. | ||
''; | ||
}; | ||
|
||
hostKey = mkOption { | ||
type = types.nullOr types.path; | ||
default = null; | ||
example = "/run/keys/upterm_host_ed25519_key"; | ||
description = '' | ||
Path to SSH host key. If not defined, an ed25519 keypair is generated automatically. | ||
''; | ||
}; | ||
|
||
extraFlags = mkOption { | ||
type = types.listOf types.str; | ||
default = []; | ||
example = [ "--debug" ]; | ||
description = '' | ||
Extra flags passed to the uptermd command. | ||
''; | ||
}; | ||
}; | ||
}; | ||
|
||
config = mkIf cfg.enable { | ||
networking.firewall = mkIf cfg.openFirewall { | ||
allowedTCPPorts = [ cfg.port ]; | ||
}; | ||
|
||
systemd.services.uptermd = { | ||
description = "Upterm Daemon"; | ||
wantedBy = [ "multi-user.target" ]; | ||
after = [ "network.target" ]; | ||
|
||
path = [ pkgs.openssh ]; | ||
|
||
preStart = mkIf (cfg.hostKey == null) '' | ||
if ! [ -f ssh_host_ed25519_key ]; then | ||
ssh-keygen \ | ||
-t ed25519 \ | ||
-f ssh_host_ed25519_key \ | ||
-N "" | ||
fi | ||
''; | ||
|
||
serviceConfig = { | ||
StateDirectory = "uptermd"; | ||
WorkingDirectory = "/var/lib/uptermd"; | ||
ExecStart = "${pkgs.upterm}/bin/uptermd --ssh-addr ${cfg.listenAddress}:${toString cfg.port} --private-key ${if cfg.hostKey == null then "ssh_host_ed25519_key" else cfg.hostKey} ${concatStringsSep " " cfg.extraFlags}"; | ||
|
||
# Hardening | ||
AmbientCapabilities = mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; | ||
CapabilityBoundingSet = mkIf (cfg.port < 1024) [ "CAP_NET_BIND_SERVICE" ]; | ||
PrivateUsers = cfg.port >= 1024; | ||
LockPersonality = true; | ||
MemoryDenyWriteExecute = true; | ||
PrivateDevices = true; | ||
ProtectClock = true; | ||
ProtectControlGroups = true; | ||
ProtectHome = true; | ||
ProtectHostname = true; | ||
ProtectKernelLogs = true; | ||
ProtectKernelModules = true; | ||
ProtectKernelTunables = true; | ||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; | ||
RestrictNamespaces = true; | ||
RestrictRealtime = true; | ||
SystemCallArchitectures = "native"; | ||
SystemCallFilter = "@system-service"; | ||
}; | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import ./make-test-python.nix ({ pkgs, ...}: | ||
|
||
let | ||
client = {pkgs, ...}:{ | ||
environment.systemPackages = [ pkgs.upterm ]; | ||
}; | ||
in | ||
{ | ||
name = "uptermd"; | ||
meta = with pkgs.lib.maintainers; { | ||
maintainers = [ fleaz ]; | ||
}; | ||
|
||
nodes = { | ||
server = {config, ...}: { | ||
services.uptermd = { | ||
enable = true; | ||
openFirewall = true; | ||
port = 1337; | ||
}; | ||
}; | ||
client1 = client; | ||
client2 = client; | ||
}; | ||
|
||
|
||
testScript = '' | ||
start_all() | ||
server.wait_for_unit("uptermd.service") | ||
server.wait_for_unit("network-online.target") | ||
# Add SSH hostkeys from the server to both clients | ||
# uptermd needs an '@cert-authority entry so we need to modify the known_hosts file | ||
client1.execute("sleep 3; mkdir -p ~/.ssh && ssh -o StrictHostKeyChecking=no -p 1337 server ls") | ||
client1.execute("echo @cert-authority $(cat ~/.ssh/known_hosts) > ~/.ssh/known_hosts") | ||
client2.execute("sleep 3; mkdir -p ~/.ssh && ssh -o StrictHostKeyChecking=no -p 1337 server ls") | ||
client2.execute("echo @cert-authority $(cat ~/.ssh/known_hosts) > ~/.ssh/known_hosts") | ||
client1.wait_for_unit("multi-user.target") | ||
client1.wait_until_succeeds("pgrep -f 'agetty.*tty1'") | ||
client1.wait_until_tty_matches(1, "login: ") | ||
client1.send_chars("root\n") | ||
client1.wait_until_succeeds("pgrep -u root bash") | ||
client1.execute("ssh-keygen -t ed25519 -N \"\" -f /root/.ssh/id_ed25519") | ||
client1.send_chars("TERM=xterm upterm host --server ssh://server:1337 --force-command hostname -- bash > /tmp/session-details\n") | ||
client1.wait_for_file("/tmp/session-details") | ||
client1.send_key("q") | ||
# uptermd can't connect if we don't have a keypair | ||
client2.execute("ssh-keygen -t ed25519 -N \"\" -f /root/.ssh/id_ed25519") | ||
# Grep the ssh connect command from the output of 'upterm host' | ||
ssh_command = client1.succeed("grep 'SSH Session' /tmp/session-details | cut -d':' -f2-").strip() | ||
# Connect with client2. Because we used '--force-command hostname' we should get "client1" as the output | ||
output = client2.succeed(ssh_command) | ||
assert output.strip() == "client1" | ||
''; | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.