sshd: Add support for socket activation

By enabling ‘services.openssh.startWhenNeeded’, sshd is started
on-demand by systemd using socket activation. This is particularly
useful if you have a zillion containers and don't want to have sshd
running permanently. Note that socket activation is not noticeable
slower, contrary to what the manpage for ‘sshd -i’ says, so we might
want to make this the default one day.
This commit is contained in:
Eelco Dolstra 2014-04-22 16:07:53 +02:00
parent 83b43cfe51
commit 03d9e5cda0
2 changed files with 59 additions and 23 deletions

View File

@ -86,6 +86,16 @@ in
'';
};
startWhenNeeded = mkOption {
type = types.bool;
default = false;
description = ''
If set, <command>sshd</command> is socket-activated; that
is, instead of having it permanently running as a daemon,
systemd will start an instance for each incoming connection.
'';
};
forwardX11 = mkOption {
type = types.bool;
default = cfgc.setXAuthLocation;
@ -248,37 +258,60 @@ in
}
];
systemd.services.sshd =
{ description = "SSH Daemon";
systemd =
let
service =
{ description = "SSH Daemon";
wantedBy = [ "multi-user.target" ];
wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target";
stopIfChanged = false;
stopIfChanged = false;
path = [ pkgs.openssh pkgs.gawk ];
path = [ pkgs.openssh pkgs.gawk ];
environment.LD_LIBRARY_PATH = nssModulesPath;
environment.LD_LIBRARY_PATH = nssModulesPath;
preStart =
''
mkdir -m 0755 -p /etc/ssh
preStart =
''
mkdir -m 0755 -p /etc/ssh
${flip concatMapStrings cfg.hostKeys (k: ''
if ! [ -f "${k.path}" ]; then
ssh-keygen -t "${k.type}" -b "${toString k.bits}" -f "${k.path}" -N ""
fi
'')}
'';
${flip concatMapStrings cfg.hostKeys (k: ''
if ! [ -f "${k.path}" ]; then
ssh-keygen -t "${k.type}" -b "${toString k.bits}" -f "${k.path}" -N ""
fi
'')}
'';
serviceConfig =
{ ExecStart =
"${pkgs.openssh}/sbin/sshd " +
"-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
Restart = "always";
Type = "forking";
KillMode = "process";
PIDFile = "/run/sshd.pid";
serviceConfig =
{ ExecStart =
"${pkgs.openssh}/sbin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
"-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
KillMode = "process";
} // (if cfg.startWhenNeeded then {
StandardInput = "socket";
} else {
Restart = "always";
Type = "forking";
PIDFile = "/run/sshd.pid";
});
};
in
if cfg.startWhenNeeded then {
sockets.sshd =
{ description = "SSH Socket";
wantedBy = [ "sockets.target" ];
socketConfig.ListenStream = cfg.ports;
socketConfig.Accept = true;
};
services."sshd@" = service;
} else {
services.sshd = service;
};
networking.firewall.allowedTCPPorts = cfg.ports;

View File

@ -12,6 +12,9 @@ with lib;
networking.useHostResolvConf = true;
# Containers should be light-weight, so start sshd on demand.
services.openssh.startWhenNeeded = mkDefault true;
# Shut up warnings about not having a boot loader.
system.build.installBootLoader = "${pkgs.coreutils}/bin/true";