Should have a working KDC...
This commit is contained in:
parent
945312e94e
commit
098b55d047
|
@ -40,7 +40,7 @@
|
||||||
local-groups = [ "fudo" "selby" "admin" ];
|
local-groups = [ "fudo" "selby" "admin" ];
|
||||||
local-admins = [ "niten" ];
|
local-admins = [ "niten" ];
|
||||||
admin-email = "niten@fudo.org";
|
admin-email = "niten@fudo.org";
|
||||||
gssapi-realm = "FUDO.ORG";
|
gssapi-realm = "RUS.SELBY.CA";
|
||||||
};
|
};
|
||||||
|
|
||||||
"informis.land" = {
|
"informis.land" = {
|
||||||
|
|
|
@ -91,8 +91,8 @@ in {
|
||||||
realm = "RUS.SELBY.CA";
|
realm = "RUS.SELBY.CA";
|
||||||
bind-addresses = [ "10.0.0.1" "127.0.0.1" "[::1]" ];
|
bind-addresses = [ "10.0.0.1" "127.0.0.1" "[::1]" ];
|
||||||
acl = {
|
acl = {
|
||||||
"niten" = { perms = [ "all" ]; };
|
"niten" = { perms = [ "add" "change-password" "list" ]; };
|
||||||
"*/root" = { perms = [ "password" "list" ]; };
|
"*/root" = { perms = [ "all" ]; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
let local-domain = "rus.selby.ca";
|
let local-domain = "rus.selby.ca";
|
||||||
|
|
||||||
in {
|
in {
|
||||||
default-host = "10.0.0.1";
|
default-host = "10.0.0.1";
|
||||||
|
|
||||||
mx = [ "mail.fudo.org" ];
|
mx = [ "mail.fudo.org" ];
|
||||||
|
|
||||||
gssapi-realm = "FUDO.ORG";
|
gssapi-realm = toUpper local-domain;
|
||||||
|
|
||||||
hosts = {
|
hosts = {
|
||||||
clunk = {
|
clunk = {
|
||||||
|
@ -61,11 +61,11 @@ in {
|
||||||
}];
|
}];
|
||||||
kerberos = [{
|
kerberos = [{
|
||||||
port = 88;
|
port = 88;
|
||||||
host = "france.fudo.org";
|
host = "clunk.${local-domain}";
|
||||||
}];
|
}];
|
||||||
kerberos-adm = [{
|
kerberos-adm = [{
|
||||||
port = 88;
|
port = 749;
|
||||||
host = "france.fudo.org";
|
host = "clunk.${local-domain}";
|
||||||
}];
|
}];
|
||||||
ssh = [{
|
ssh = [{
|
||||||
port = 22;
|
port = 22;
|
||||||
|
@ -80,15 +80,15 @@ in {
|
||||||
}];
|
}];
|
||||||
kerberos = [{
|
kerberos = [{
|
||||||
port = 88;
|
port = 88;
|
||||||
host = "france.fudo.org";
|
host = "clunk.${local-domain}";
|
||||||
}];
|
}];
|
||||||
kerboros-master = [{
|
kerboros-master = [{
|
||||||
port = 88;
|
port = 88;
|
||||||
host = "france.fudo.org";
|
host = "clunk.${local-domain}";
|
||||||
}];
|
}];
|
||||||
kpasswd = [{
|
kpasswd = [{
|
||||||
port = 464;
|
port = 464;
|
||||||
host = "france.fudo.org";
|
host = "clunk.${local-domain}";
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,15 +25,22 @@ in {
|
||||||
krb5 = {
|
krb5 = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
appdefaults = {
|
||||||
|
forwardable = true;
|
||||||
|
proxiable = true;
|
||||||
|
encrypt = true;
|
||||||
|
forward = true;
|
||||||
|
};
|
||||||
|
|
||||||
libdefaults = {
|
libdefaults = {
|
||||||
allow_weak_crypto = false;
|
allow_weak_crypto = false;
|
||||||
dns_lookup_kdc = true;
|
dns_lookup_kdc = true;
|
||||||
|
dns_lookup_realm = true;
|
||||||
forwardable = true;
|
forwardable = true;
|
||||||
ignore_acceptor_hostname = true;
|
|
||||||
noaddresses = true;
|
|
||||||
rdns = false;
|
|
||||||
proxiable = true;
|
proxiable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kerberos = pkgs.heimdalFull;
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
|
|
|
@ -85,6 +85,13 @@ let
|
||||||
enable-gui = mkEnableOption "Install desktop GUI software.";
|
enable-gui = mkEnableOption "Install desktop GUI software.";
|
||||||
|
|
||||||
docker-server = mkEnableOption "Enable Docker on the current host.";
|
docker-server = mkEnableOption "Enable Docker on the current host.";
|
||||||
|
|
||||||
|
kerberos-services = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"List of services which should exist for this host, if it belongs to a realm.";
|
||||||
|
default = [ "ssh" "host" ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
289
lib/fudo/kdc.nix
289
lib/fudo/kdc.nix
|
@ -4,92 +4,82 @@ with lib;
|
||||||
let
|
let
|
||||||
cfg = config.fudo.auth.kdc;
|
cfg = config.fudo.auth.kdc;
|
||||||
|
|
||||||
kerberos-database = "${cfg.state-directory}/kerberos.db";
|
database-file = "${cfg.state-directory}/principals.db";
|
||||||
|
iprop-log = "${cfg.state-directory}/iprop.log";
|
||||||
|
acl-file = generate-acl-file cfg.acl;
|
||||||
|
kdc-conf =
|
||||||
|
generate-kdc-conf cfg.realm database-file cfg.master-key-file acl-file;
|
||||||
|
|
||||||
get-domain-hosts = domain:
|
get-domain-hosts = domain:
|
||||||
mapAttrsToList (host: hostOpts: "${host}.${domain}")
|
attrNames
|
||||||
(filterAttrs (host: hostOpts: hostOpts.domain == domain) config.fudo.hosts);
|
(filterAttrs (host: hostOpts: hostOpts.domain == domain) config.fudo.hosts);
|
||||||
|
|
||||||
add-host-principals = realm: db-name: host: ''
|
get-host-principals = realm: hostname:
|
||||||
${pkgs.krb5}/bin/kadmin.local -d ${db-name} addprinc -randkey host/${host} -r ${realm}
|
let host = config.fudo.hosts.${hostname};
|
||||||
${pkgs.krb5}/bin/kadmin.local -d ${db-name} addprinc -randkey ssh/${host} -r ${realm}
|
in map (service: "${service}/${hostname}.${toLower realm}@${realm}")
|
||||||
'';
|
host.kerberos-services;
|
||||||
|
|
||||||
initialize-db = realm: kdc-conf: user: group: key-file: db-name:
|
add-principal-str = kdc-conf: principal:
|
||||||
|
"${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- add --random-key --use-defaults ${principal}";
|
||||||
|
|
||||||
|
add-hosts-principals = realm: kdc-conf:
|
||||||
|
concatStringsSep "\n" (map (add-principal-str kdc-conf)
|
||||||
|
(concatMap (get-host-principals realm)
|
||||||
|
(get-domain-hosts (toLower realm))));
|
||||||
|
|
||||||
|
initialize-db =
|
||||||
|
realm: user: group: kdc-conf: key-file: db-name: max-lifetime: max-renewal: primary-keytab: kadmin-keytab: local-hostname:
|
||||||
pkgs.writeShellScript "initialize-kdc-db.sh" ''
|
pkgs.writeShellScript "initialize-kdc-db.sh" ''
|
||||||
if [ ! -e ${db-name} ]; then
|
if [ ! -e ${key-file} ]; then
|
||||||
KRB5_CONFIG=/etc/krb5.conf
|
${pkgs.heimdalFull}/bin/kstash --key-file=${key-file} --random-key
|
||||||
KRB5_KDC_PROFILE=${kdc-conf}
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- init --realm-max-ticket-life="${max-lifetime}" --realm-max-renewable-life="${max-renewal}" RUS.SELBY.CA
|
||||||
PWD=$(${pkgs.pwgen}/bin/pwgen 40 1)
|
${add-hosts-principals realm kdc-conf}
|
||||||
printf "$PWD\n$PWD\n$PWD\n" | ${pkgs.krb5}/bin/kdb5_util -r ${realm} -sf ${key-file} -d ${db-name} -m create -s
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- add --random-key --use-defaults kadmin/${local-hostname}@${realm}
|
||||||
${pkgs.coreutils}/bin/chown -R ${user}:${group} $(dirname ${db-name})
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${primary-keytab} */${local-hostname}@${realm}
|
||||||
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kadmin-keytab} kadmin/${local-hostname}@${realm}
|
||||||
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${key-file}
|
||||||
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${db-name}
|
||||||
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${iprop-log}
|
||||||
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${primary-keytab}
|
||||||
|
${pkgs.coreutils}/bin/chown ${user}:${group} ${kadmin-keytab}
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
|
|
||||||
initialize-kadmin = realm: db-name: user: group: kadmin-keytab: host:
|
generate-kdc-conf = realm: db-file: key-file: acl-file:
|
||||||
let
|
|
||||||
domain = toLower realm;
|
|
||||||
hosts = get-domain-hosts domain;
|
|
||||||
in pkgs.writeShellScript "initialize-kadmin.sh" ''
|
|
||||||
if [ ! -e ${kadmin-keytab} ]; then
|
|
||||||
# ${pkgs.krb5}/bin/kadmin.local -d ${db-name} addprinc -randkey kadmin/${host}.${domain}
|
|
||||||
# ${pkgs.krb5}/bin/kadmin.local -d ${db-name} ktadd -k ${kadmin-keytab} kadmin/${host}.${domain}
|
|
||||||
# TODO: extract kadmin keytab
|
|
||||||
# ${
|
|
||||||
concatStringsSep "\n" (map (add-host-principals realm db-name) hosts)
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
generate-kdc-conf =
|
|
||||||
realm: database: kdc-listen-addrs: kadmin-listen-addrs: kpasswd-listen-addrs: acl-file: kadmin-keytab: key-stash-file:
|
|
||||||
pkgs.writeText "kdc.conf" ''
|
pkgs.writeText "kdc.conf" ''
|
||||||
[kdcdefaults]
|
[kdc]
|
||||||
kdc_listen = ${concatStringsSep "," kdc-listen-addrs}
|
database = {
|
||||||
kdc_tcp_listen = ${concatStringsSep "," kdc-listen-addrs}
|
dbname = sqlite:${db-file}
|
||||||
|
realm = ${realm}
|
||||||
[realm]
|
mkey_file = ${key-file}
|
||||||
${realm} = {
|
|
||||||
kadmind_listen = ${concatStringsSep "," kadmin-listen-addrs}
|
|
||||||
kpasswd_listen = ${concatStringsSep "," kpasswd-listen-addrs}
|
|
||||||
max_life = 24h 0m 0s
|
|
||||||
max_renewable_life = 14d 0h 0m 0s
|
|
||||||
acl_file = ${acl-file}
|
acl_file = ${acl-file}
|
||||||
admin_keytab = ${kadmin-keytab}
|
log_file = ${iprop-log}
|
||||||
key_stash_file = ${key-stash-file}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[dbmodules]
|
[realms]
|
||||||
${realm} = {
|
${realm} = {
|
||||||
database_name = ${database}
|
enable-http = false
|
||||||
db_library = db2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[logging]
|
[logging]
|
||||||
kdc = SYSLOG
|
|
||||||
admin_server = SYSLOG
|
|
||||||
default = SYSLOG
|
default = SYSLOG
|
||||||
'';
|
'';
|
||||||
|
|
||||||
perm-map = {
|
|
||||||
"add" = "a";
|
|
||||||
"all" = "x";
|
|
||||||
"password" = "c";
|
|
||||||
"delete" = "d";
|
|
||||||
"inquire" = "i";
|
|
||||||
"list" = "l";
|
|
||||||
"modify" = "m";
|
|
||||||
"propagate" = "p";
|
|
||||||
"set-key" = "s";
|
|
||||||
};
|
|
||||||
|
|
||||||
perms-to-permstring = perms:
|
|
||||||
concatStringsSep "" (map (perm: perm-map.${perm}) perms);
|
|
||||||
|
|
||||||
aclEntry = { principal, ... }: {
|
aclEntry = { principal, ... }: {
|
||||||
options = with types; {
|
options = with types; {
|
||||||
perms = mkOption {
|
perms = let
|
||||||
type = listOf (enum (attrNames perm-map));
|
perms = [
|
||||||
|
"change-password"
|
||||||
|
"add"
|
||||||
|
"list"
|
||||||
|
"delete"
|
||||||
|
"modify"
|
||||||
|
"get"
|
||||||
|
"get-keys"
|
||||||
|
"all"
|
||||||
|
];
|
||||||
|
in mkOption {
|
||||||
|
type = listOf (enum perms);
|
||||||
description = "List of permissions.";
|
description = "List of permissions.";
|
||||||
default = [ ];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
@ -103,6 +93,8 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
perms-to-permstring = perms: concatStringsSep "," perms;
|
||||||
|
|
||||||
generate-acl-file = acl-entries:
|
generate-acl-file = acl-entries:
|
||||||
pkgs.writeText "kdc.acl" (concatStringsSep "\n" (mapAttrsToList
|
pkgs.writeText "kdc.acl" (concatStringsSep "\n" (mapAttrsToList
|
||||||
(principal: opts:
|
(principal: opts:
|
||||||
|
@ -110,15 +102,10 @@ let
|
||||||
optionalString (opts.target != null) " ${opts.target}"
|
optionalString (opts.target != null) " ${opts.target}"
|
||||||
}") acl-entries));
|
}") acl-entries));
|
||||||
|
|
||||||
acl-file = generate-acl-file cfg.acl;
|
kadmin-local = kdc-conf: kadmin-keytab:
|
||||||
|
pkgs.writeShellScriptBin "kadmin.local" ''
|
||||||
kdc-listen-addrs = map (ip: "${ip}:88") cfg.bind-addresses;
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} --keytab=${kadmin-keytab}
|
||||||
kadmin-listen-addrs = map (ip: "${ip}:749") cfg.bind-addresses;
|
'';
|
||||||
kpasswd-listen-addrs = map (ip: "${ip}:464") cfg.bind-addresses;
|
|
||||||
|
|
||||||
kdc-conf = generate-kdc-conf cfg.realm kerberos-database kdc-listen-addrs
|
|
||||||
kadmin-listen-addrs kpasswd-listen-addrs acl-file cfg.kadmin-keytab
|
|
||||||
cfg.master-key-file;
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
|
@ -170,18 +157,50 @@ in {
|
||||||
default = "/var/kerberos/master.key";
|
default = "/var/kerberos/master.key";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
primary-keytab = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Location of keytab for kadmind.";
|
||||||
|
default = "/var/kerberos/host.keytab";
|
||||||
|
};
|
||||||
|
|
||||||
kadmin-keytab = mkOption {
|
kadmin-keytab = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
description = "Location of keytab for kadmind.";
|
description = "Location of keytab for kadmind.";
|
||||||
default = "/var/kerberos/kadmind.keytab";
|
default = "/var/kerberos/kadmind.keytab";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kdc-internal-port = mkOption {
|
||||||
|
type = port;
|
||||||
|
description =
|
||||||
|
"Localhost port on which to listen for KDC traffic. Port 88 will be forwarded";
|
||||||
|
default = 4088;
|
||||||
|
};
|
||||||
|
|
||||||
|
k5login-directory = mkOption {
|
||||||
|
type = str;
|
||||||
|
description =
|
||||||
|
"Directory in which k5login files are stored for local users (equivalent to ~/.k5login).";
|
||||||
|
default = "/var/kerberos/k5login";
|
||||||
|
};
|
||||||
|
|
||||||
|
max-ticket-lifetime = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Maximum lifetime of a single ticket in this realm.";
|
||||||
|
default = "1d";
|
||||||
|
};
|
||||||
|
|
||||||
|
max-ticket-renewal = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Maximum time a ticket may be renewed in this realm.";
|
||||||
|
default = "7d";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
users = {
|
users = {
|
||||||
users.${cfg.user} = {
|
users.${cfg.user} = {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
home = "/var/heimdal";
|
home = "/var/kerberos";
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -189,26 +208,21 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
krb5 = {
|
krb5 = {
|
||||||
libdefaults = { default_realm = mkDefault cfg.realm; };
|
libdefaults = {
|
||||||
realms.${cfg.realm} = { key_stash_file = cfg.master-key-file; };
|
k5login_directory = cfg.k5login-directory;
|
||||||
extraConfig = mkAfter ''
|
ticket_lifetime = cfg.max-ticket-lifetime;
|
||||||
[dbmodules]
|
renew_lifetime = cfg.max-ticket-renewal;
|
||||||
${cfg.realm} = {
|
};
|
||||||
database_name = ${kerberos-database}
|
realms = { ${cfg.realm} = { enable-http = false; }; };
|
||||||
}
|
extraConfig = ''
|
||||||
|
default = SYSLOG
|
||||||
[realm]
|
|
||||||
${cfg.realm} = {
|
|
||||||
kadmind_listen = ${concatStringsSep "," kadmin-listen-addrs}
|
|
||||||
kpasswd_listen = ${concatStringsSep "," kpasswd-listen-addrs}
|
|
||||||
acl_file = ${acl-file}
|
|
||||||
admin_keytab = ${cfg.kadmin-keytab}
|
|
||||||
key_stash_file = ${cfg.master-key-file}
|
|
||||||
}
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
environment = { systemPackages = [ pkgs.kerberos pkgs.krb5 ]; };
|
environment = {
|
||||||
|
systemPackages =
|
||||||
|
[ pkgs.heimdalFull (kadmin-local kdc-conf cfg.kadmin-keytab) ];
|
||||||
|
};
|
||||||
|
|
||||||
fudo.system = {
|
fudo.system = {
|
||||||
ensure-directories = {
|
ensure-directories = {
|
||||||
|
@ -217,64 +231,79 @@ in {
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
perms = "0740";
|
perms = "0740";
|
||||||
};
|
};
|
||||||
"/run/mit-kdc" = {
|
};
|
||||||
user = cfg.user;
|
|
||||||
group = cfg.group;
|
internal-port-map = {
|
||||||
perms = "0744";
|
kdc = {
|
||||||
};
|
internal-port = cfg.kdc-internal-port;
|
||||||
"/run/mit-kadmin" = {
|
external-port = 88;
|
||||||
user = cfg.user;
|
protocols = [ "tcp" "udp" ];
|
||||||
group = cfg.group;
|
|
||||||
perms = "0744";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
mit-kdc = {
|
heimdal-kdc = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
type = "forking";
|
description =
|
||||||
description = "MIT Kerberos Key Distribution Center (ticket server).";
|
"Heimdal Kerberos Key Distribution Center (ticket server).";
|
||||||
execStart =
|
execStart =
|
||||||
"${pkgs.krb5}/bin/krb5kdc -r ${cfg.realm} -d ${kerberos-database} -P /run/mit-kdc/mit-kdc.pid";
|
"${pkgs.heimdalFull}/libexec/heimdal/kdc -c ${kdc-conf} --ports=${
|
||||||
readWritePaths = [ "/run/mit-kdc" ];
|
toString cfg.kdc-internal-port
|
||||||
environment = {
|
} --addresses=127.0.0.1";
|
||||||
KRB5_CONFIG = "/etc/krb5.conf";
|
environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
|
||||||
KRB5_KDC_PROFILE = "${kdc-conf}";
|
|
||||||
};
|
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
workingDirectory = cfg.state-directory;
|
workingDirectory = cfg.state-directory;
|
||||||
preStart = "${initialize-db cfg.realm kdc-conf cfg.user cfg.group
|
|
||||||
cfg.master-key-file kerberos-database}";
|
|
||||||
privateNetwork = false;
|
privateNetwork = false;
|
||||||
addressFamilies = [ "AF_INET" "AF_INET6" ];
|
addressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||||
requiredCapabilities = [ "CAP_NET_BIND_SERVICE+ep" ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mit-kadmin = {
|
heimdal-kdc-init = {
|
||||||
wantedBy = [ "multi-user.target" ];
|
requires = [ "heimdal-kdc.service" ];
|
||||||
after = [ "network.target" ];
|
description = "Initialization script for Heimdal KDC.";
|
||||||
requires = [ "mit-kdc.service" ];
|
type = "oneshot";
|
||||||
description = "MIT Kerberos Remote Administration Server.";
|
execStart = "${initialize-db cfg.realm cfg.user cfg.group kdc-conf
|
||||||
execStart =
|
cfg.master-key-file database-file cfg.max-ticket-lifetime
|
||||||
"${pkgs.krb5}/bin/kadmind -r ${cfg.realm} -P /run/mit-kadmin/mit-kadmin.pid";
|
cfg.max-ticket-renewal cfg.primary-keytab cfg.kadmin-keytab
|
||||||
readWritePaths = [ "/run/mit-kadmin" ];
|
"${config.networking.hostName}.${toLower cfg.realm}"}";
|
||||||
environment = {
|
|
||||||
KRB5_CONFIG = "/etc/krb5.conf";
|
|
||||||
KRB5_KDC_PROFILE = "${kdc-conf}";
|
|
||||||
};
|
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
workingDirectory = cfg.state-directory;
|
workingDirectory = cfg.state-directory;
|
||||||
privateNetwork = false;
|
environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
|
||||||
# postStart =
|
|
||||||
# "${initialize-kadmin cfg.realm kerberos-database cfg.user cfg.group
|
|
||||||
# cfg.kadmin-keytab config.networking.hostName}";
|
|
||||||
addressFamilies = [ "AF_INET" "AF_INET6" ];
|
|
||||||
requiredCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.rules = mkIf (cfg.primary-keytab != "/etc/krb5.keytab")
|
||||||
|
[ "L /etc/krb5.keytab - - - - ${cfg.primary-keytab}" ];
|
||||||
|
|
||||||
|
services.xinetd = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
services = [
|
||||||
|
{
|
||||||
|
name = "kerberos-adm";
|
||||||
|
user = cfg.user;
|
||||||
|
server = "${pkgs.heimdalFull}/libexec/heimdal/kadmind";
|
||||||
|
protocol = "tcp";
|
||||||
|
serverArgs =
|
||||||
|
"--config-file=${kdc-conf} --keytab=${cfg.kadmin-keytab}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "kpasswd";
|
||||||
|
user = cfg.user;
|
||||||
|
server = "${pkgs.heimdalFull}/libexec/heimdal/kpasswdd";
|
||||||
|
protocol = "udp";
|
||||||
|
serverArgs =
|
||||||
|
"--config-file=${kdc-conf} --keytab=${cfg.kadmin-keytab}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
allowedTCPPorts = [ 88 749 ];
|
||||||
|
allowedUDPPorts = [ 88 464 ];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,12 +260,12 @@ let
|
||||||
"A list of paths which should be inaccessible to the service.";
|
"A list of paths which should be inaccessible to the service.";
|
||||||
default = [ "/home" "/root" ];
|
default = [ "/home" "/root" ];
|
||||||
};
|
};
|
||||||
noExecPaths = mkOption {
|
# noExecPaths = mkOption {
|
||||||
type = listOf str;
|
# type = listOf str;
|
||||||
description =
|
# description =
|
||||||
"A list of paths where the service will not be allowed to run executables.";
|
# "A list of paths where the service will not be allowed to run executables.";
|
||||||
default = [ "/home" "/root" "/tmp" "/var" ];
|
# default = [ "/home" "/root" "/tmp" "/var" ];
|
||||||
};
|
# };
|
||||||
readOnlyPaths = mkOption {
|
readOnlyPaths = mkOption {
|
||||||
type = listOf str;
|
type = listOf str;
|
||||||
description =
|
description =
|
||||||
|
@ -390,11 +390,11 @@ let
|
||||||
type = port;
|
type = port;
|
||||||
description = "External port on which to listen for traffic.";
|
description = "External port on which to listen for traffic.";
|
||||||
};
|
};
|
||||||
protocol = mkOption {
|
protocols = mkOption {
|
||||||
type = nullOr str;
|
type = listOf str;
|
||||||
description =
|
description =
|
||||||
"Protocol for which to forward ports. Default is tcp & udp.";
|
"Protocols for which to forward ports. Default is tcp-only.";
|
||||||
default = null;
|
default = [ "tcp" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -464,15 +464,22 @@ in {
|
||||||
# opts.external-port) cfg.internal-port-map);
|
# opts.external-port) cfg.internal-port-map);
|
||||||
# };
|
# };
|
||||||
|
|
||||||
services.xinetd = {
|
services.xinetd = mkIf ((length (attrNames cfg.internal-port-map)) > 0) {
|
||||||
enable = true;
|
enable = true;
|
||||||
services = mapAttrsToList (name: opts: {
|
services = let
|
||||||
name = name;
|
svcs = mapAttrsToList (name: opts: opts // { name = name; })
|
||||||
|
cfg.internal-port-map;
|
||||||
|
svcs-protocols = concatMap
|
||||||
|
(svc: map (protocol: svc // { protocol = protocol; }) svc.protocols)
|
||||||
|
svcs;
|
||||||
|
in map (opts: {
|
||||||
|
name = opts.name;
|
||||||
unlisted = true;
|
unlisted = true;
|
||||||
port = opts.external-port;
|
port = opts.external-port;
|
||||||
server = "${pkgs.coreutils}/bin/false";
|
server = "${pkgs.coreutils}/bin/false";
|
||||||
extraConfig = "redirect = localhost ${toString opts.internal-port}";
|
extraConfig = "redirect = localhost ${toString opts.internal-port}";
|
||||||
}) cfg.internal-port-map;
|
protocol = opts.protocol;
|
||||||
|
}) svcs-protocols;
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.timers = mapAttrs (name: opts: {
|
systemd.timers = mapAttrs (name: opts: {
|
||||||
|
@ -559,7 +566,8 @@ in {
|
||||||
ReadWritePaths = opts.readWritePaths;
|
ReadWritePaths = opts.readWritePaths;
|
||||||
ReadOnlyPaths = opts.readOnlyPaths;
|
ReadOnlyPaths = opts.readOnlyPaths;
|
||||||
InaccessiblePaths = opts.inaccessiblePaths;
|
InaccessiblePaths = opts.inaccessiblePaths;
|
||||||
NoExecPaths = opts.noExecPaths;
|
# Apparently not supported yet?
|
||||||
|
# NoExecPaths = opts.noExecPaths;
|
||||||
ExecPaths = opts.execPaths;
|
ExecPaths = opts.execPaths;
|
||||||
};
|
};
|
||||||
}) config.fudo.system.services;
|
}) config.fudo.system.services;
|
||||||
|
|
Loading…
Reference in New Issue