Commit fea0eb85 authored by sternenseemann's avatar sternenseemann
Browse files

Merge remote-tracking branch 'origin/master' into haskell-updates

parents 072b4ff7 6e45c538
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -11056,6 +11056,12 @@
    githubId = 47835714;
    name = "Nintron";
  };
  niols = {
    email = "niols@niols.fr";
    github = "niols";
    githubId = 5920602;
    name = "Nicolas Jeannerod";
  };
  nioncode = {
    email = "nioncode+github@gmail.com";
    github = "nioncode";
+8 −1
Original line number Diff line number Diff line
@@ -16,8 +16,12 @@ In addition to numerous new and upgraded packages, this release has the followin
    It's recommended to use `nixos-rebuild boot` and `reboot`, rather than `nixos-rebuild switch` - since in some rare cases
    the switch of a live system might fail.

  - glibc: 2.35 -\> 2.37

- Cinnamon has been updated to 5.6, see [the pull request](https://github.com/NixOS/nixpkgs/pull/201328#issue-1449910204) for what is changed.

- GNOME has been upgraded to version 44. Please see the [release notes](https://release.gnome.org/44/) for details.

- KDE Plasma has been updated to v5.27, see [the release notes](https://kde.org/announcements/plasma/5/5.27.0/) for what is changed.

- `nixos-rebuild` now supports an extra `--specialisation` option that can be used to change specialisation for `switch` and `test` commands.
@@ -232,7 +236,7 @@ In addition to numerous new and upgraded packages, this release has the followin

- `vim_configurable` has been renamed to `vim-full` to avoid confusion: `vim-full`'s build-time features are configurable, but both `vim` and `vim-full` are _customizable_ (in the sense of user configuration, like vimrc).

- Pantheon now defaults to Mutter 42 and GNOME settings daemon 42, all Pantheon packages are now tracking elementary OS 7 updates.
- Pantheon now defaults to Mutter 43 and GNOME settings daemon 43, all Pantheon packages are now tracking elementary OS 7 updates.

- The module for the application firewall `opensnitch` got the ability to configure rules. Available as [services.opensnitch.rules](#opt-services.opensnitch.rules)

@@ -396,6 +400,9 @@ In addition to numerous new and upgraded packages, this release has the followin

- The option `services.prometheus.exporters.pihole.interval` does not exist anymore and has been removed.

- The option `services.gpsd.device` has been replaced with
  `services.gpsd.devices`, which supports multiple devices.

- `k3s` can now be configured with an EnvironmentFile for its systemd service, allowing secrets to be provided without ending up in the Nix Store.

- `boot.initrd.luks.device.<name>` has a new `tryEmptyPassphrase` option, this is useful for OEM's who need to install an encrypted disk with a future settable passphrase
+1 −0
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@
  ./security/doas.nix
  ./security/duosec.nix
  ./security/google_oslogin.nix
  ./security/ipa.nix
  ./security/lock-kernel-modules.nix
  ./security/misc.nix
  ./security/oath.nix
+258 −0
Original line number Diff line number Diff line
{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.security.ipa;
  pyBool = x:
    if x
    then "True"
    else "False";

  ldapConf = pkgs.writeText "ldap.conf" ''
    # Turning this off breaks GSSAPI used with krb5 when rdns = false
    SASL_NOCANON    on

    URI ldaps://${cfg.server}
    BASE ${cfg.basedn}
    TLS_CACERT /etc/ipa/ca.crt
  '';
  nssDb =
    pkgs.runCommand "ipa-nssdb"
    {
      nativeBuildInputs = [pkgs.nss.tools];
    } ''
      mkdir -p $out
      certutil -d $out -N --empty-password
      certutil -d $out -A --empty-password -n "${cfg.realm} IPA CA" -t CT,C,C -i ${cfg.certificate}
    '';
in {
  options = {
    security.ipa = {
      enable = mkEnableOption (lib.mdDoc "FreeIPA domain integration");

      certificate = mkOption {
        type = types.package;
        description = lib.mdDoc ''
          IPA server CA certificate.

          Use `nix-prefetch-url http://$server/ipa/config/ca.crt` to
          obtain the file and the hash.
        '';
        example = literalExpression ''
          pkgs.fetchurl {
            url = http://ipa.example.com/ipa/config/ca.crt;
            sha256 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
          };
        '';
      };

      domain = mkOption {
        type = types.str;
        example = "example.com";
        description = lib.mdDoc "Domain of the IPA server.";
      };

      realm = mkOption {
        type = types.str;
        example = "EXAMPLE.COM";
        description = lib.mdDoc "Kerberos realm.";
      };

      server = mkOption {
        type = types.str;
        example = "ipa.example.com";
        description = lib.mdDoc "IPA Server hostname.";
      };

      basedn = mkOption {
        type = types.str;
        example = "dc=example,dc=com";
        description = lib.mdDoc "Base DN to use when performing LDAP operations.";
      };

      offlinePasswords = mkOption {
        type = types.bool;
        default = true;
        description = lib.mdDoc "Whether to store offline passwords when the server is down.";
      };

      cacheCredentials = mkOption {
        type = types.bool;
        default = true;
        description = lib.mdDoc "Whether to cache credentials.";
      };

      ifpAllowedUids = mkOption {
        type = types.listOf types.string;
        default = ["root"];
        description = lib.mdDoc "A list of users allowed to access the ifp dbus interface.";
      };

      dyndns = {
        enable = mkOption {
          type = types.bool;
          default = true;
          description = lib.mdDoc "Whether to enable FreeIPA automatic hostname updates.";
        };

        interface = mkOption {
          type = types.str;
          example = "eth0";
          default = "*";
          description = lib.mdDoc "Network interface to perform hostname updates through.";
        };
      };

      chromiumSupport = mkOption {
        type = types.bool;
        default = true;
        description = lib.mdDoc "Whether to whitelist the FreeIPA domain in Chromium.";
      };
    };
  };

  config = mkIf cfg.enable {
    assertions = [
      {
        assertion = !config.krb5.enable;
        message = "krb5 must be disabled through `krb5.enable` for FreeIPA integration to work.";
      }
      {
        assertion = !config.users.ldap.enable;
        message = "ldap must be disabled through `users.ldap.enable` for FreeIPA integration to work.";
      }
    ];

    environment.systemPackages = with pkgs; [krb5Full freeipa];

    environment.etc = {
      "ipa/default.conf".text = ''
        [global]
        basedn = ${cfg.basedn}
        realm = ${cfg.realm}
        domain = ${cfg.domain}
        server = ${cfg.server}
        host = ${config.networking.hostName}
        xmlrpc_uri = https://${cfg.server}/ipa/xml
        enable_ra = True
      '';

      "ipa/nssdb".source = nssDb;

      "krb5.conf".text = ''
        [libdefaults]
         default_realm = ${cfg.realm}
         dns_lookup_realm = false
         dns_lookup_kdc = true
         rdns = false
         ticket_lifetime = 24h
         forwardable = true
         udp_preference_limit = 0

        [realms]
         ${cfg.realm} = {
          kdc = ${cfg.server}:88
          master_kdc = ${cfg.server}:88
          admin_server = ${cfg.server}:749
          default_domain = ${cfg.domain}
          pkinit_anchors = FILE:/etc/ipa/ca.crt
        }

        [domain_realm]
         .${cfg.domain} = ${cfg.realm}
         ${cfg.domain} = ${cfg.realm}
         ${cfg.server} = ${cfg.realm}

        [dbmodules]
          ${cfg.realm} = {
            db_library = ${pkgs.freeipa}/lib/krb5/plugins/kdb/ipadb.so
          }
      '';

      "openldap/ldap.conf".source = ldapConf;
    };

    environment.etc."chromium/policies/managed/freeipa.json" = mkIf cfg.chromiumSupport {
      text = ''
        { "AuthServerWhitelist": "*.${cfg.domain}" }
      '';
    };

    system.activationScripts.ipa = stringAfter ["etc"] ''
      # libcurl requires a hard copy of the certificate
      if ! ${pkgs.diffutils}/bin/diff ${cfg.certificate} /etc/ipa/ca.crt > /dev/null 2>&1; then
        rm -f /etc/ipa/ca.crt
        cp ${cfg.certificate} /etc/ipa/ca.crt
      fi

      if [ ! -f /etc/krb5.keytab ]; then
        cat <<EOF

          In order to complete FreeIPA integration, please join the domain by completing the following steps:
          1. Authenticate as an IPA user authorized to join new hosts, e.g. kinit admin@${cfg.realm}
          2. Join the domain and obtain the keytab file: ipa-join
          3. Install the keytab file: sudo install -m 600 krb5.keytab /etc/
          4. Restart sssd systemd service: sudo systemctl restart sssd

      EOF
      fi
    '';

    services.sssd.config = ''
      [domain/${cfg.domain}]
      id_provider = ipa
      auth_provider = ipa
      access_provider = ipa
      chpass_provider = ipa

      ipa_domain = ${cfg.domain}
      ipa_server = _srv_, ${cfg.server}
      ipa_hostname = ${config.networking.hostName}.${cfg.domain}

      cache_credentials = ${pyBool cfg.cacheCredentials}
      krb5_store_password_if_offline = ${pyBool cfg.offlinePasswords}
      ${optionalString ((toLower cfg.domain) != (toLower cfg.realm))
        "krb5_realm = ${cfg.realm}"}

      dyndns_update = ${pyBool cfg.dyndns.enable}
      dyndns_iface = ${cfg.dyndns.interface}

      ldap_tls_cacert = /etc/ipa/ca.crt
      ldap_user_extra_attrs = mail:mail, sn:sn, givenname:givenname, telephoneNumber:telephoneNumber, lock:nsaccountlock

      [sssd]
      debug_level = 65510
      services = nss, sudo, pam, ssh, ifp
      domains = ${cfg.domain}

      [nss]
      homedir_substring = /home

      [pam]
      pam_pwd_expiration_warning = 3
      pam_verbosity = 3

      [sudo]
      debug_level = 65510

      [autofs]

      [ssh]

      [pac]

      [ifp]
      user_attributes = +mail, +telephoneNumber, +givenname, +sn, +lock
      allowed_uids = ${concatStringsSep ", " cfg.ifpAllowedUids}
    '';

    services.ntp.servers = singleton cfg.server;
    services.sssd.enable = true;
    services.ntp.enable = true;

    security.pki.certificateFiles = singleton cfg.certificate;
  };
}
+27 −19
Original line number Diff line number Diff line
{ config, lib, pkgs, ... }:
{ config, lib, pkgs, utils, ... }:

with lib;

@@ -8,12 +8,15 @@ let
  gid = config.ids.gids.gpsd;
  cfg = config.services.gpsd;

in

{
in {

  ###### interface

  imports = [
    (lib.mkRemovedOptionModule [ "services" "gpsd" "device" ]
      "Use `services.gpsd.devices` instead.")
  ];

  options = {

    services.gpsd = {
@@ -26,13 +29,17 @@ in
        '';
      };

      device = mkOption {
        type = types.str;
        default = "/dev/ttyUSB0";
      devices = mkOption {
        type = types.listOf types.str;
        default = [ "/dev/ttyUSB0" ];
        description = lib.mdDoc ''
          A device may be a local serial device for GPS input, or a URL of the form:
               `[{dgpsip|ntrip}://][user:passwd@]host[:port][/stream]`
          in which case it specifies an input source for DGPS or ntrip data.
          List of devices that `gpsd` should subscribe to.

          A device may be a local serial device for GPS input, or a
          URL of the form:
          `[{dgpsip|ntrip}://][user:passwd@]host[:port][/stream]` in
          which case it specifies an input source for DGPS or ntrip
          data.
        '';
      };

@@ -89,13 +96,12 @@ in

  };


  ###### implementation

  config = mkIf cfg.enable {

    users.users.gpsd =
      { inherit uid;
    users.users.gpsd = {
      inherit uid;
      group = "gpsd";
      description = "gpsd daemon user";
      home = "/var/empty";
@@ -109,13 +115,15 @@ in
      after = [ "network.target" ];
      serviceConfig = {
        Type = "forking";
        ExecStart = ''
        ExecStart = let
          devices = utils.escapeSystemdExecArgs cfg.devices;
        in ''
          ${pkgs.gpsd}/sbin/gpsd -D "${toString cfg.debugLevel}"  \
            -S "${toString cfg.port}"                             \
            ${optionalString cfg.readonly "-b"}                   \
            ${optionalString cfg.nowait "-n"}                     \
            ${optionalString cfg.listenany "-G"}                  \
            "${cfg.device}"
            ${devices}
        '';
      };
    };
Loading