1
0
Fork 0
mirror of https://github.com/NixOS/nixpkgs.git synced 2025-07-09 03:55:44 +03:00

Merge staging-next into staging

This commit is contained in:
Frederik Rietdijk 2020-03-28 21:15:15 +01:00
commit a36be028f5
639 changed files with 13721 additions and 10162 deletions

View file

@ -218,9 +218,7 @@ in
++ optionals config.services.xserver.enable [ desktopItem pkgs.nixos-icons ]);
services.mingetty.helpLine = mkIf cfg.doc.enable (
"\nRun `nixos-help` "
+ optionalString config.services.nixosManual.showManual "or press <Alt-F${toString config.services.nixosManual.ttyNumber}> "
+ "for the NixOS manual."
"\nRun 'nixos-help' for the NixOS manual."
);
})

View file

@ -469,7 +469,6 @@
./services/misc/nix-daemon.nix
./services/misc/nix-gc.nix
./services/misc/nix-optimise.nix
./services/misc/nixos-manual.nix
./services/misc/nix-ssh-serve.nix
./services/misc/novacomd.nix
./services/misc/nzbget.nix
@ -485,7 +484,6 @@
./services/misc/redmine.nix
./services/misc/rippled.nix
./services/misc/ripple-data-api.nix
./services/misc/rogue.nix
./services/misc/serviio.nix
./services/misc/safeeyes.nix
./services/misc/sickbeard.nix
@ -692,6 +690,7 @@
./services/networking/prosody.nix
./services/networking/quagga.nix
./services/networking/quassel.nix
./services/networking/quorum.nix
./services/networking/quicktun.nix
./services/networking/racoon.nix
./services/networking/radicale.nix
@ -823,6 +822,7 @@
./services/web-apps/documize.nix
./services/web-apps/dokuwiki.nix
./services/web-apps/frab.nix
./services/web-apps/gerrit.nix
./services/web-apps/gotify-server.nix
./services/web-apps/grocy.nix
./services/web-apps/icingaweb2/icingaweb2.nix

View file

@ -26,10 +26,6 @@ with lib;
# Show the manual.
documentation.nixos.enable = mkForce true;
services.nixosManual.showManual = true;
# Let the user play Rogue on TTY 8 during the installation.
#services.rogue.enable = true;
# Use less privileged nixos user
users.users.nixos = {

View file

@ -26,5 +26,7 @@ with lib;
services.dbus.packages = [ pkgs.gnome3.rygel ];
systemd.packages = [ pkgs.gnome3.rygel ];
environment.etc."rygel.conf".source = "${pkgs.gnome3.rygel}/etc/rygel.conf";
};
}

View file

@ -1,73 +0,0 @@
# This module optionally starts a browser that shows the NixOS manual
# on one of the virtual consoles which is useful for the installation
# CD.
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.nixosManual;
cfgd = config.documentation;
in
{
options = {
# TODO(@oxij): rename this to `.enable` eventually.
services.nixosManual.showManual = mkOption {
type = types.bool;
default = false;
description = ''
Whether to show the NixOS manual on one of the virtual
consoles.
'';
};
services.nixosManual.ttyNumber = mkOption {
type = types.int;
default = 8;
description = ''
Virtual console on which to show the manual.
'';
};
services.nixosManual.browser = mkOption {
type = types.path;
default = "${pkgs.w3m-nographics}/bin/w3m";
description = ''
Browser used to show the manual.
'';
};
};
config = mkMerge [
(mkIf cfg.showManual {
assertions = singleton {
assertion = cfgd.enable && cfgd.nixos.enable;
message = "Can't enable `services.nixosManual.showManual` without `documentation.nixos.enable`";
};
})
(mkIf (cfg.showManual && cfgd.enable && cfgd.nixos.enable) {
console.extraTTYs = [ "tty${toString cfg.ttyNumber}" ];
systemd.services.nixos-manual = {
description = "NixOS Manual";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${cfg.browser} ${config.system.build.manual.manualHTMLIndex}";
StandardInput = "tty";
StandardOutput = "tty";
TTYPath = "/dev/tty${toString cfg.ttyNumber}";
TTYReset = true;
TTYVTDisallocate = true;
Restart = "always";
};
};
})
];
}

View file

@ -1,62 +0,0 @@
# Execute the game `rogue' on tty 9. Mostly used by the NixOS
# installation CD.
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.rogue;
in
{
###### interface
options = {
services.rogue.enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether to enable the Rogue game on one of the virtual
consoles.
'';
};
services.rogue.tty = mkOption {
type = types.str;
default = "tty9";
description = ''
Virtual console on which to run Rogue.
'';
};
};
###### implementation
config = mkIf cfg.enable {
console.extraTTYs = [ cfg.tty ];
systemd.services.rogue =
{ description = "Rogue dungeon crawling game";
wantedBy = [ "multi-user.target" ];
serviceConfig =
{ ExecStart = "${pkgs.rogue}/bin/rogue";
StandardInput = "tty";
StandardOutput = "tty";
TTYPath = "/dev/${cfg.tty}";
TTYReset = true;
TTYVTDisallocate = true;
WorkingDirectory = "/tmp";
Restart = "always";
};
};
};
}

View file

@ -155,7 +155,7 @@ in {
systemd.services.alertmanager = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
after = [ "network-online.target" ];
preStart = ''
${lib.getBin pkgs.envsubst}/bin/envsubst -o "/tmp/alert-manager-substituted.yaml" \
-i "${alertmanagerYml}"

View file

@ -0,0 +1,229 @@
{ config, pkgs, lib, ... }:
let
inherit (lib) mkEnableOption mkIf mkOption literalExample types optionalString;
cfg = config.services.quorum;
dataDir = "/var/lib/quorum";
genesisFile = pkgs.writeText "genesis.json" (builtins.toJSON cfg.genesis);
staticNodesFile = pkgs.writeText "static-nodes.json" (builtins.toJSON cfg.staticNodes);
in {
options = {
services.quorum = {
enable = mkEnableOption "Quorum blockchain daemon";
user = mkOption {
type = types.str;
default = "quorum";
description = "The user as which to run quorum.";
};
group = mkOption {
type = types.str;
default = cfg.user;
description = "The group as which to run quorum.";
};
port = mkOption {
type = types.port;
default = 21000;
description = "Override the default port on which to listen for connections.";
};
nodekeyFile = mkOption {
type = types.path;
default = "${dataDir}/nodekey";
description = "Path to the nodekey.";
};
staticNodes = mkOption {
type = types.listOf types.str;
default = [];
example = [ "enode://dd333ec28f0a8910c92eb4d336461eea1c20803eed9cf2c056557f986e720f8e693605bba2f4e8f289b1162e5ac7c80c914c7178130711e393ca76abc1d92f57@0.0.0.0:30303?discport=0" ];
description = "List of validator nodes.";
};
privateconfig = mkOption {
type = types.str;
default = "ignore";
description = "Configuration of privacy transaction manager.";
};
syncmode = mkOption {
type = types.enum [ "fast" "full" "light" ];
default = "full";
description = "Blockchain sync mode.";
};
blockperiod = mkOption {
type = types.int;
default = 5;
description = "Default minimum difference between two consecutive block's timestamps in seconds.";
};
permissioned = mkOption {
type = types.bool;
default = true;
description = "Allow only a defined list of nodes to connect.";
};
rpc = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable RPC interface.";
};
address = mkOption {
type = types.str;
default = "0.0.0.0";
description = "Listening address for RPC connections.";
};
port = mkOption {
type = types.port;
default = 22004;
description = "Override the default port on which to listen for RPC connections.";
};
api = mkOption {
type = types.str;
default = "admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul";
description = "API's offered over the HTTP-RPC interface.";
};
};
ws = {
enable = mkOption {
type = types.bool;
default = true;
description = "Enable WS-RPC interface.";
};
address = mkOption {
type = types.str;
default = "0.0.0.0";
description = "Listening address for WS-RPC connections.";
};
port = mkOption {
type = types.port;
default = 8546;
description = "Override the default port on which to listen for WS-RPC connections.";
};
api = mkOption {
type = types.str;
default = "admin,db,eth,debug,miner,net,shh,txpool,personal,web3,quorum,istanbul";
description = "API's offered over the WS-RPC interface.";
};
origins = mkOption {
type = types.str;
default = "*";
description = "Origins from which to accept websockets requests";
};
};
genesis = mkOption {
type = types.nullOr types.attrs;
default = null;
example = literalExample '' {
alloc = {
a47385db68718bdcbddc2d2bb7c54018066ec111 = {
balance = "1000000000000000000000000000";
};
};
coinbase = "0x0000000000000000000000000000000000000000";
config = {
byzantiumBlock = 4;
chainId = 494702925;
eip150Block = 2;
eip155Block = 3;
eip158Block = 3;
homesteadBlock = 1;
isQuorum = true;
istanbul = {
epoch = 30000;
policy = 0;
};
};
difficulty = "0x1";
extraData = "0x0000000000000000000000000000000000000000000000000000000000000000f85ad59438f0508111273d8e482f49410ca4078afc86a961b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0";
gasLimit = "0x2FEFD800";
mixHash = "0x63746963616c2062797a616e74696e65201111756c7420746f6c6572616e6365";
nonce = "0x0";
parentHash = "0x0000000000000000000000000000000000000000000000000000000000000000";
timestamp = "0x00";
}'';
description = "Blockchain genesis settings.";
};
};
};
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.quorum ];
systemd.tmpfiles.rules = [
"d '${dataDir}' 0770 '${cfg.user}' '${cfg.group}' - -"
];
systemd.services.quorum = {
description = "Quorum daemon";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
PRIVATE_CONFIG = "${cfg.privateconfig}";
};
preStart = ''
if [ ! -d ${dataDir}/geth ]; then
if [ ! -d ${dataDir}/keystore ]; then
echo ERROR: You need to create a wallet before initializing your genesis file, run:
echo # su -s /bin/sh - quorum
echo $ geth --datadir ${dataDir} account new
echo and configure your genesis file accordingly.
exit 1;
fi
ln -s ${staticNodesFile} ${dataDir}/static-nodes.json
${pkgs.quorum}/bin/geth --datadir ${dataDir} init ${genesisFile}
fi
'';
serviceConfig = {
User = cfg.user;
Group = cfg.group;
ExecStart = ''${pkgs.quorum}/bin/geth \
--nodiscover \
--verbosity 5 \
--nodekey ${cfg.nodekeyFile} \
--istanbul.blockperiod ${toString cfg.blockperiod} \
--syncmode ${cfg.syncmode} \
${optionalString (cfg.permissioned)
"--permissioned"} \
--mine --minerthreads 1 \
${optionalString (cfg.rpc.enable)
"--rpc --rpcaddr ${cfg.rpc.address} --rpcport ${toString cfg.rpc.port} --rpcapi ${cfg.rpc.api}"} \
${optionalString (cfg.ws.enable)
"--ws --wsaddr ${cfg.ws.address} --wsport ${toString cfg.ws.port} --wsapi ${cfg.ws.api} --wsorigins ${cfg.ws.origins}"} \
--emitcheckpoints \
--datadir ${dataDir} \
--port ${toString cfg.port}'';
Restart = "on-failure";
# Hardening measures
PrivateTmp = "true";
ProtectSystem = "full";
NoNewPrivileges = "true";
PrivateDevices = "true";
MemoryDenyWriteExecute = "true";
};
};
users.users.${cfg.user} = {
name = cfg.user;
group = cfg.group;
description = "Quorum daemon user";
home = dataDir;
isSystemUser = true;
};
users.groups.${cfg.group} = {};
};
}

View file

@ -67,8 +67,6 @@ in
systemd.services.atd = {
description = "Job Execution Daemon (atd)";
after = [ "systemd-udev-settle.service" ];
wants = [ "systemd-udev-settle.service" ];
wantedBy = [ "multi-user.target" ];
path = [ at ];

View file

@ -0,0 +1,218 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.gerrit;
# NixOS option type for git-like configs
gitIniType = with types;
let
primitiveType = either str (either bool int);
multipleType = either primitiveType (listOf primitiveType);
sectionType = lazyAttrsOf multipleType;
supersectionType = lazyAttrsOf (either multipleType sectionType);
in lazyAttrsOf supersectionType;
gerritConfig = pkgs.writeText "gerrit.conf" (
lib.generators.toGitINI cfg.settings
);
# Wrap the gerrit java with all the java options so it can be called
# like a normal CLI app
gerrit-cli = pkgs.writeShellScriptBin "gerrit" ''
set -euo pipefail
jvmOpts=(
${lib.escapeShellArgs cfg.jvmOpts}
-Xmx${cfg.jvmHeapLimit}
)
exec ${cfg.jvmPackage}/bin/java \
"''${jvmOpts[@]}" \
-jar ${cfg.package}/webapps/${cfg.package.name}.war \
"$@"
'';
gerrit-plugins = pkgs.runCommand
"gerrit-plugins"
{
buildInputs = [ gerrit-cli ];
}
''
shopt -s nullglob
mkdir $out
for name in ${toString cfg.builtinPlugins}; do
echo "Installing builtin plugin $name.jar"
gerrit cat plugins/$name.jar > $out/$name.jar
done
for file in ${toString cfg.plugins}; do
name=$(echo "$file" | cut -d - -f 2-)
echo "Installing plugin $name"
ln -sf "$file" $out/$name
done
'';
in
{
options = {
services.gerrit = {
enable = mkEnableOption "Gerrit service";
package = mkOption {
type = types.package;
default = pkgs.gerrit;
description = "Gerrit package to use";
};
jvmPackage = mkOption {
type = types.package;
default = pkgs.jre_headless;
defaultText = "pkgs.jre_headless";
description = "Java Runtime Environment package to use";
};
jvmOpts = mkOption {
type = types.listOf types.str;
default = [
"-Dflogger.backend_factory=com.google.common.flogger.backend.log4j.Log4jBackendFactory#getInstance"
"-Dflogger.logging_context=com.google.gerrit.server.logging.LoggingContext#getInstance"
];
description = "A list of JVM options to start gerrit with.";
};
jvmHeapLimit = mkOption {
type = types.str;
default = "1024m";
description = ''
How much memory to allocate to the JVM heap
'';
};
listenAddress = mkOption {
type = types.str;
default = "[::]:8080";
description = ''
<literal>hostname:port</literal> to listen for HTTP traffic.
This is bound using the systemd socket activation.
'';
};
settings = mkOption {
type = gitIniType;
default = {};
description = ''
Gerrit configuration. This will be generated to the
<literal>etc/gerrit.config</literal> file.
'';
};
plugins = mkOption {
type = types.listOf types.package;
default = [];
description = ''
List of plugins to add to Gerrit. Each derivation is a jar file
itself where the name of the derivation is the name of plugin.
'';
};
builtinPlugins = mkOption {
type = types.listOf (types.enum cfg.package.passthru.plugins);
default = [];
description = ''
List of builtins plugins to install. Those are shipped in the
<literal>gerrit.war</literal> file.
'';
};
serverId = mkOption {
type = types.str;
description = ''
Set a UUID that uniquely identifies the server.
This can be generated with
<literal>nix-shell -p utillinux --run uuidgen</literal>.
'';
};
};
};
config = mkIf cfg.enable {
services.gerrit.settings = {
cache.directory = "/var/cache/gerrit";
container.heapLimit = cfg.jvmHeapLimit;
gerrit.basePath = lib.mkDefault "git";
gerrit.serverId = cfg.serverId;
httpd.inheritChannel = "true";
httpd.listenUrl = lib.mkDefault "http://${cfg.listenAddress}";
index.type = lib.mkDefault "lucene";
};
# Add the gerrit CLI to the system to run `gerrit init` and friends.
environment.systemPackages = [ gerrit-cli ];
systemd.sockets.gerrit = {
unitConfig.Description = "Gerrit HTTP socket";
wantedBy = [ "sockets.target" ];
listenStreams = [ cfg.listenAddress ];
};
systemd.services.gerrit = {
description = "Gerrit";
wantedBy = [ "multi-user.target" ];
requires = [ "gerrit.socket" ];
after = [ "gerrit.socket" "network.target" ];
path = [
gerrit-cli
pkgs.bash
pkgs.coreutils
pkgs.git
pkgs.openssh
];
environment = {
GERRIT_HOME = "%S/gerrit";
GERRIT_TMP = "%T";
HOME = "%S/gerrit";
XDG_CONFIG_HOME = "%S/gerrit/.config";
};
preStart = ''
set -euo pipefail
# bootstrap if nothing exists
if [[ ! -d git ]]; then
gerrit init --batch --no-auto-start
fi
# install gerrit.war for the plugin manager
rm -rf bin
mkdir bin
ln -sfv ${cfg.package}/webapps/${cfg.package.name}.war bin/gerrit.war
# copy the config, keep it mutable because Gerrit
ln -sfv ${gerritConfig} etc/gerrit.config
# install the plugins
rm -rf plugins
ln -sv ${gerrit-plugins} plugins
''
;
serviceConfig = {
CacheDirectory = "gerrit";
DynamicUser = true;
ExecStart = "${gerrit-cli}/bin/gerrit daemon --console-log";
LimitNOFILE = 4096;
StandardInput = "socket";
StandardOutput = "journal";
StateDirectory = "gerrit";
WorkingDirectory = "%S/gerrit";
};
};
};
meta.maintainers = with lib.maintainers; [ edef zimbatm ];
}

View file

@ -30,7 +30,7 @@ let
occ = pkgs.writeScriptBin "nextcloud-occ" ''
#! ${pkgs.stdenv.shell}
cd ${pkgs.nextcloud}
cd ${cfg.package}
sudo=exec
if [[ "$USER" != nextcloud ]]; then
sudo='exec /run/wrappers/bin/sudo -u nextcloud --preserve-env=NEXTCLOUD_CONFIG_DIR'
@ -42,6 +42,8 @@ let
occ $*
'';
inherit (config.system) stateVersion;
in {
options.services.nextcloud = {
enable = mkEnableOption "nextcloud";
@ -64,6 +66,11 @@ in {
default = false;
description = "Use https for generated links.";
};
package = mkOption {
type = types.package;
description = "Which package to use for the Nextcloud instance.";
relatedPackages = [ "nextcloud17" "nextcloud18" ];
};
maxUploadSize = mkOption {
default = "512M";
@ -309,10 +316,31 @@ in {
}
];
warnings = optional (cfg.poolConfig != null) ''
Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release.
Please migrate your configuration to config.services.nextcloud.poolSettings.
'';
warnings = []
++ (optional (cfg.poolConfig != null) ''
Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release.
Please migrate your configuration to config.services.nextcloud.poolSettings.
'')
++ (optional (versionOlder cfg.package.version "18") ''
You're currently deploying an older version of Nextcloud. This may be needed
since Nextcloud doesn't allow major version upgrades across multiple versions (i.e. an
upgrade from 16 is possible to 17, but not to 18).
Please deploy this to your server and wait until the migration is finished. After
that you can deploy to the latest Nextcloud version available.
'');
services.nextcloud.package = with pkgs;
mkDefault (
if pkgs ? nextcloud
then throw ''
The `pkgs.nextcloud`-attribute has been removed. If it's supposed to be the default
nextcloud defined in an overlay, please set `services.nextcloud.package` to
`pkgs.nextcloud`.
''
else if versionOlder stateVersion "20.03" then nextcloud17
else nextcloud18
);
}
{ systemd.timers.nextcloud-cron = {
@ -407,7 +435,7 @@ in {
path = [ occ ];
script = ''
chmod og+x ${cfg.home}
ln -sf ${pkgs.nextcloud}/apps ${cfg.home}/
ln -sf ${cfg.package}/apps ${cfg.home}/
mkdir -p ${cfg.home}/config ${cfg.home}/data ${cfg.home}/store-apps
ln -sf ${overrideConfig} ${cfg.home}/config/override.config.php
@ -429,7 +457,7 @@ in {
environment.NEXTCLOUD_CONFIG_DIR = "${cfg.home}/config";
serviceConfig.Type = "oneshot";
serviceConfig.User = "nextcloud";
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${pkgs.nextcloud}/cron.php";
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
};
nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
serviceConfig.Type = "oneshot";
@ -471,7 +499,7 @@ in {
enable = true;
virtualHosts = {
${cfg.hostName} = {
root = pkgs.nextcloud;
root = cfg.package;
locations = {
"= /robots.txt" = {
priority = 100;

View file

@ -113,5 +113,53 @@
maintenance:install</literal>! This command tries to install the application
and can cause unwanted side-effects!</para>
</warning>
<para>
Nextcloud doesn't allow to move more than one major-version forward. If you're e.g. on
<literal>v16</literal>, you cannot upgrade to <literal>v18</literal>, you need to upgrade to
<literal>v17</literal> first. This is ensured automatically as long as the
<link linkend="opt-system.stateVersion">stateVersion</link> is declared properly. In that case
the oldest version available (one major behind the one from the previous NixOS
release) will be selected by default and the module will generate a warning that reminds
the user to upgrade to latest Nextcloud <emphasis>after</emphasis> that deploy.
</para>
</section>
<section xml:id="module-services-nextcloud-maintainer-info">
<title>Maintainer information</title>
<para>
As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud
since it cannot move more than one major version forward on a single upgrade. This chapter
adds some notes how Nextcloud updates should be rolled out in the future.
</para>
<para>
While minor and patch-level updates are no problem and can be done directly in the
package-expression (and should be backported to supported stable branches after that),
major-releases should be added in a new attribute (e.g. Nextcloud <literal>v19.0.0</literal>
should be available in <literal>nixpkgs</literal> as <literal>pkgs.nextcloud19</literal>).
To provide simple upgrade paths it's generally useful to backport those as well to stable
branches. As long as the package-default isn't altered, this won't break existing setups.
After that, the versioning-warning in the <literal>nextcloud</literal>-module should be
updated to make sure that the
<link linkend="opt-services.nextcloud.package">package</link>-option selects the latest version
on fresh setups.
</para>
<para>
If major-releases will be abandoned by upstream, we should check first if those are needed
in NixOS for a safe upgrade-path before removing those. In that case we shold keep those
packages, but mark them as insecure in an expression like this (in
<literal>&lt;nixpkgs/pkgs/servers/nextcloud/default.nix&gt;</literal>):
<programlisting>/* ... */
{
nextcloud17 = generic {
version = "17.0.x";
sha256 = "0000000000000000000000000000000000000000000000000000";
insecure = true;
};
}</programlisting>
</para>
</section>
</chapter>

View file

@ -46,6 +46,15 @@ let
}
''));
commonHttpConfig = ''
# The mime type definitions included with nginx are very incomplete, so
# we use a list of mime types from the mailcap package, which is also
# used by most other Linux distributions by default.
include ${pkgs.mailcap}/etc/nginx/mime.types;
include ${cfg.package}/conf/fastcgi.conf;
include ${cfg.package}/conf/uwsgi_params;
'';
configFile = pkgs.writers.writeNginxConfig "nginx.conf" ''
pid /run/nginx/nginx.pid;
error_log ${cfg.logError};
@ -61,12 +70,7 @@ let
${optionalString (cfg.httpConfig == "" && cfg.config == "") ''
http {
# The mime type definitions included with nginx are very incomplete, so
# we use a list of mime types from the mailcap package, which is also
# used by most other Linux distributions by default.
include ${pkgs.mailcap}/etc/nginx/mime.types;
include ${cfg.package}/conf/fastcgi.conf;
include ${cfg.package}/conf/uwsgi_params;
${commonHttpConfig}
${optionalString (cfg.resolver.addresses != []) ''
resolver ${toString cfg.resolver.addresses} ${optionalString (cfg.resolver.valid != "") "valid=${cfg.resolver.valid}"} ${optionalString (!cfg.resolver.ipv6) "ipv6=off"};
@ -79,7 +83,7 @@ let
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
types_hash_max_size 4096;
''}
ssl_protocols ${cfg.sslProtocols};
@ -172,9 +176,7 @@ let
${optionalString (cfg.httpConfig != "") ''
http {
include ${cfg.package}/conf/mime.types;
include ${cfg.package}/conf/fastcgi.conf;
include ${cfg.package}/conf/uwsgi_params;
${common.httpConfig}
${cfg.httpConfig}
}''}

View file

@ -651,8 +651,7 @@ in
systemd.services.display-manager =
{ description = "X11 Server";
after = [ "systemd-udev-settle.service" "acpid.service" "systemd-logind.service" ];
wants = [ "systemd-udev-settle.service" ];
after = [ "acpid.service" "systemd-logind.service" ];
restartIfChanged = false;

View file

@ -10,19 +10,21 @@ in
{
options = {
boot.initrd.network.ssh.enable = mkOption {
options.boot.initrd.network.ssh = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Start SSH service during initrd boot. It can be used to debug failing
boot on a remote server, enter pasphrase for an encrypted partition etc.
Service is killed when stage-1 boot is finished.
The sshd configuration is largely inherited from
<option>services.openssh</option>.
'';
};
boot.initrd.network.ssh.port = mkOption {
port = mkOption {
type = types.int;
default = 22;
description = ''
@ -30,7 +32,7 @@ in
'';
};
boot.initrd.network.ssh.shell = mkOption {
shell = mkOption {
type = types.str;
default = "/bin/ash";
description = ''
@ -38,95 +40,163 @@ in
'';
};
boot.initrd.network.ssh.hostRSAKey = mkOption {
type = types.nullOr types.path;
default = null;
hostKeys = mkOption {
type = types.listOf (types.either types.str types.path);
default = [];
example = [
"/etc/secrets/initrd/ssh_host_rsa_key"
"/etc/secrets/initrd/ssh_host_ed25519_key"
];
description = ''
RSA SSH private key file in the Dropbear format.
Specify SSH host keys to import into the initrd.
WARNING: Unless your bootloader supports initrd secrets, this key is
contained insecurely in the global Nix store. Do NOT use your regular
SSH host private keys for this purpose or you'll expose them to
regular users!
To generate keys, use
<citerefentry><refentrytitle>ssh-keygen</refentrytitle><manvolnum>1</manvolnum></citerefentry>:
<screen>
<prompt># </prompt>ssh-keygen -t rsa -N "" -f /etc/secrets/initrd/ssh_host_rsa_key
<prompt># </prompt>ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed_25519_key
</screen>
<warning>
<para>
Unless your bootloader supports initrd secrets, these keys
are stored insecurely in the global Nix store. Do NOT use
your regular SSH host private keys for this purpose or
you'll expose them to regular users!
</para>
<para>
Additionally, even if your initrd supports secrets, if
you're using initrd SSH to unlock an encrypted disk then
using your regular host keys exposes the private keys on
your unencrypted boot partition.
</para>
</warning>
'';
};
boot.initrd.network.ssh.hostDSSKey = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
DSS SSH private key file in the Dropbear format.
WARNING: Unless your bootloader supports initrd secrets, this key is
contained insecurely in the global Nix store. Do NOT use your regular
SSH host private keys for this purpose or you'll expose them to
regular users!
'';
};
boot.initrd.network.ssh.hostECDSAKey = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
ECDSA SSH private key file in the Dropbear format.
WARNING: Unless your bootloader supports initrd secrets, this key is
contained insecurely in the global Nix store. Do NOT use your regular
SSH host private keys for this purpose or you'll expose them to
regular users!
'';
};
boot.initrd.network.ssh.authorizedKeys = mkOption {
authorizedKeys = mkOption {
type = types.listOf types.str;
default = config.users.users.root.openssh.authorizedKeys.keys;
defaultText = "config.users.users.root.openssh.authorizedKeys.keys";
description = ''
Authorized keys for the root user on initrd.
Note that Dropbear doesn't support OpenSSH's Ed25519 key type.
'';
};
};
config = mkIf (config.boot.initrd.network.enable && cfg.enable) {
imports =
map (opt: mkRemovedOptionModule ([ "boot" "initrd" "network" "ssh" ] ++ [ opt ]) ''
The initrd SSH functionality now uses OpenSSH rather than Dropbear.
If you want to keep your existing initrd SSH host keys, convert them with
$ dropbearconvert dropbear openssh dropbear_host_$type_key ssh_host_$type_key
and then set options.boot.initrd.network.ssh.hostKeys.
'') [ "hostRSAKey" "hostDSSKey" "hostECDSAKey" ];
config = let
# Nix complains if you include a store hash in initrd path names, so
# as an awful hack we drop the first character of the hash.
initrdKeyPath = path: if isString path
then path
else let name = builtins.baseNameOf path; in
builtins.unsafeDiscardStringContext ("/etc/ssh/" +
substring 1 (stringLength name) name);
sshdCfg = config.services.openssh;
sshdConfig = ''
Port ${toString cfg.port}
PasswordAuthentication no
ChallengeResponseAuthentication no
${flip concatMapStrings cfg.hostKeys (path: ''
HostKey ${initrdKeyPath path}
'')}
KexAlgorithms ${concatStringsSep "," sshdCfg.kexAlgorithms}
Ciphers ${concatStringsSep "," sshdCfg.ciphers}
MACs ${concatStringsSep "," sshdCfg.macs}
LogLevel ${sshdCfg.logLevel}
${if sshdCfg.useDns then ''
UseDNS yes
'' else ''
UseDNS no
''}
'';
in mkIf (config.boot.initrd.network.enable && cfg.enable) {
assertions = [
{ assertion = cfg.authorizedKeys != [];
{
assertion = cfg.authorizedKeys != [];
message = "You should specify at least one authorized key for initrd SSH";
}
{
assertion = cfg.hostKeys != [];
message = ''
You must now pre-generate the host keys for initrd SSH.
See the boot.inird.network.ssh.hostKeys documentation
for instructions.
'';
}
];
boot.initrd.extraUtilsCommands = ''
copy_bin_and_libs ${pkgs.dropbear}/bin/dropbear
copy_bin_and_libs ${pkgs.openssh}/bin/sshd
cp -pv ${pkgs.glibc.out}/lib/libnss_files.so.* $out/lib
'';
boot.initrd.extraUtilsCommandsTest = ''
$out/bin/dropbear -V
# sshd requires a host key to check config, so we pass in the test's
echo -n ${escapeShellArg sshdConfig} |
$out/bin/sshd -t -f /dev/stdin \
-h ${../../../tests/initrd-network-ssh/ssh_host_ed25519_key}
'';
boot.initrd.network.postCommands = ''
echo '${cfg.shell}' > /etc/shells
echo 'root:x:0:0:root:/root:${cfg.shell}' > /etc/passwd
echo 'sshd:x:1:1:sshd:/var/empty:/bin/nologin' >> /etc/passwd
echo 'passwd: files' > /etc/nsswitch.conf
mkdir -p /var/log
mkdir -p /var/log /var/empty
touch /var/log/lastlog
mkdir -p /etc/dropbear
mkdir -p /etc/ssh
echo -n ${escapeShellArg sshdConfig} > /etc/ssh/sshd_config
echo "export PATH=$PATH" >> /etc/profile
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH" >> /etc/profile
mkdir -p /root/.ssh
${concatStrings (map (key: ''
echo ${escapeShellArg key} >> /root/.ssh/authorized_keys
'') cfg.authorizedKeys)}
dropbear -s -j -k -E -p ${toString cfg.port} ${optionalString (cfg.hostRSAKey == null && cfg.hostDSSKey == null && cfg.hostECDSAKey == null) "-R"}
${flip concatMapStrings cfg.hostKeys (path: ''
# keys from Nix store are world-readable, which sshd doesn't like
chmod 0600 "${initrdKeyPath path}"
'')}
/bin/sshd -e
'';
boot.initrd.secrets =
(optionalAttrs (cfg.hostRSAKey != null) { "/etc/dropbear/dropbear_rsa_host_key" = cfg.hostRSAKey; }) //
(optionalAttrs (cfg.hostDSSKey != null) { "/etc/dropbear/dropbear_dss_host_key" = cfg.hostDSSKey; }) //
(optionalAttrs (cfg.hostECDSAKey != null) { "/etc/dropbear/dropbear_ecdsa_host_key" = cfg.hostECDSAKey; });
boot.initrd.postMountCommands = ''
# Stop sshd cleanly before stage 2.
#
# If you want to keep it around to debug post-mount SSH issues,
# run `touch /.keep_sshd` (either from an SSH session or in
# another initrd hook like preDeviceCommands).
if ! [ -e /.keep_sshd ]; then
pkill -x sshd
fi
'';
boot.initrd.secrets = listToAttrs
(map (path: nameValuePair (initrdKeyPath path) path) cfg.hostKeys);
};
}

View file

@ -142,7 +142,10 @@ let
let source' = if source == null then dest else source; in
''
mkdir -p $(dirname "$out/secrets/${dest}")
cp -a ${source'} "$out/secrets/${dest}"
# Some programs (e.g. ssh) doesn't like secrets to be
# symlinks, so we use `cp -L` here to match the
# behaviour when secrets are natively supported.
cp -Lr ${source'} "$out/secrets/${dest}"
''
) config.boot.initrd.secrets))
}

View file

@ -478,6 +478,7 @@ in
createImportService = pool:
nameValuePair "zfs-import-${pool}" {
description = "Import ZFS pool \"${pool}\"";
# we need systemd-udev-settle until https://github.com/zfsonlinux/zfs/pull/4943 is merged
requires = [ "systemd-udev-settle.service" ];
after = [ "systemd-udev-settle.service" "systemd-modules-load.service" ];
wantedBy = (getPoolMounts pool) ++ [ "local-fs.target" ];