diff options
Diffstat (limited to 'nixos/modules/services/networking/tmate-ssh-server.nix')
-rw-r--r-- | nixos/modules/services/networking/tmate-ssh-server.nix | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/nixos/modules/services/networking/tmate-ssh-server.nix b/nixos/modules/services/networking/tmate-ssh-server.nix new file mode 100644 index 00000000000..1b8f6662ef4 --- /dev/null +++ b/nixos/modules/services/networking/tmate-ssh-server.nix @@ -0,0 +1,122 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.tmate-ssh-server; + + defaultKeysDir = "/etc/tmate-ssh-server-keys"; + edKey = "${defaultKeysDir}/ssh_host_ed25519_key"; + rsaKey = "${defaultKeysDir}/ssh_host_rsa_key"; + + keysDir = + if cfg.keysDir == null + then defaultKeysDir + else cfg.keysDir; + + domain = config.networking.domain; +in +{ + options.services.tmate-ssh-server = { + enable = mkEnableOption (mdDoc "tmate ssh server"); + + package = mkOption { + type = types.package; + description = mdDoc "The package containing tmate-ssh-server"; + defaultText = literalExpression "pkgs.tmate-ssh-server"; + default = pkgs.tmate-ssh-server; + }; + + host = mkOption { + type = types.str; + description = mdDoc "External host name"; + defaultText = lib.literalExpression "config.networking.domain or config.networking.hostName "; + default = + if domain == null then + config.networking.hostName + else + domain; + }; + + port = mkOption { + type = types.port; + description = mdDoc "Listen port for the ssh server"; + default = 2222; + }; + + openFirewall = mkOption { + type = types.bool; + default = true; + description = mdDoc "Whether to automatically open the specified ports in the firewall."; + }; + + advertisedPort = mkOption { + type = types.port; + description = mdDoc "External port advertised to clients"; + }; + + keysDir = mkOption { + type = with types; nullOr str; + description = mdDoc "Directory containing ssh keys, defaulting to auto-generation"; + default = null; + }; + }; + + config = mkIf cfg.enable { + + networking.firewall.allowedTCPPorts = optionals cfg.openFirewall [ cfg.port ]; + + services.tmate-ssh-server = { + advertisedPort = mkDefault cfg.port; + }; + + environment.systemPackages = + let + tmate-config = pkgs.writeText "tmate.conf" + '' + set -g tmate-server-host "${cfg.host}" + set -g tmate-server-port ${toString cfg.port} + set -g tmate-server-ed25519-fingerprint "@ed25519_fingerprint@" + set -g tmate-server-rsa-fingerprint "@rsa_fingerprint@" + ''; + in + [ + (pkgs.writeShellApplication { + name = "tmate-client-config"; + runtimeInputs = with pkgs;[ openssh coreutils sd ]; + text = '' + RSA_SIG="$(ssh-keygen -l -E SHA256 -f "${keysDir}/ssh_host_rsa_key.pub" | cut -d ' ' -f 2)" + ED25519_SIG="$(ssh-keygen -l -E SHA256 -f "${keysDir}/ssh_host_ed25519_key.pub" | cut -d ' ' -f 2)" + sd -sp '@ed25519_fingerprint@' "$ED25519_SIG" ${tmate-config} | \ + sd -sp '@rsa_fingerprint@' "$RSA_SIG" + ''; + }) + ]; + + systemd.services.tmate-ssh-server = { + description = "tmate SSH Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/tmate-ssh-server -h ${cfg.host} -p ${toString cfg.port} -q ${toString cfg.advertisedPort} -k ${keysDir}"; + }; + preStart = mkIf (cfg.keysDir == null) '' + if [[ ! -d ${defaultKeysDir} ]] + then + mkdir -p ${defaultKeysDir} + fi + if [[ ! -f ${edKey} ]] + then + ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f ${edKey} -N "" + fi + if [[ ! -f ${rsaKey} ]] + then + ${pkgs.openssh}/bin/ssh-keygen -t rsa -f ${rsaKey} -N "" + fi + ''; + }; + }; + + meta = { + maintainers = with maintainers; [ jlesquembre ]; + }; + +} |