nixos/services.openssh: remove with lib;
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
||||
# The splicing information needed for nativeBuildInputs isn't available
|
||||
@@ -17,8 +14,8 @@ let
|
||||
let
|
||||
# reports boolean as yes / no
|
||||
mkValueString = with lib; v:
|
||||
if isInt v then toString v
|
||||
else if isString v then v
|
||||
if lib.isInt v then toString v
|
||||
else if lib.isString v then v
|
||||
else if true == v then "yes"
|
||||
else if false == v then "no"
|
||||
else throw "unsupported type ${builtins.typeOf v}: ${(lib.generators.toPretty {}) v}";
|
||||
@@ -37,10 +34,10 @@ let
|
||||
in {
|
||||
inherit (base) type;
|
||||
generate = name: value:
|
||||
let transformedValue = mapAttrs (key: val:
|
||||
if isList val then
|
||||
if elem key commaSeparated then concatStringsSep "," val
|
||||
else if elem key spaceSeparated then concatStringsSep " " val
|
||||
let transformedValue = lib.mapAttrs (key: val:
|
||||
if lib.isList val then
|
||||
if lib.elem key commaSeparated then lib.concatStringsSep "," val
|
||||
else if lib.elem key spaceSeparated then lib.concatStringsSep " " val
|
||||
else throw "list value for unknown key ${key}: ${(lib.generators.toPretty {}) val}"
|
||||
else
|
||||
val
|
||||
@@ -49,7 +46,7 @@ let
|
||||
base.generate name transformedValue;
|
||||
};
|
||||
|
||||
configFile = settingsFormat.generate "sshd.conf-settings" (filterAttrs (n: v: v != null) cfg.settings);
|
||||
configFile = settingsFormat.generate "sshd.conf-settings" (lib.filterAttrs (n: v: v != null) cfg.settings);
|
||||
sshconf = pkgs.runCommand "sshd.conf-final" { } ''
|
||||
cat ${configFile} - >$out <<EOL
|
||||
${cfg.extraConfig}
|
||||
@@ -65,8 +62,8 @@ let
|
||||
userOptions = {
|
||||
|
||||
options.openssh.authorizedKeys = {
|
||||
keys = mkOption {
|
||||
type = types.listOf types.singleLineStr;
|
||||
keys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.singleLineStr;
|
||||
default = [];
|
||||
description = ''
|
||||
A list of verbatim OpenSSH public keys that should be added to the
|
||||
@@ -83,8 +80,8 @@ let
|
||||
];
|
||||
};
|
||||
|
||||
keyFiles = mkOption {
|
||||
type = types.listOf types.path;
|
||||
keyFiles = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.path;
|
||||
default = [];
|
||||
description = ''
|
||||
A list of files each containing one OpenSSH public key that should be
|
||||
@@ -96,8 +93,8 @@ let
|
||||
};
|
||||
};
|
||||
|
||||
options.openssh.authorizedPrincipals = mkOption {
|
||||
type = with types; listOf types.singleLineStr;
|
||||
options.openssh.authorizedPrincipals = lib.mkOption {
|
||||
type = with lib.types; listOf lib.types.singleLineStr;
|
||||
default = [];
|
||||
description = ''
|
||||
A list of verbatim principal names that should be added to the user's
|
||||
@@ -112,46 +109,46 @@ let
|
||||
};
|
||||
|
||||
authKeysFiles = let
|
||||
mkAuthKeyFile = u: nameValuePair "ssh/authorized_keys.d/${u.name}" {
|
||||
mkAuthKeyFile = u: lib.nameValuePair "ssh/authorized_keys.d/${u.name}" {
|
||||
mode = "0444";
|
||||
source = pkgs.writeText "${u.name}-authorized_keys" ''
|
||||
${concatStringsSep "\n" u.openssh.authorizedKeys.keys}
|
||||
${concatMapStrings (f: readFile f + "\n") u.openssh.authorizedKeys.keyFiles}
|
||||
${lib.concatStringsSep "\n" u.openssh.authorizedKeys.keys}
|
||||
${lib.concatMapStrings (f: lib.readFile f + "\n") u.openssh.authorizedKeys.keyFiles}
|
||||
'';
|
||||
};
|
||||
usersWithKeys = attrValues (flip filterAttrs config.users.users (n: u:
|
||||
length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0
|
||||
usersWithKeys = lib.attrValues (lib.flip lib.filterAttrs config.users.users (n: u:
|
||||
lib.length u.openssh.authorizedKeys.keys != 0 || lib.length u.openssh.authorizedKeys.keyFiles != 0
|
||||
));
|
||||
in listToAttrs (map mkAuthKeyFile usersWithKeys);
|
||||
in lib.listToAttrs (map mkAuthKeyFile usersWithKeys);
|
||||
|
||||
authPrincipalsFiles = let
|
||||
mkAuthPrincipalsFile = u: nameValuePair "ssh/authorized_principals.d/${u.name}" {
|
||||
mkAuthPrincipalsFile = u: lib.nameValuePair "ssh/authorized_principals.d/${u.name}" {
|
||||
mode = "0444";
|
||||
text = concatStringsSep "\n" u.openssh.authorizedPrincipals;
|
||||
text = lib.concatStringsSep "\n" u.openssh.authorizedPrincipals;
|
||||
};
|
||||
usersWithPrincipals = attrValues (flip filterAttrs config.users.users (n: u:
|
||||
length u.openssh.authorizedPrincipals != 0
|
||||
usersWithPrincipals = lib.attrValues (lib.flip lib.filterAttrs config.users.users (n: u:
|
||||
lib.length u.openssh.authorizedPrincipals != 0
|
||||
));
|
||||
in listToAttrs (map mkAuthPrincipalsFile usersWithPrincipals);
|
||||
in lib.listToAttrs (map mkAuthPrincipalsFile usersWithPrincipals);
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
imports = [
|
||||
(mkAliasOptionModuleMD [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ])
|
||||
(mkAliasOptionModuleMD [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "challengeResponseAuthentication" ] [ "services" "openssh" "kbdInteractiveAuthentication" ])
|
||||
(lib.mkAliasOptionModuleMD [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ])
|
||||
(lib.mkAliasOptionModuleMD [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "challengeResponseAuthentication" ] [ "services" "openssh" "kbdInteractiveAuthentication" ])
|
||||
|
||||
(mkRenamedOptionModule [ "services" "openssh" "kbdInteractiveAuthentication" ] [ "services" "openssh" "settings" "KbdInteractiveAuthentication" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "passwordAuthentication" ] [ "services" "openssh" "settings" "PasswordAuthentication" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "useDns" ] [ "services" "openssh" "settings" "UseDns" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "permitRootLogin" ] [ "services" "openssh" "settings" "PermitRootLogin" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "logLevel" ] [ "services" "openssh" "settings" "LogLevel" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "macs" ] [ "services" "openssh" "settings" "Macs" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "ciphers" ] [ "services" "openssh" "settings" "Ciphers" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "kexAlgorithms" ] [ "services" "openssh" "settings" "KexAlgorithms" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "gatewayPorts" ] [ "services" "openssh" "settings" "GatewayPorts" ])
|
||||
(mkRenamedOptionModule [ "services" "openssh" "forwardX11" ] [ "services" "openssh" "settings" "X11Forwarding" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "kbdInteractiveAuthentication" ] [ "services" "openssh" "settings" "KbdInteractiveAuthentication" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "passwordAuthentication" ] [ "services" "openssh" "settings" "PasswordAuthentication" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "useDns" ] [ "services" "openssh" "settings" "UseDns" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "permitRootLogin" ] [ "services" "openssh" "settings" "PermitRootLogin" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "logLevel" ] [ "services" "openssh" "settings" "LogLevel" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "macs" ] [ "services" "openssh" "settings" "Macs" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "ciphers" ] [ "services" "openssh" "settings" "Ciphers" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "kexAlgorithms" ] [ "services" "openssh" "settings" "KexAlgorithms" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "gatewayPorts" ] [ "services" "openssh" "settings" "GatewayPorts" ])
|
||||
(lib.mkRenamedOptionModule [ "services" "openssh" "forwardX11" ] [ "services" "openssh" "settings" "X11Forwarding" ])
|
||||
];
|
||||
|
||||
###### interface
|
||||
@@ -160,8 +157,8 @@ in
|
||||
|
||||
services.openssh = {
|
||||
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to enable the OpenSSH secure shell daemon, which
|
||||
@@ -169,15 +166,15 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = config.programs.ssh.package;
|
||||
defaultText = literalExpression "programs.ssh.package";
|
||||
defaultText = lib.literalExpression "programs.ssh.package";
|
||||
description = "OpenSSH package to use for sshd.";
|
||||
};
|
||||
|
||||
startWhenNeeded = mkOption {
|
||||
type = types.bool;
|
||||
startWhenNeeded = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
If set, {command}`sshd` is socket-activated; that
|
||||
@@ -186,8 +183,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
allowSFTP = mkOption {
|
||||
type = types.bool;
|
||||
allowSFTP = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to enable the SFTP subsystem in the SSH daemon. This
|
||||
@@ -196,8 +193,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sftpServerExecutable = mkOption {
|
||||
type = types.str;
|
||||
sftpServerExecutable = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "internal-sftp";
|
||||
description = ''
|
||||
The sftp server executable. Can be a path or "internal-sftp" to use
|
||||
@@ -205,8 +202,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
sftpFlags = mkOption {
|
||||
type = with types; listOf str;
|
||||
sftpFlags = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
default = [];
|
||||
example = [ "-f AUTHPRIV" "-l INFO" ];
|
||||
description = ''
|
||||
@@ -214,34 +211,34 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
ports = mkOption {
|
||||
type = types.listOf types.port;
|
||||
ports = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.port;
|
||||
default = [22];
|
||||
description = ''
|
||||
Specifies on which ports the SSH daemon listens.
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Whether to automatically open the specified ports in the firewall.
|
||||
'';
|
||||
};
|
||||
|
||||
listenAddresses = mkOption {
|
||||
type = with types; listOf (submodule {
|
||||
listenAddresses = lib.mkOption {
|
||||
type = with lib.types; listOf (submodule {
|
||||
options = {
|
||||
addr = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
addr = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = ''
|
||||
Host, IPv4 or IPv6 address to listen to.
|
||||
'';
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
port = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
description = ''
|
||||
Port to listen to.
|
||||
@@ -261,8 +258,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
hostKeys = mkOption {
|
||||
type = types.listOf types.attrs;
|
||||
hostKeys = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default =
|
||||
[ { type = "rsa"; bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; }
|
||||
{ type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
|
||||
@@ -279,16 +276,16 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
banner = mkOption {
|
||||
type = types.nullOr types.lines;
|
||||
banner = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.lines;
|
||||
default = null;
|
||||
description = ''
|
||||
Message to display to the remote user before authentication is allowed.
|
||||
'';
|
||||
};
|
||||
|
||||
authorizedKeysFiles = mkOption {
|
||||
type = types.listOf types.str;
|
||||
authorizedKeysFiles = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Specify the rules for which files to read on the host.
|
||||
@@ -303,8 +300,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
authorizedKeysInHomedir = mkOption {
|
||||
type = types.bool;
|
||||
authorizedKeysInHomedir = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Enables the use of the `~/.ssh/authorized_keys` file.
|
||||
@@ -314,8 +311,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
authorizedKeysCommand = mkOption {
|
||||
type = types.str;
|
||||
authorizedKeysCommand = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "none";
|
||||
description = ''
|
||||
Specifies a program to be used to look up the user's public
|
||||
@@ -324,8 +321,8 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
authorizedKeysCommandUser = mkOption {
|
||||
type = types.str;
|
||||
authorizedKeysCommandUser = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "nobody";
|
||||
description = ''
|
||||
Specifies the user under whose account the AuthorizedKeysCommand
|
||||
@@ -336,28 +333,28 @@ in
|
||||
|
||||
|
||||
|
||||
settings = mkOption {
|
||||
settings = lib.mkOption {
|
||||
description = "Configuration for `sshd_config(5)`.";
|
||||
default = { };
|
||||
example = literalExpression ''
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
UseDns = true;
|
||||
PasswordAuthentication = false;
|
||||
}
|
||||
'';
|
||||
type = types.submodule ({name, ...}: {
|
||||
type = lib.types.submodule ({name, ...}: {
|
||||
freeformType = settingsFormat.type;
|
||||
options = {
|
||||
AuthorizedPrincipalsFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
AuthorizedPrincipalsFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "none"; # upstream default
|
||||
description = ''
|
||||
Specifies a file that lists principal names that are accepted for certificate authentication. The default
|
||||
is `"none"`, i.e. not to use a principals file.
|
||||
'';
|
||||
};
|
||||
LogLevel = mkOption {
|
||||
type = types.nullOr (types.enum [ "QUIET" "FATAL" "ERROR" "INFO" "VERBOSE" "DEBUG" "DEBUG1" "DEBUG2" "DEBUG3" ]);
|
||||
LogLevel = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.enum [ "QUIET" "FATAL" "ERROR" "INFO" "VERBOSE" "DEBUG" "DEBUG1" "DEBUG2" "DEBUG3" ]);
|
||||
default = "INFO"; # upstream default
|
||||
description = ''
|
||||
Gives the verbosity level that is used when logging messages from sshd(8). Logging with a DEBUG level
|
||||
@@ -365,10 +362,10 @@ in
|
||||
'';
|
||||
};
|
||||
UsePAM =
|
||||
mkEnableOption "PAM authentication"
|
||||
// { default = true; type = types.nullOr types.bool; };
|
||||
UseDns = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
lib.mkEnableOption "PAM authentication"
|
||||
// { default = true; type = lib.types.nullOr lib.types.bool; };
|
||||
UseDns = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.bool;
|
||||
# apply if cfg.useDns then "yes" else "no"
|
||||
default = false;
|
||||
description = ''
|
||||
@@ -378,36 +375,36 @@ in
|
||||
~/.ssh/authorized_keys from and sshd_config Match Host directives.
|
||||
'';
|
||||
};
|
||||
X11Forwarding = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
X11Forwarding = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to allow X11 connections to be forwarded.
|
||||
'';
|
||||
};
|
||||
PasswordAuthentication = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
PasswordAuthentication = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Specifies whether password authentication is allowed.
|
||||
'';
|
||||
};
|
||||
PermitRootLogin = mkOption {
|
||||
PermitRootLogin = lib.mkOption {
|
||||
default = "prohibit-password";
|
||||
type = types.nullOr (types.enum ["yes" "without-password" "prohibit-password" "forced-commands-only" "no"]);
|
||||
type = lib.types.nullOr (lib.types.enum ["yes" "without-password" "prohibit-password" "forced-commands-only" "no"]);
|
||||
description = ''
|
||||
Whether the root user can login using ssh.
|
||||
'';
|
||||
};
|
||||
KbdInteractiveAuthentication = mkOption {
|
||||
type = types.nullOr types.bool;
|
||||
KbdInteractiveAuthentication = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.bool;
|
||||
default = true;
|
||||
description = ''
|
||||
Specifies whether keyboard-interactive authentication is allowed.
|
||||
'';
|
||||
};
|
||||
GatewayPorts = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
GatewayPorts = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "no";
|
||||
description = ''
|
||||
Specifies whether remote hosts are allowed to connect to
|
||||
@@ -415,8 +412,8 @@ in
|
||||
{manpage}`sshd_config(5)`.
|
||||
'';
|
||||
};
|
||||
KexAlgorithms = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
KexAlgorithms = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = [
|
||||
"sntrup761x25519-sha512@openssh.com"
|
||||
"curve25519-sha256"
|
||||
@@ -432,8 +429,8 @@ in
|
||||
<https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
|
||||
'';
|
||||
};
|
||||
Macs = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
Macs = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = [
|
||||
"hmac-sha2-512-etm@openssh.com"
|
||||
"hmac-sha2-256-etm@openssh.com"
|
||||
@@ -448,15 +445,15 @@ in
|
||||
<https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
|
||||
'';
|
||||
};
|
||||
StrictModes = mkOption {
|
||||
type = types.nullOr (types.bool);
|
||||
StrictModes = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.bool);
|
||||
default = true;
|
||||
description = ''
|
||||
Whether sshd should check file modes and ownership of directories
|
||||
'';
|
||||
};
|
||||
Ciphers = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
Ciphers = lib.mkOption {
|
||||
type = lib.types.nullOr (lib.types.listOf lib.types.str);
|
||||
default = [
|
||||
"chacha20-poly1305@openssh.com"
|
||||
"aes256-gcm@openssh.com"
|
||||
@@ -474,16 +471,16 @@ in
|
||||
<https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67>
|
||||
'';
|
||||
};
|
||||
AllowUsers = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
AllowUsers = lib.mkOption {
|
||||
type = with lib.types; nullOr (listOf str);
|
||||
default = null;
|
||||
description = ''
|
||||
If specified, login is allowed only for the listed users.
|
||||
See {manpage}`sshd_config(5)` for details.
|
||||
'';
|
||||
};
|
||||
DenyUsers = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
DenyUsers = lib.mkOption {
|
||||
type = with lib.types; nullOr (listOf str);
|
||||
default = null;
|
||||
description = ''
|
||||
If specified, login is denied for all listed users. Takes
|
||||
@@ -491,8 +488,8 @@ in
|
||||
See {manpage}`sshd_config(5)` for details.
|
||||
'';
|
||||
};
|
||||
AllowGroups = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
AllowGroups = lib.mkOption {
|
||||
type = with lib.types; nullOr (listOf str);
|
||||
default = null;
|
||||
description = ''
|
||||
If specified, login is allowed only for users part of the
|
||||
@@ -500,8 +497,8 @@ in
|
||||
See {manpage}`sshd_config(5)` for details.
|
||||
'';
|
||||
};
|
||||
DenyGroups = mkOption {
|
||||
type = with types; nullOr (listOf str);
|
||||
DenyGroups = lib.mkOption {
|
||||
type = with lib.types; nullOr (listOf str);
|
||||
default = null;
|
||||
description = ''
|
||||
If specified, login is denied for all users part of the listed
|
||||
@@ -512,21 +509,21 @@ in
|
||||
};
|
||||
# Disabled by default, since pam_motd handles this.
|
||||
PrintMotd =
|
||||
mkEnableOption "printing /etc/motd when a user logs in interactively"
|
||||
// { type = types.nullOr types.bool; };
|
||||
lib.mkEnableOption "printing /etc/motd when a user logs in interactively"
|
||||
// { type = lib.types.nullOr lib.types.bool; };
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.lines;
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.lines;
|
||||
default = "";
|
||||
description = "Verbatim contents of {file}`sshd_config`.";
|
||||
};
|
||||
|
||||
moduliFile = mkOption {
|
||||
moduliFile = lib.mkOption {
|
||||
example = "/etc/my-local-ssh-moduli;";
|
||||
type = types.path;
|
||||
type = lib.types.path;
|
||||
description = ''
|
||||
Path to `moduli` file to install in
|
||||
`/etc/ssh/moduli`. If this option is unset, then
|
||||
@@ -536,8 +533,8 @@ in
|
||||
|
||||
};
|
||||
|
||||
users.users = mkOption {
|
||||
type = with types; attrsOf (submodule userOptions);
|
||||
users.users = lib.mkOption {
|
||||
type = with lib.types; attrsOf (submodule userOptions);
|
||||
};
|
||||
|
||||
};
|
||||
@@ -545,7 +542,7 @@ in
|
||||
|
||||
###### implementation
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
users.users.sshd =
|
||||
{
|
||||
@@ -555,8 +552,8 @@ in
|
||||
};
|
||||
users.groups.sshd = {};
|
||||
|
||||
services.openssh.moduliFile = mkDefault "${cfg.package}/etc/ssh/moduli";
|
||||
services.openssh.sftpServerExecutable = mkDefault "${cfg.package}/libexec/sftp-server";
|
||||
services.openssh.moduliFile = lib.mkDefault "${cfg.package}/etc/ssh/moduli";
|
||||
services.openssh.sftpServerExecutable = lib.mkDefault "${cfg.package}/libexec/sftp-server";
|
||||
|
||||
environment.etc = authKeysFiles // authPrincipalsFiles //
|
||||
{ "ssh/moduli".source = cfg.moduliFile;
|
||||
@@ -567,13 +564,13 @@ in
|
||||
let
|
||||
service =
|
||||
{ description = "SSH Daemon";
|
||||
wantedBy = optional (!cfg.startWhenNeeded) "multi-user.target";
|
||||
wantedBy = lib.optional (!cfg.startWhenNeeded) "multi-user.target";
|
||||
after = [ "network.target" ];
|
||||
stopIfChanged = false;
|
||||
path = [ cfg.package pkgs.gawk ];
|
||||
environment.LD_LIBRARY_PATH = nssModulesPath;
|
||||
|
||||
restartTriggers = optionals (!cfg.startWhenNeeded) [
|
||||
restartTriggers = lib.optionals (!cfg.startWhenNeeded) [
|
||||
config.environment.etc."ssh/sshd_config".source
|
||||
];
|
||||
|
||||
@@ -583,7 +580,7 @@ in
|
||||
# socket activation, it goes to the remote side (#19589).
|
||||
exec >&2
|
||||
|
||||
${flip concatMapStrings cfg.hostKeys (k: ''
|
||||
${lib.flip lib.concatMapStrings cfg.hostKeys (k: ''
|
||||
if ! [ -s "${k.path}" ]; then
|
||||
if ! [ -h "${k.path}" ]; then
|
||||
rm -f "${k.path}"
|
||||
@@ -591,10 +588,10 @@ in
|
||||
mkdir -m 0755 -p "$(dirname '${k.path}')"
|
||||
ssh-keygen \
|
||||
-t "${k.type}" \
|
||||
${optionalString (k ? bits) "-b ${toString k.bits}"} \
|
||||
${optionalString (k ? rounds) "-a ${toString k.rounds}"} \
|
||||
${optionalString (k ? comment) "-C '${k.comment}'"} \
|
||||
${optionalString (k ? openSSHFormat && k.openSSHFormat) "-o"} \
|
||||
${lib.optionalString (k ? bits) "-b ${toString k.bits}"} \
|
||||
${lib.optionalString (k ? rounds) "-a ${toString k.rounds}"} \
|
||||
${lib.optionalString (k ? comment) "-C '${k.comment}'"} \
|
||||
${lib.optionalString (k ? openSSHFormat && k.openSSHFormat) "-o"} \
|
||||
-f "${k.path}" \
|
||||
-N ""
|
||||
fi
|
||||
@@ -603,8 +600,8 @@ in
|
||||
|
||||
serviceConfig =
|
||||
{ ExecStart =
|
||||
(optionalString cfg.startWhenNeeded "-") +
|
||||
"${cfg.package}/bin/sshd " + (optionalString cfg.startWhenNeeded "-i ") +
|
||||
(lib.optionalString cfg.startWhenNeeded "-") +
|
||||
"${cfg.package}/bin/sshd " + (lib.optionalString cfg.startWhenNeeded "-i ") +
|
||||
"-D " + # don't detach into a daemon process
|
||||
"-f /etc/ssh/sshd_config";
|
||||
KillMode = "process";
|
||||
@@ -625,7 +622,7 @@ in
|
||||
{ description = "SSH Socket";
|
||||
wantedBy = [ "sockets.target" ];
|
||||
socketConfig.ListenStream = if cfg.listenAddresses != [] then
|
||||
concatMap
|
||||
lib.concatMap
|
||||
({ addr, port }:
|
||||
if port != null then [ "${addr}:${toString port}" ]
|
||||
else map (p: "${addr}:${toString p}") cfg.ports)
|
||||
@@ -645,7 +642,7 @@ in
|
||||
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = optionals cfg.openFirewall cfg.ports;
|
||||
networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall cfg.ports;
|
||||
|
||||
security.pam.services.sshd = lib.mkIf cfg.settings.UsePAM
|
||||
{ startSession = true;
|
||||
@@ -662,34 +659,34 @@ in
|
||||
services.openssh.authorizedKeysFiles =
|
||||
lib.optional cfg.authorizedKeysInHomedir "%h/.ssh/authorized_keys" ++ [ "/etc/ssh/authorized_keys.d/%u" ];
|
||||
|
||||
services.openssh.settings.AuthorizedPrincipalsFile = mkIf (authPrincipalsFiles != {}) "/etc/ssh/authorized_principals.d/%u";
|
||||
services.openssh.settings.AuthorizedPrincipalsFile = lib.mkIf (authPrincipalsFiles != {}) "/etc/ssh/authorized_principals.d/%u";
|
||||
|
||||
services.openssh.extraConfig = mkOrder 0
|
||||
services.openssh.extraConfig = lib.mkOrder 0
|
||||
''
|
||||
Banner ${if cfg.banner == null then "none" else pkgs.writeText "ssh_banner" cfg.banner}
|
||||
|
||||
AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"}
|
||||
${concatMapStrings (port: ''
|
||||
${lib.concatMapStrings (port: ''
|
||||
Port ${toString port}
|
||||
'') cfg.ports}
|
||||
|
||||
${concatMapStrings ({ port, addr, ... }: ''
|
||||
ListenAddress ${addr}${optionalString (port != null) (":" + toString port)}
|
||||
${lib.concatMapStrings ({ port, addr, ... }: ''
|
||||
ListenAddress ${addr}${lib.optionalString (port != null) (":" + toString port)}
|
||||
'') cfg.listenAddresses}
|
||||
|
||||
${optionalString cfgc.setXAuthLocation ''
|
||||
${lib.optionalString cfgc.setXAuthLocation ''
|
||||
XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
|
||||
''}
|
||||
${optionalString cfg.allowSFTP ''
|
||||
Subsystem sftp ${cfg.sftpServerExecutable} ${concatStringsSep " " cfg.sftpFlags}
|
||||
${lib.optionalString cfg.allowSFTP ''
|
||||
Subsystem sftp ${cfg.sftpServerExecutable} ${lib.concatStringsSep " " cfg.sftpFlags}
|
||||
''}
|
||||
AuthorizedKeysFile ${toString cfg.authorizedKeysFiles}
|
||||
${optionalString (cfg.authorizedKeysCommand != "none") ''
|
||||
${lib.optionalString (cfg.authorizedKeysCommand != "none") ''
|
||||
AuthorizedKeysCommand ${cfg.authorizedKeysCommand}
|
||||
AuthorizedKeysCommandUser ${cfg.authorizedKeysCommandUser}
|
||||
''}
|
||||
|
||||
${flip concatMapStrings cfg.hostKeys (k: ''
|
||||
${lib.flip lib.concatMapStrings cfg.hostKeys (k: ''
|
||||
HostKey ${k.path}
|
||||
'')}
|
||||
'';
|
||||
@@ -699,13 +696,13 @@ in
|
||||
{
|
||||
nativeBuildInputs = [ validationPackage ];
|
||||
} ''
|
||||
${concatMapStringsSep "\n"
|
||||
${lib.concatMapStringsSep "\n"
|
||||
(lport: "sshd -G -T -C lport=${toString lport} -f ${sshconf} > /dev/null")
|
||||
cfg.ports}
|
||||
${concatMapStringsSep "\n"
|
||||
${lib.concatMapStringsSep "\n"
|
||||
(la:
|
||||
concatMapStringsSep "\n"
|
||||
(port: "sshd -G -T -C ${escapeShellArg "laddr=${la.addr},lport=${toString port}"} -f ${sshconf} > /dev/null")
|
||||
lib.concatMapStringsSep "\n"
|
||||
(port: "sshd -G -T -C ${lib.escapeShellArg "laddr=${la.addr},lport=${toString port}"} -f ${sshconf} > /dev/null")
|
||||
(if la.port != null then [ la.port ] else cfg.ports)
|
||||
)
|
||||
cfg.listenAddresses}
|
||||
@@ -726,7 +723,7 @@ in
|
||||
# Grab the groups, we don't care about the group identifiers
|
||||
lib.attrValues (
|
||||
# Group the settings that are the same in lower case
|
||||
lib.groupBy lib.strings.toLower (attrNames cfg.settings)
|
||||
lib.groupBy lib.strings.toLower (lib.attrNames cfg.settings)
|
||||
)
|
||||
);
|
||||
formattedDuplicates = lib.concatMapStringsSep ", " (dupl: "(${lib.concatStringsSep ", " dupl})") duplicates;
|
||||
@@ -735,7 +732,7 @@ in
|
||||
assertion = lib.length duplicates == 0;
|
||||
message = ''Duplicate sshd config key; does your capitalization match the option's? Duplicate keys: ${formattedDuplicates}'';
|
||||
})]
|
||||
++ forEach cfg.listenAddresses ({ addr, ... }: {
|
||||
++ lib.forEach cfg.listenAddresses ({ addr, ... }: {
|
||||
assertion = addr != null;
|
||||
message = "addr must be specified in each listenAddresses entry";
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user