[Nix-dev] [PoC] Automatic UIDs and keys owned by non-root users

Игорь Пашев pashev.igor at gmail.com
Sun Nov 29 17:20:45 CET 2015


$ id mariadb
uid=1000003264(mariadb) gid=1000003264(mariadb)
groups=96(keys),1000003264(mariadb)

...
  config = mkIf cfg.enable {
    autoUsers = [ cfg.user ];
    keyrings.${cfg.user} = [ cfg.s3cfg ];
...


keyrings.nix: ----------------
{ config, lib, ... }:

with lib;
with lib.types;
with builtins;

let
  allusers = config.users.users;
  read = key:
    if config.production
    then (readFile (<secrets> + "/${key}"))
    else "dummy";

in {
  options = {
    keyrings = mkOption {
      type = attrsOf (listOf path);
      description = "Binds keys to a user";
      default = {};
      example = { backup = [ "s3cmd.cfg" ]; };
    };
  };

  config = {
    users.users = genAttrs (attrNames config.keyrings) (
      name: optionalAttrs (name != "root") { extraGroups = [ "keys" ]; }
    );

    deployment.keys = foldl (a: b: a//b) {} (
      mapAttrsToList (name: keys:
        genAttrs (map baseNameOf keys)
                 (key: { text = read key;
                         user = toString allusers.${name}.uid;
                       })
      ) config.keyrings
    );
  };
}


autoUsers.nix: ---------------
{ config, pkgs, lib, ... }:

let
  names = config.autoUsers;
  uid = name: let
      dec = {
        "0" =  0; "1" =  1; "2" =  2; "3" =  3;
        "4" =  4; "5" =  5; "6" =  6; "7" =  7;
        "8" =  8; "9" =  9; "a" = 10; "b" = 11;
        "c" = 12; "d" = 13; "e" = 14; "f" = 15;
      };
      base = 1000000000; # 2^31 > base + 16^7, 2^31 for JSON int
      hex = lib.toLower (builtins.substring 0 7 (builtins.hashString
"sha1" name));
      digits = lib.imap (i: d: {m = (i - 1)*16; d = d;})
(lib.stringToCharacters hex);
      f = a: {m, d}: a + m * dec.${d};

      in lib.foldl f base digits;

in {
  options = {
    autoUsers = lib.mkOption {
      type = lib.types.listOf lib.types.str;
      description = "List of system users with automatic UID and group";
      default = [];
    };
  };

  config = {
    users.extraGroups = lib.genAttrs names (name: { gid = uid name; });
    users.extraUsers = lib.genAttrs names
      (name: {
        isSystemUser = true;
        uid = uid name;
        group = name;
      });
  };
}


More information about the nix-dev mailing list