diff options
Diffstat (limited to 'nixos')
21 files changed, 480 insertions, 69 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 582b1715d1a4..78bd6c6a22d8 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -322,6 +322,15 @@ </listitem> <listitem> <para> + <link xlink:href="https://github.com/tmate-io/tmate-ssh-server">tmate-ssh-server</link>, + server side part of + <link xlink:href="https://tmate.io/">tmate</link>. Available + as + <link linkend="opt-services.tmate-ssh-server.enable">services.tmate-ssh-server</link>. + </para> + </listitem> + <listitem> + <para> <link xlink:href="https://www.grafana.com/oss/tempo/">Grafana Tempo</link>, a distributed tracing store. Available as <link linkend="opt-services.tempo.enable">services.tempo</link>. @@ -529,6 +538,16 @@ </listitem> <listitem> <para> + <literal>teleport</literal> has been upgraded to major version + 10. Please see upstream + <link xlink:href="https://goteleport.com/docs/ver/10.0/management/operations/upgrading/">upgrade + instructions</link> and + <link xlink:href="https://goteleport.com/docs/ver/10.0/changelog/#1000">release + notes</link>. + </para> + </listitem> + <listitem> + <para> lemmy module option <literal>services.lemmy.settings.database.createLocally</literal> moved to diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 3e38f85b8f10..37b0db8a8ce1 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -110,6 +110,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [go-autoconfig](https://github.com/L11R/go-autoconfig), IMAP/SMTP autodiscover server. Available as [services.go-autoconfig](#opt-services.go-autoconfig.enable). +- [tmate-ssh-server](https://github.com/tmate-io/tmate-ssh-server), server side part of [tmate](https://tmate.io/). Available as [services.tmate-ssh-server](#opt-services.tmate-ssh-server.enable). + - [Grafana Tempo](https://www.grafana.com/oss/tempo/), a distributed tracing store. Available as [services.tempo](#opt-services.tempo.enable). - [AusweisApp2](https://www.ausweisapp.bund.de/), the authentication software for the German ID card. Available as [programs.ausweisapp](#opt-programs.ausweisapp.enable). @@ -178,6 +180,8 @@ Available as [services.patroni](options.html#opt-services.patroni.enable). - dd-agent package removed along with the `services.dd-agent` module, due to the project being deprecated in favor of `datadog-agent`, which is available via the `services.datadog-agent` module. +- `teleport` has been upgraded to major version 10. Please see upstream [upgrade instructions](https://goteleport.com/docs/ver/10.0/management/operations/upgrading/) and [release notes](https://goteleport.com/docs/ver/10.0/changelog/#1000). + - lemmy module option `services.lemmy.settings.database.createLocally` moved to `services.lemmy.database.createLocally`. diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix index d7671a374999..f646f70323e3 100644 --- a/nixos/lib/utils.nix +++ b/nixos/lib/utils.nix @@ -102,7 +102,11 @@ rec { if item ? ${attr} then nameValuePair prefix item.${attr} else if isAttrs item then - map (name: recurse (prefix + "." + name) item.${name}) (attrNames item) + map (name: + let + escapedName = ''"${replaceChars [''"'' "\\"] [''\"'' "\\\\"] name}"''; + in + recurse (prefix + "." + escapedName) item.${name}) (attrNames item) else if isList item then imap0 (index: item: recurse (prefix + "[${toString index}]") item) item else @@ -182,13 +186,13 @@ rec { '') (attrNames secrets)) + "\n" - + "${pkgs.jq}/bin/jq >'${output}' '" - + concatStringsSep + + "${pkgs.jq}/bin/jq >'${output}' " + + lib.escapeShellArg (concatStringsSep " | " (imap1 (index: name: ''${name} = $ENV.secret${toString index}'') - (attrNames secrets)) + (attrNames secrets))) + '' - ' <<'EOF' + <<'EOF' ${builtins.toJSON set} EOF (( ! $inherit_errexit_enabled )) && shopt -u inherit_errexit diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index c25450167075..db07d6312c42 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -960,6 +960,7 @@ ./services/networking/tinc.nix ./services/networking/tinydns.nix ./services/networking/tftpd.nix + ./services/networking/tmate-ssh-server.nix ./services/networking/trickster.nix ./services/networking/tox-bootstrapd.nix ./services/networking/tox-node.nix diff --git a/nixos/modules/security/acme/default.nix b/nixos/modules/security/acme/default.nix index 377b543c5813..e9299fb1b3ad 100644 --- a/nixos/modules/security/acme/default.nix +++ b/nixos/modules/security/acme/default.nix @@ -190,7 +190,7 @@ let ); renewOpts = escapeShellArgs ( commonOpts - ++ [ "renew" ] + ++ [ "renew" "--no-random-sleep" ] ++ optionals data.ocspMustStaple [ "--must-staple" ] ++ data.extraLegoRenewFlags ); @@ -223,9 +223,9 @@ let # have many certificates, the renewals are distributed over # the course of the day to avoid rate limits. AccuracySec = "${toString (_24hSecs / numCerts)}s"; - # Skew randomly within the day, per https://letsencrypt.org/docs/integration-guide/. RandomizedDelaySec = "24h"; + FixedRandomDelay = true; }; }; @@ -325,6 +325,7 @@ let ''); } // optionalAttrs (data.listenHTTP != null && toInt (elemAt (splitString ":" data.listenHTTP) 1) < 1024) { CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; }; # Working directory will be /tmp @@ -376,7 +377,8 @@ let # Check if we can renew. # We can only renew if the list of domains has not changed. - if cmp -s domainhash.txt certificates/domainhash.txt && [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' -a -n "$(ls -1 accounts)" ]; then + # We also need an account key. Avoids #190493 + if cmp -s domainhash.txt certificates/domainhash.txt && [ -e 'certificates/${keyName}.key' -a -e 'certificates/${keyName}.crt' -a -n "$(find accounts -name '${data.email}.key')" ]; then # Even if a cert is not expired, it may be revoked by the CA. # Try to renew, and silently fail if the cert is not expired. diff --git a/nixos/modules/security/acme/doc.xml b/nixos/modules/security/acme/doc.xml index 4817f7a7fc6b..1439594a5aca 100644 --- a/nixos/modules/security/acme/doc.xml +++ b/nixos/modules/security/acme/doc.xml @@ -237,8 +237,8 @@ services.bind = { <programlisting> systemd.services.dns-rfc2136-conf = { - requiredBy = ["acme-example.com.service", "bind.service"]; - before = ["acme-example.com.service", "bind.service"]; + requiredBy = ["acme-example.com.service" "bind.service"]; + before = ["acme-example.com.service" "bind.service"]; unitConfig = { ConditionPathExists = "!/var/lib/secrets/dnskeys.conf"; }; @@ -249,18 +249,19 @@ systemd.services.dns-rfc2136-conf = { path = [ pkgs.bind ]; script = '' mkdir -p /var/lib/secrets + chmod 755 /var/lib/secrets tsig-keygen rfc2136key.example.com > /var/lib/secrets/dnskeys.conf chown named:root /var/lib/secrets/dnskeys.conf chmod 400 /var/lib/secrets/dnskeys.conf - # Copy the secret value from the dnskeys.conf, and put it in - # RFC2136_TSIG_SECRET below + # extract secret value from the dnskeys.conf + while read x y; do if [ "$x" = "secret" ]; then secret="''${y:1:''${#y}-3}"; fi; done < /var/lib/secrets/dnskeys.conf cat > /var/lib/secrets/certs.secret << EOF RFC2136_NAMESERVER='127.0.0.1:53' RFC2136_TSIG_ALGORITHM='hmac-sha256.' RFC2136_TSIG_KEY='rfc2136key.example.com' - RFC2136_TSIG_SECRET='your secret key' + RFC2136_TSIG_SECRET='$secret' EOF chmod 400 /var/lib/secrets/certs.secret ''; diff --git a/nixos/modules/services/hardware/fwupd.nix b/nixos/modules/services/hardware/fwupd.nix index 2249f866803a..1be2d49f9708 100644 --- a/nixos/modules/services/hardware/fwupd.nix +++ b/nixos/modules/services/hardware/fwupd.nix @@ -33,18 +33,26 @@ let mkEtcFile = p: nameValuePair (mkName p) { source = p; }; in listToAttrs (map mkEtcFile cfg.extraTrustedKeys); - # We cannot include the file in $out and rely on filesInstalledToEtc - # to install it because it would create a cyclic dependency between - # the outputs. We also need to enable the remote, - # which should not be done by default. - testRemote = if cfg.enableTestRemote then { - "fwupd/remotes.d/fwupd-tests.conf" = { - source = pkgs.runCommand "fwupd-tests-enabled.conf" {} '' + enableRemote = base: remote: { + "fwupd/remotes.d/${remote}.conf" = { + source = pkgs.runCommand "${remote}-enabled.conf" {} '' sed "s,^Enabled=false,Enabled=true," \ - "${cfg.package.installedTests}/etc/fwupd/remotes.d/fwupd-tests.conf" > "$out" + "${base}/etc/fwupd/remotes.d/${remote}.conf" > "$out" ''; }; - } else {}; + }; + remotes = (foldl' + (configFiles: remote: configFiles // (enableRemote cfg.package remote)) + {} + cfg.extraRemotes + ) // ( + # We cannot include the file in $out and rely on filesInstalledToEtc + # to install it because it would create a cyclic dependency between + # the outputs. We also need to enable the remote, + # which should not be done by default. + mkIf cfg.enableTestRemote (enableRemote cfg.package.installedTests "fwupd-tests") + ); + in { ###### interface @@ -86,6 +94,15 @@ in { ''; }; + extraRemotes = mkOption { + type = with types; listOf str; + default = []; + example = [ "lvfs-testing" ]; + description = lib.mdDoc '' + Enables extra remotes in fwupd. See `/etc/fwupd/remotes.d`. + ''; + }; + enableTestRemote = mkOption { type = types.bool; default = false; @@ -119,7 +136,7 @@ in { environment.systemPackages = [ cfg.package ]; # customEtc overrides some files from the package - environment.etc = originalEtc // customEtc // extraTrustedKeys // testRemote; + environment.etc = originalEtc // customEtc // extraTrustedKeys // remotes; services.dbus.packages = [ cfg.package ]; diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix index fa9d06b441af..4b962da0c037 100644 --- a/nixos/modules/services/hardware/udev.nix +++ b/nixos/modules/services/hardware/udev.nix @@ -171,10 +171,10 @@ let mv etc/udev/hwdb.bin $out ''; - compressFirmware = if config.boot.kernelPackages.kernelAtLeast "5.3" then - pkgs.compressFirmwareXz + compressFirmware = firmware: if (config.boot.kernelPackages.kernelAtLeast "5.3" && (firmware.compressFirmware or true)) then + pkgs.compressFirmwareXz firmware else - id; + id firmware; # Udev has a 512-character limit for ENV{PATH}, so create a symlink # tree to work around this. diff --git a/nixos/modules/services/matrix/dendrite.nix b/nixos/modules/services/matrix/dendrite.nix index 9279af246f41..a5fea3da4844 100644 --- a/nixos/modules/services/matrix/dendrite.nix +++ b/nixos/modules/services/matrix/dendrite.nix @@ -195,6 +195,25 @@ in ''; }; }; + options.sync_api.search = { + enable = lib.mkEnableOption (lib.mdDoc "Dendrite's full-text search engine"); + index_path = lib.mkOption { + type = lib.types.str; + default = "${workingDir}/searchindex"; + description = lib.mdDoc '' + The path the search index will be created in. + ''; + }; + language = lib.mkOption { + type = lib.types.str; + default = "en"; + description = lib.mdDoc '' + The language most likely to be used on the server - used when indexing, to + ensure the returned results match expectations. A full list of possible languages + can be found at https://github.com/blevesearch/bleve/tree/master/analysis/lang + ''; + }; + }; options.user_api = { account_database = { connection_string = lib.mkOption { diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index e5de3a2b6ad1..772693cb624e 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -6,6 +6,9 @@ let cfg = config.services.gitlab; opt = options.services.gitlab; + toml = pkgs.formats.toml {}; + yaml = pkgs.formats.yaml {}; + ruby = cfg.packages.gitlab.ruby; postgresqlPackage = if config.services.postgresql.enable then @@ -89,17 +92,18 @@ let repos_path = "${cfg.statePath}/repositories"; secret_file = "${cfg.statePath}/gitlab_shell_secret"; log_file = "${cfg.statePath}/log/gitlab-shell.log"; - redis = { - bin = "${pkgs.redis}/bin/redis-cli"; - host = "127.0.0.1"; - port = config.services.redis.servers.gitlab.port; - database = 0; - namespace = "resque:gitlab"; - }; }; redisConfig.production.url = cfg.redisUrl; + cableYml = yaml.generate "cable.yml" { + production = { + adapter = "redis"; + url = cfg.redisUrl; + channel_prefix = "gitlab_production"; + }; + }; + pagesArgs = [ "-pages-domain" gitlabConfig.production.pages.host "-pages-root" "${gitlabConfig.production.shared.path}/pages" @@ -188,6 +192,17 @@ let MALLOC_ARENA_MAX = "2"; } // cfg.extraEnv; + runtimeDeps = with pkgs; [ + nodejs + gzip + git + gnutar + postgresqlPackage + coreutils + procps + findutils # Needed for gitlab:cleanup:orphan_job_artifact_files + ]; + gitlab-rake = pkgs.stdenv.mkDerivation { name = "gitlab-rake"; buildInputs = [ pkgs.makeWrapper ]; @@ -197,7 +212,7 @@ let mkdir -p $out/bin makeWrapper ${cfg.packages.gitlab.rubyEnv}/bin/rake $out/bin/gitlab-rake \ ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") gitlabEnv)} \ - --set PATH '${lib.makeBinPath [ pkgs.nodejs pkgs.gzip pkgs.git pkgs.gnutar postgresqlPackage pkgs.coreutils pkgs.procps ]}:$PATH' \ + --set PATH '${lib.makeBinPath runtimeDeps}:$PATH' \ --set RAKEOPT '-f ${cfg.packages.gitlab}/share/gitlab/Rakefile' \ --chdir '${cfg.packages.gitlab}/share/gitlab' ''; @@ -212,7 +227,7 @@ let mkdir -p $out/bin makeWrapper ${cfg.packages.gitlab.rubyEnv}/bin/rails $out/bin/gitlab-rails \ ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${value}' ") gitlabEnv)} \ - --set PATH '${lib.makeBinPath [ pkgs.nodejs pkgs.gzip pkgs.git pkgs.gnutar postgresqlPackage pkgs.coreutils pkgs.procps ]}:$PATH' \ + --set PATH '${lib.makeBinPath runtimeDeps}:$PATH' \ --chdir '${cfg.packages.gitlab}/share/gitlab' ''; }; @@ -468,9 +483,9 @@ in { redisUrl = mkOption { type = types.str; - default = "redis://localhost:${toString config.services.redis.servers.gitlab.port}/"; - defaultText = literalExpression ''redis://localhost:''${toString config.services.redis.servers.gitlab.port}/''; - description = lib.mdDoc "Redis URL for all GitLab services except gitlab-shell"; + default = "unix:/run/gitlab/redis.sock"; + example = "redis://localhost:6379/"; + description = lib.mdDoc "Redis URL for all GitLab services."; }; extraGitlabRb = mkOption { @@ -867,8 +882,41 @@ in { }; }; + workhorse.config = mkOption { + type = toml.type; + default = {}; + example = literalExpression '' + { + object_storage.provider = "AWS"; + object_storage.s3 = { + aws_access_key_id = "AKIAXXXXXXXXXXXXXXXX"; + aws_secret_access_key = { _secret = "/var/keys/aws_secret_access_key"; }; + }; + }; + ''; + description = lib.mdDoc '' + Configuration options to add to Workhorse's configuration + file. + + See + <https://gitlab.com/gitlab-org/gitlab/-/blob/master/workhorse/config.toml.example> + and + <https://docs.gitlab.com/ee/development/workhorse/configuration.html> + for examples and option documentation. + + Options containing secret data should be set to an attribute + set containing the attribute `_secret` - a string pointing + to a file containing the value the option should be set + to. See the example to get a better picture of this: in the + resulting configuration file, the + `object_storage.s3.aws_secret_access_key` key will be set to + the contents of the {file}`/var/keys/aws_secret_access_key` + file. + ''; + }; + extraConfig = mkOption { - type = types.attrs; + type = yaml.type; default = {}; example = literalExpression '' { @@ -972,8 +1020,9 @@ in { # Redis is required for the sidekiq queue runner. services.redis.servers.gitlab = { enable = mkDefault true; - port = mkDefault 31636; - bind = mkDefault "127.0.0.1"; + user = mkDefault cfg.user; + unixSocket = mkDefault "/run/gitlab/redis.sock"; + unixSocketPerm = mkDefault 770; }; # We use postgres as the main data store. @@ -1062,6 +1111,7 @@ in { # Ensure Docker Registry launches after the certificate generation job systemd.services.docker-registry = optionalAttrs cfg.registry.enable { wants = [ "gitlab-registry-cert.service" ]; + after = [ "gitlab-registry-cert.service" ]; }; # Enable Docker Registry, if GitLab-Container Registry is enabled @@ -1115,6 +1165,7 @@ in { "d ${gitlabConfig.production.shared.path}/lfs-objects 0750 ${cfg.user} ${cfg.group} -" "d ${gitlabConfig.production.shared.path}/packages 0750 ${cfg.user} ${cfg.group} -" "d ${gitlabConfig.production.shared.path}/pages 0750 ${cfg.user} ${cfg.group} -" + "d ${gitlabConfig.production.shared.path}/registry 0750 ${cfg.user} ${cfg.group} -" "d ${gitlabConfig.production.shared.path}/terraform_state 0750 ${cfg.user} ${cfg.group} -" "L+ /run/gitlab/config - - - - ${cfg.statePath}/config" "L+ /run/gitlab/log - - - - ${cfg.statePath}/log" @@ -1168,6 +1219,7 @@ in { cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/config.dist/* ${cfg.statePath}/config cp -rf --no-preserve=mode ${cfg.packages.gitlab}/share/gitlab/db/* ${cfg.statePath}/db ln -sf ${extraGitlabRb} ${cfg.statePath}/config/initializers/extra-gitlab.rb + ln -sf ${cableYml} ${cfg.statePath}/config/cable.yml ${cfg.packages.gitlab-shell}/bin/install @@ -1357,6 +1409,7 @@ in { wantedBy = [ "gitlab.target" ]; partOf = [ "gitlab.target" ]; path = with pkgs; [ + remarshal exiftool gitPackage gnutar @@ -1371,6 +1424,17 @@ in { TimeoutSec = "infinity"; Restart = "on-failure"; WorkingDirectory = gitlabEnv.HOME; + ExecStartPre = pkgs.writeShellScript "gitlab-workhorse-pre-start" '' + set -o errexit -o pipefail -o nounset + shopt -s dotglob nullglob inherit_errexit + + ${utils.genJqSecretsReplacementSnippet + cfg.workhorse.config + "${cfg.statePath}/config/gitlab-workhorse.json"} + + json2toml "${cfg.statePath}/config/gitlab-workhorse.json" "${cfg.statePath}/config/gitlab-workhorse.toml" + rm "${cfg.statePath}/config/gitlab-workhorse.json" + ''; ExecStart = "${cfg.packages.gitlab-workhorse}/bin/workhorse " + "-listenUmask 0 " @@ -1378,6 +1442,7 @@ in { + "-listenAddr /run/gitlab/gitlab-workhorse.socket " + "-authSocket ${gitlabSocket} " + "-documentRoot ${cfg.packages.gitlab}/share/gitlab/public " + + "-config ${cfg.statePath}/config/gitlab-workhorse.toml " + "-secretPath ${cfg.statePath}/.gitlab_workhorse_secret"; }; }; diff --git a/nixos/modules/services/networking/firefox-syncserver.nix b/nixos/modules/services/networking/firefox-syncserver.nix index fa8e4fcaed2f..d7d5df59a4eb 100644 --- a/nixos/modules/services/networking/firefox-syncserver.nix +++ b/nixos/modules/services/networking/firefox-syncserver.nix @@ -19,6 +19,9 @@ let fxa_email_domain = "api.accounts.firefox.com"; fxa_oauth_server_url = "https://oauth.accounts.firefox.com/v1"; run_migrations = true; + # if JWK caching is not enabled the token server must verify tokens + # using the fxa api, on a thread pool with a static size. + additional_blocking_threads_for_fxa_requests = 10; } // lib.optionalAttrs cfg.singleNode.enable { # Single-node mode is likely to be used on small instances with little # capacity. The default value (0.1) can only ever release capacity when @@ -309,11 +312,7 @@ in enableACME = cfg.singleNode.enableTLS; forceSSL = cfg.singleNode.enableTLS; locations."/" = { - proxyPass = "http://localhost:${toString cfg.settings.port}"; - # source mentions that this header should be set - extraConfig = '' - add_header X-Content-Type-Options nosniff; - ''; + proxyPass = "http://127.0.0.1:${toString cfg.settings.port}"; }; }; }; diff --git a/nixos/modules/services/networking/iwd.nix b/nixos/modules/services/networking/iwd.nix index 526e6ab0a7ad..a9908b01a58a 100644 --- a/nixos/modules/services/networking/iwd.nix +++ b/nixos/modules/services/networking/iwd.nix @@ -67,5 +67,5 @@ in }; }; - meta.maintainers = with lib.maintainers; [ mic92 dtzWill ]; + meta.maintainers = with lib.maintainers; [ dtzWill ]; } diff --git a/nixos/modules/services/networking/jitsi-videobridge.nix b/nixos/modules/services/networking/jitsi-videobridge.nix index 4455b7bcee4a..eefaa70604cd 100644 --- a/nixos/modules/services/networking/jitsi-videobridge.nix +++ b/nixos/modules/services/networking/jitsi-videobridge.nix @@ -70,7 +70,7 @@ in description = lib.mdDoc '' Videobridge configuration. - See <https://github.com/jitsi/jitsi-videobridge/blob/master/src/main/resources/reference.conf> + See <https://github.com/jitsi/jitsi-videobridge/blob/master/jvb/src/main/resources/reference.conf> for default configuration with comments. ''; }; 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 000000000000..1b8f6662ef4c --- /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 ]; + }; + +} diff --git a/nixos/modules/tasks/filesystems/jfs.nix b/nixos/modules/tasks/filesystems/jfs.nix index 700f05af2bec..6d80c4c657da 100644 --- a/nixos/modules/tasks/filesystems/jfs.nix +++ b/nixos/modules/tasks/filesystems/jfs.nix @@ -12,7 +12,7 @@ in boot.initrd.kernelModules = mkIf inInitrd [ "jfs" ]; - boot.initrd.extraUtilsCommands = mkIf (inInitrd && !boot.initrd.systemd.enable) '' + boot.initrd.extraUtilsCommands = mkIf (inInitrd && !config.boot.initrd.systemd.enable) '' copy_bin_and_libs ${pkgs.jfsutils}/sbin/fsck.jfs ''; }; diff --git a/nixos/tests/acme.nix b/nixos/tests/acme.nix index d3a436080ebf..d540bc6ec31b 100644 --- a/nixos/tests/acme.nix +++ b/nixos/tests/acme.nix @@ -41,6 +41,16 @@ inherit documentRoot; }; + simpleConfig = { + security.acme = { + certs."http.example.test" = { + listenHTTP = ":80"; + }; + }; + + networking.firewall.allowedTCPPorts = [ 80 ]; + }; + # Base specialisation config for testing general ACME features webserverBasicConfig = { services.nginx.enable = true; @@ -173,6 +183,26 @@ in { services.nginx.logError = "stderr info"; specialisation = { + # Tests HTTP-01 verification using Lego's built-in web server + http01lego.configuration = simpleConfig; + + renew.configuration = lib.mkMerge [ + simpleConfig + { + # Pebble provides 5 year long certs |