{ lib, pkgs, config, ... }: # CVE-2021-44512: fixed in master branch # CVE-2021-44513: fixed in master branch # Introduces compatability with tmate client in NixOS # # TODO: # Add options for all the variables # Configure websockets # Deploy web UI from tmate-master repo with lib; let tmate-ssh-server = pkgs.tmate-ssh-server.overrideAttrs ( old: { src = pkgs.fetchFromGitHub { owner = "tmate-io"; repo = "tmate-ssh-server"; rev = "1f314123df2bb29cb07427ed8663a81c8d9034fd"; sha256 = "sha256-9/xlMvtkNWUBRYYnJx20qEgtEcjagH2NtEKZcDOM1BY="; }; version = "master"; } ); cfg = config.services.tmate; in { options.services.tmate = { enable = mkEnableOption "tmate service"; sshHostname = mkOption { type = types.str; default = "localhost"; description = '' configures the SSH hostname to advertise to tmate hosts ''; }; sshPortListen = mkOption { type = types.port; default = 2200; description = '' port on which the SSH server should listen ''; }; sshKeysPath = mkOption { type = types.str; default = "${cfg.dataDir}/keys"; description = '' path where the ssh keys are located (mandatory) ''; }; openFirewall = mkOption { type = types.bool; default = false; description = '' fix me ''; }; dataDir = mkOption { type = types.str; default = "/var/lib/tmate"; example = "/var/lib/tmate"; description = '' tmate service working directory ''; }; user = mkOption { type = types.str; default = "root"; description = '' User account under which the tmate service runs ''; }; group = mkOption { type = types.str; default = "root"; description = '' Group under which the tmate service runs. ''; }; }; config = mkIf cfg.enable { networking.firewall = { allowedTCPPorts = mkIf cfg.openFirewall [ cfg.sshPortListen ]; }; systemd.services.tmate = { path = [pkgs.openssh]; #execStart = '' # mkdir -p '${cfg.sshKeysPath}' # chmod 0600 '${cfg.dataDir}' #''; preStart = '' gen_key() { keytype=$1 ks=$keytype"_" key="${cfg.sshKeysPath}/ssh_host_"$ks"key" if [ ! -e $key ] ; then ssh-keygen -t $keytype -f $key -N "" echo "" fi SIG=$(ssh-keygen -l -E SHA256 -f "$key.pub" | cut -d ' ' -f 2) } mkdir -p '${cfg.sshKeysPath}' gen_key rsa RSA_SIG=$SIG gen_key ed25519 ED25519_SIG=$SIG { echo "set -g tmate-server-host ${cfg.sshHostname}" echo "set -g tmate-server-port ${toString cfg.sshPortListen}" echo "set -g tmate-server-rsa-fingerprint $RSA_SIG" echo "set -g tmate-server-ed25519-fingerprint $ED25519_SIG" } > '${cfg.dataDir}/tmate.conf' echo 'Copy ${cfg.dataDir}/tmate.conf to ~/.tmate.conf to connect clients to this server' ''; wants = ["network-online.target"]; wantedBy = ["multi-user.target"]; serviceConfig = { ExecStart = "${tmate-ssh-server}/bin/tmate-ssh-server -k ${cfg.sshKeysPath} -p ${toString cfg.sshPortListen} -h ${cfg.sshHostname}"; WorkingDirectory = cfg.dataDir; User = cfg.user; Group = cfg.group; }; }; users = { users.tmate = { description = "tmate service"; group = "tmate"; isSystemUser = true; home = "${cfg.dataDir}"; createHome = true; }; groups = { tmate = {}; }; }; nixpkgs.config.permittedInsecurePackages = [ "tmate-ssh-server-master" ]; }; }