nixos/ttyd: add entrypoint option

This commit is contained in:
Peder Bergebakken Sundt 2024-01-31 17:59:39 +01:00
parent 0d13d2a90f
commit a8880f1647
2 changed files with 26 additions and 9 deletions

View File

@ -62,7 +62,7 @@ in
username = mkOption { username = mkOption {
type = types.nullOr types.str; type = types.nullOr types.str;
default = null; default = null;
description = "Username for basic authentication."; description = "Username for basic http authentication.";
}; };
passwordFile = mkOption { passwordFile = mkOption {
@ -70,7 +70,7 @@ in
default = null; default = null;
apply = value: if value == null then null else toString value; apply = value: if value == null then null else toString value;
description = '' description = ''
File containing the password to use for basic authentication. File containing the password to use for basic http authentication.
For insecurely putting the password in the globally readable store use For insecurely putting the password in the globally readable store use
`pkgs.writeText "ttydpw" "MyPassword"`. `pkgs.writeText "ttydpw" "MyPassword"`.
''; '';
@ -82,6 +82,26 @@ in
description = "Signal to send to the command on session close."; description = "Signal to send to the command on session close.";
}; };
entrypoint = mkOption {
type = types.listOf types.str;
default = [ "${pkgs.shadow}/bin/login" ];
defaultText = lib.literalExpression ''
[ "''${pkgs.shadow}/bin/login" ]
'';
example = lib.literalExpression ''
[ (lib.getExe pkgs.htop) ]
'';
description = "Which command ttyd runs.";
apply = lib.escapeShellArgs;
};
user = mkOption {
type = types.str;
# `login` needs to be run as root
default = "root";
description = "Which unix user ttyd should run as.";
};
writeable = mkOption { writeable = mkOption {
type = types.nullOr types.bool; type = types.nullOr types.bool;
default = null; # null causes an eval error, forcing the user to consider attack surface default = null; # null causes an eval error, forcing the user to consider attack surface
@ -193,9 +213,7 @@ in
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
serviceConfig = { serviceConfig = {
# Runs login which needs to be run as root User = cfg.user;
# login: Cannot possibly work without effective root
User = "root";
LoadCredential = lib.optionalString (cfg.passwordFile != null) "TTYD_PASSWORD_FILE:${cfg.passwordFile}"; LoadCredential = lib.optionalString (cfg.passwordFile != null) "TTYD_PASSWORD_FILE:${cfg.passwordFile}";
}; };
@ -203,11 +221,11 @@ in
PASSWORD=$(cat "$CREDENTIALS_DIRECTORY/TTYD_PASSWORD_FILE") PASSWORD=$(cat "$CREDENTIALS_DIRECTORY/TTYD_PASSWORD_FILE")
${pkgs.ttyd}/bin/ttyd ${lib.escapeShellArgs args} \ ${pkgs.ttyd}/bin/ttyd ${lib.escapeShellArgs args} \
--credential ${lib.escapeShellArg cfg.username}:"$PASSWORD" \ --credential ${lib.escapeShellArg cfg.username}:"$PASSWORD" \
${pkgs.shadow}/bin/login ${cfg.entrypoint}
'' ''
else '' else ''
${pkgs.ttyd}/bin/ttyd ${lib.escapeShellArgs args} \ ${pkgs.ttyd}/bin/ttyd ${lib.escapeShellArgs args} \
${pkgs.shadow}/bin/login ${cfg.entrypoint}
''; '';
}; };
}; };

View File

@ -5,8 +5,7 @@ import ../make-test-python.nix ({ lib, pkgs, ... }: {
nodes.readonly = { pkgs, ... }: { nodes.readonly = { pkgs, ... }: {
services.ttyd = { services.ttyd = {
enable = true; enable = true;
username = "foo"; entrypoint = [ (lib.getExe pkgs.htop) ];
passwordFile = pkgs.writeText "password" "bar";
writeable = false; writeable = false;
}; };
}; };