Lots of updates
This commit is contained in:
parent
8d9f4e247d
commit
e2558f6f0f
|
@ -12,16 +12,16 @@ let
|
||||||
in {
|
in {
|
||||||
system = {
|
system = {
|
||||||
# Don't do unsupervised upgrades...
|
# Don't do unsupervised upgrades...
|
||||||
autoUpgrade.enable = mkForce false;
|
# autoUpgrade.enable = mkForce false;
|
||||||
|
|
||||||
# DO force all DNS traffic to use the local server
|
# # DO force all DNS traffic to use the local server
|
||||||
activationScripts.force-local-dns = let
|
# activationScripts.force-local-dns = let
|
||||||
wifi-ip =
|
# wifi-ip =
|
||||||
config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
|
# config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
|
||||||
in ''
|
# in ''
|
||||||
${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
|
# ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
|
||||||
${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
|
# ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
|
||||||
'';
|
# '';
|
||||||
};
|
};
|
||||||
|
|
||||||
fudo.local-network = let
|
fudo.local-network = let
|
||||||
|
@ -77,6 +77,11 @@ in {
|
||||||
enable = true;
|
enable = true;
|
||||||
externalInterface = "enp1s0";
|
externalInterface = "enp1s0";
|
||||||
internalInterfaces = [ "intif0" ];
|
internalInterfaces = [ "intif0" ];
|
||||||
|
forwardPorts = [{
|
||||||
|
destination = "127.0.0.1:53";
|
||||||
|
sourcePort = 53;
|
||||||
|
proto = "udp";
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,7 +94,7 @@ in {
|
||||||
auth.kdc = {
|
auth.kdc = {
|
||||||
enable = true;
|
enable = true;
|
||||||
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 = [ "add" "change-password" "list" ]; };
|
"niten" = { perms = [ "add" "change-password" "list" ]; };
|
||||||
"*/root" = { perms = [ "all" ]; };
|
"*/root" = { perms = [ "all" ]; };
|
||||||
|
|
|
@ -12,6 +12,8 @@ in {
|
||||||
|
|
||||||
boot.tmpOnTmpfs = true;
|
boot.tmpOnTmpfs = true;
|
||||||
|
|
||||||
|
system.autoUpgrade.enable = true;
|
||||||
|
|
||||||
services.xserver = mkIf enable-gui {
|
services.xserver = mkIf enable-gui {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
# Available to all users on the system. Keep it minimal.
|
# Available to all users on the system. Keep it minimal.
|
||||||
global-packages = with pkgs; [ bind git openssh_gssapi vim wget ];
|
global-packages = with pkgs; [ bind git heimdal openssh_gssapi vim wget ];
|
||||||
|
|
||||||
in {
|
in {
|
||||||
environment = {
|
environment = {
|
||||||
|
@ -20,8 +20,6 @@ in {
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
|
|
||||||
system.autoUpgrade.enable = true;
|
|
||||||
|
|
||||||
krb5 = {
|
krb5 = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
|
@ -59,6 +57,16 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lshd = {
|
||||||
|
enable = true;
|
||||||
|
portNumber = 2112;
|
||||||
|
rootLogin = true;
|
||||||
|
srpKeyExchange = true;
|
||||||
|
tcpForwarding = false;
|
||||||
|
publicKeyAuthentication = true;
|
||||||
|
passwordAuthentication = false;
|
||||||
|
};
|
||||||
|
|
||||||
fail2ban = {
|
fail2ban = {
|
||||||
enable = true;
|
enable = true;
|
||||||
bantime-increment.enable = true;
|
bantime-increment.enable = true;
|
||||||
|
@ -74,6 +82,14 @@ in {
|
||||||
# udev.packages = with pkgs; [ yubikey-personalization ];
|
# udev.packages = with pkgs; [ yubikey-personalization ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
networking.firewall = {
|
||||||
|
# Allow mosh connections if the firewall is enabled
|
||||||
|
allowedUDPPortRanges = [{
|
||||||
|
from = 60000;
|
||||||
|
to = 60100;
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
console.useXkbConfig = true;
|
console.useXkbConfig = true;
|
||||||
|
|
||||||
i18n.defaultLocale = "en_US.UTF-8";
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
|
@ -59,6 +59,8 @@ in {
|
||||||
# noXlibs = lib.mkForce true;
|
# noXlibs = lib.mkForce true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.autoUpgrade.enable = false;
|
||||||
|
|
||||||
security = { hideProcessInformation = true; };
|
security = { hideProcessInformation = true; };
|
||||||
|
|
||||||
networking.networkmanager.enable = mkForce false;
|
networking.networkmanager.enable = mkForce false;
|
||||||
|
|
|
@ -16,12 +16,13 @@
|
||||||
home-manager-config =
|
home-manager-config =
|
||||||
import ../home-manager/niten.nix { inherit config lib pkgs; };
|
import ../home-manager/niten.nix { inherit config lib pkgs; };
|
||||||
k5login = [
|
k5login = [
|
||||||
"niten@FUDO.ORG"
|
|
||||||
"niten/root@FUDO.ORG"
|
"niten/root@FUDO.ORG"
|
||||||
"niten/admin@FUDO.ORG"
|
"niten/admin@FUDO.ORG"
|
||||||
"niten@INFORMIS.LAND"
|
"niten@INFORMIS.LAND"
|
||||||
"niten/root@INFORMIS.LAND"
|
"niten/root@INFORMIS.LAND"
|
||||||
"niten/admin@INFORMIS.LAND"
|
"niten/admin@INFORMIS.LAND"
|
||||||
|
"niten@RUS.SELBY.CA"
|
||||||
|
"niten/root@RUS.SELBY.CA"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -88,14 +88,14 @@ in {
|
||||||
onChange = "${pkgs.doomEmacsInit}/bin/doom-emacs-init.sh";
|
onChange = "${pkgs.doomEmacsInit}/bin/doom-emacs-init.sh";
|
||||||
};
|
};
|
||||||
|
|
||||||
".k5login" = {
|
# ".k5login" = {
|
||||||
source = pkgs.writeText "niten-k5login" ''
|
# source = pkgs.writeText "niten-k5login" ''
|
||||||
niten@FUDO.ORG
|
# niten@FUDO.ORG
|
||||||
niten/root@FUDO.ORG
|
# niten/root@FUDO.ORG
|
||||||
niten@INFORMIS.LAND
|
# niten@INFORMIS.LAND
|
||||||
niten/root@INFORMIS.LAND
|
# niten/root@INFORMIS.LAND
|
||||||
'';
|
# '';
|
||||||
};
|
# };
|
||||||
};
|
};
|
||||||
|
|
||||||
sessionVariables = {
|
sessionVariables = {
|
||||||
|
|
|
@ -27,6 +27,7 @@ in {
|
||||||
source = pkgs.writeText "niten-k5login" ''
|
source = pkgs.writeText "niten-k5login" ''
|
||||||
niten/root@FUDO.ORG
|
niten/root@FUDO.ORG
|
||||||
niten/root@INFORMIS.LAND
|
niten/root@INFORMIS.LAND
|
||||||
|
reaper/root@FUDO.ORG
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,6 +36,7 @@ with lib; {
|
||||||
./fudo/sites.nix
|
./fudo/sites.nix
|
||||||
./fudo/slynk.nix
|
./fudo/slynk.nix
|
||||||
./fudo/system.nix
|
./fudo/system.nix
|
||||||
|
./fudo/system-networking.nix
|
||||||
./fudo/users.nix
|
./fudo/users.nix
|
||||||
./fudo/vpn.nix
|
./fudo/vpn.nix
|
||||||
./fudo/webmail.nix
|
./fudo/webmail.nix
|
||||||
|
|
|
@ -28,7 +28,7 @@ let
|
||||||
(get-domain-hosts (toLower realm))));
|
(get-domain-hosts (toLower realm))));
|
||||||
|
|
||||||
initialize-db =
|
initialize-db =
|
||||||
realm: user: group: kdc-conf: key-file: db-name: max-lifetime: max-renewal: primary-keytab: kadmin-keytab: local-hostname:
|
realm: user: group: kdc-conf: key-file: db-name: max-lifetime: max-renewal: primary-keytab: kadmin-keytab: kpasswd-keytab: local-hostname:
|
||||||
pkgs.writeShellScript "initialize-kdc-db.sh" ''
|
pkgs.writeShellScript "initialize-kdc-db.sh" ''
|
||||||
if [ ! -e ${key-file} ]; then
|
if [ ! -e ${key-file} ]; then
|
||||||
${pkgs.heimdalFull}/bin/kstash --key-file=${key-file} --random-key
|
${pkgs.heimdalFull}/bin/kstash --key-file=${key-file} --random-key
|
||||||
|
@ -36,6 +36,8 @@ let
|
||||||
${add-hosts-principals realm kdc-conf}
|
${add-hosts-principals realm kdc-conf}
|
||||||
${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=${primary-keytab} */${local-hostname}@${realm}
|
||||||
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kadmin-keytab} kadmin/admin@${realm}
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kadmin-keytab} kadmin/admin@${realm}
|
||||||
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kpasswd-keytab} kadmin/changepw@${realm}
|
||||||
|
${pkgs.heimdalFull}/bin/kadmin -l -c ${kdc-conf} -- ext_keytab --keytab=${kpasswd-keytab} kadmin/changepw@${realm}
|
||||||
#${pkgs.coreutils}/bin/chown ${user}:${group} ${key-file}
|
#${pkgs.coreutils}/bin/chown ${user}:${group} ${key-file}
|
||||||
#${pkgs.coreutils}/bin/chown ${user}:${group} ${db-name}
|
#${pkgs.coreutils}/bin/chown ${user}:${group} ${db-name}
|
||||||
#${pkgs.coreutils}/bin/chown ${user}:${group} ${iprop-log}
|
#${pkgs.coreutils}/bin/chown ${user}:${group} ${iprop-log}
|
||||||
|
@ -61,7 +63,8 @@ let
|
||||||
}
|
}
|
||||||
|
|
||||||
[logging]
|
[logging]
|
||||||
default = SYSLOG
|
kdc = FILE:/var/kerberos/kerberos.log
|
||||||
|
default = FILE:/var/kerberos/kerberos.log
|
||||||
'';
|
'';
|
||||||
|
|
||||||
aclEntry = { principal, ... }: {
|
aclEntry = { principal, ... }: {
|
||||||
|
@ -168,6 +171,12 @@ in {
|
||||||
default = "/var/kerberos/kadmind.keytab";
|
default = "/var/kerberos/kadmind.keytab";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kpasswdd-keytab = mkOption {
|
||||||
|
type = str;
|
||||||
|
description = "Location of keytab for kpasswdd.";
|
||||||
|
default = "/var/kerberos/kpasswdd.keytab";
|
||||||
|
};
|
||||||
|
|
||||||
kdc-internal-port = mkOption {
|
kdc-internal-port = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
description =
|
description =
|
||||||
|
@ -175,12 +184,12 @@ in {
|
||||||
default = 4088;
|
default = 4088;
|
||||||
};
|
};
|
||||||
|
|
||||||
k5login-directory = mkOption {
|
# k5login-directory = mkOption {
|
||||||
type = str;
|
# type = str;
|
||||||
description =
|
# description =
|
||||||
"Directory in which k5login files are stored for local users (equivalent to ~/.k5login).";
|
# "Directory in which k5login files are stored for local users (equivalent to ~/.k5login).";
|
||||||
default = "/var/kerberos/k5login";
|
# default = "/var/kerberos/k5login";
|
||||||
};
|
# };
|
||||||
|
|
||||||
max-ticket-lifetime = mkOption {
|
max-ticket-lifetime = mkOption {
|
||||||
type = str;
|
type = str;
|
||||||
|
@ -208,13 +217,14 @@ in {
|
||||||
|
|
||||||
krb5 = {
|
krb5 = {
|
||||||
libdefaults = {
|
libdefaults = {
|
||||||
k5login_directory = cfg.k5login-directory;
|
# Stick to ~/.k5login
|
||||||
|
# k5login_directory = cfg.k5login-directory;
|
||||||
ticket_lifetime = cfg.max-ticket-lifetime;
|
ticket_lifetime = cfg.max-ticket-lifetime;
|
||||||
renew_lifetime = cfg.max-ticket-renewal;
|
renew_lifetime = cfg.max-ticket-renewal;
|
||||||
};
|
};
|
||||||
realms = { ${cfg.realm} = { enable-http = false; }; };
|
realms = { ${cfg.realm} = { enable-http = false; }; };
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
default = SYSLOG
|
default = FILE:/var/kerberos/kerberos.log
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -232,42 +242,41 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
internal-port-map = {
|
|
||||||
kdc = {
|
|
||||||
internal-port = cfg.kdc-internal-port;
|
|
||||||
external-port = 88;
|
|
||||||
protocols = [ "tcp" "udp" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
heimdal-kdc = {
|
heimdal-kdc = let
|
||||||
|
listen-addrs = concatStringsSep " "
|
||||||
|
(map (addr: "--addresses=${addr}") cfg.bind-addresses);
|
||||||
|
command =
|
||||||
|
"${pkgs.heimdalFull}/libexec/heimdal/kdc -c ${kdc-conf} --ports=88 ${listen-addrs}";
|
||||||
|
in {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
after = [ "network.target" ];
|
after = [ "network.target" ];
|
||||||
description =
|
description =
|
||||||
"Heimdal Kerberos Key Distribution Center (ticket server).";
|
"Heimdal Kerberos Key Distribution Center (ticket server).";
|
||||||
execStart =
|
execStart = command;
|
||||||
"${pkgs.heimdalFull}/libexec/heimdal/kdc -c ${kdc-conf} --ports=${
|
|
||||||
toString cfg.kdc-internal-port
|
|
||||||
} --addresses=127.0.0.1";
|
|
||||||
environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
|
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
workingDirectory = cfg.state-directory;
|
workingDirectory = cfg.state-directory;
|
||||||
privateNetwork = false;
|
privateNetwork = false;
|
||||||
addressFamilies = [ "AF_INET" "AF_INET6" ];
|
addressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||||
|
requiredCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||||
|
environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
|
||||||
};
|
};
|
||||||
|
|
||||||
heimdal-kdc-init = {
|
heimdal-kdc-init = {
|
||||||
requires = [ "heimdal-kdc.service" ];
|
requires = [ "heimdal-kdc.service" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
description = "Initialization script for Heimdal KDC.";
|
description = "Initialization script for Heimdal KDC.";
|
||||||
type = "oneshot";
|
type = "oneshot";
|
||||||
execStart = "${initialize-db cfg.realm cfg.user cfg.group kdc-conf
|
execStart = "${initialize-db cfg.realm cfg.user cfg.group kdc-conf
|
||||||
cfg.master-key-file database-file cfg.max-ticket-lifetime
|
cfg.master-key-file database-file cfg.max-ticket-lifetime
|
||||||
cfg.max-ticket-renewal cfg.primary-keytab cfg.kadmin-keytab
|
cfg.max-ticket-renewal cfg.primary-keytab cfg.kadmin-keytab
|
||||||
|
cfg.kpasswdd-keytab
|
||||||
"${config.networking.hostName}.${toLower cfg.realm}"}";
|
"${config.networking.hostName}.${toLower cfg.realm}"}";
|
||||||
user = cfg.user;
|
user = cfg.user;
|
||||||
group = cfg.group;
|
group = cfg.group;
|
||||||
|
protectSystem = "full";
|
||||||
|
addressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||||
workingDirectory = cfg.state-directory;
|
workingDirectory = cfg.state-directory;
|
||||||
environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
|
environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
|
||||||
};
|
};
|
||||||
|
@ -295,7 +304,7 @@ in {
|
||||||
server = "${pkgs.heimdalFull}/libexec/heimdal/kpasswdd";
|
server = "${pkgs.heimdalFull}/libexec/heimdal/kpasswdd";
|
||||||
protocol = "udp";
|
protocol = "udp";
|
||||||
serverArgs =
|
serverArgs =
|
||||||
"--config-file=${kdc-conf} --keytab=${cfg.kadmin-keytab}";
|
"--config-file=${kdc-conf} --keytab=${cfg.kpasswdd-keytab}";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -308,10 +308,36 @@ in {
|
||||||
|
|
||||||
systemd.services.openldap = {
|
systemd.services.openldap = {
|
||||||
environment = { KRB5_KTNAME = cfg.kerberos-keytab; };
|
environment = { KRB5_KTNAME = cfg.kerberos-keytab; };
|
||||||
|
# FIXME: THIS IS ALL UNPROVEN
|
||||||
|
serviceConfig = {
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateMounts = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectSystem = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
KeyringMode = "private";
|
||||||
|
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||||
|
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
|
||||||
|
Restart = "on-failure";
|
||||||
|
LockPersonality = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
SystemCallFilter =
|
||||||
|
"~@clock @debug @module @mount @raw-io @reboot @swap @privileged @resources @cpu-emulation @obsolete";
|
||||||
|
UMask = "7007";
|
||||||
|
InaccessiblePaths = [ "/home" "/root" ];
|
||||||
|
LimitNOFILE = 49152;
|
||||||
|
PermissionsStartOnly = true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.openldap = {
|
services.openldap = {
|
||||||
|
|
||||||
enable = true;
|
enable = true;
|
||||||
suffix = cfg.base;
|
suffix = cfg.base;
|
||||||
rootdn = "cn=admin,${cfg.base}";
|
rootdn = "cn=admin,${cfg.base}";
|
||||||
|
|
|
@ -0,0 +1,158 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.fudo.system;
|
||||||
|
|
||||||
|
portMappingOpts = { name, ... }: {
|
||||||
|
options = with types; {
|
||||||
|
internal-port = mkOption {
|
||||||
|
type = port;
|
||||||
|
description = "Port on localhost to recieve traffic";
|
||||||
|
};
|
||||||
|
external-port = mkOption {
|
||||||
|
type = port;
|
||||||
|
description = "External port on which to listen for traffic.";
|
||||||
|
};
|
||||||
|
protocols = mkOption {
|
||||||
|
type = listOf str;
|
||||||
|
description =
|
||||||
|
"Protocols for which to forward ports. Default is tcp-only.";
|
||||||
|
default = [ "tcp" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
options.fudo.system = with types; {
|
||||||
|
internal-port-map = mkOption {
|
||||||
|
type = attrsOf (submodule portMappingOpts);
|
||||||
|
description =
|
||||||
|
"Sets of external ports to internal (i.e. localhost) ports to forward.";
|
||||||
|
default = { };
|
||||||
|
example = {
|
||||||
|
sshmap = {
|
||||||
|
internal-port = 2222;
|
||||||
|
external-port = 22;
|
||||||
|
protocol = "udp";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.internal-port-map != { }) {
|
||||||
|
# FIXME: FUCK ME THIS IS WAY HARDER THAN IT SHOULD BE
|
||||||
|
# boot.kernel.sysctl = mkIf (cfg.internal-port-map != { }) {
|
||||||
|
# "net.ipv4.conf.all.route_localnet" = "1";
|
||||||
|
# };
|
||||||
|
|
||||||
|
# fudo.system.services.forward-internal-ports = let
|
||||||
|
# ip-line = op: src-port: target-port: protocol: ''
|
||||||
|
# ${ipt} -t nat -${op} PREROUTING -p ${protocol} --dport ${
|
||||||
|
# toString src-port
|
||||||
|
# } -j REDIRECT --to-ports ${toString target-port}
|
||||||
|
# ${ipt} -t nat -${op} OUTPUT -p ${protocol} -s lo --dport ${
|
||||||
|
# toString src-port
|
||||||
|
# } -j REDIRECT --to-ports ${toString target-port}
|
||||||
|
# '';
|
||||||
|
|
||||||
|
# ip-forward-line = ip-line "I";
|
||||||
|
|
||||||
|
# ip-unforward-line = ip-line "D";
|
||||||
|
|
||||||
|
# traceOut = obj: builtins.trace obj obj;
|
||||||
|
|
||||||
|
# concatMapAttrsToList = f: attrs: concatLists (mapAttrsToList f attrs);
|
||||||
|
|
||||||
|
# portmap-entries = concatMapAttrsToList (name: opts:
|
||||||
|
# map (protocol: {
|
||||||
|
# src = opts.external-port;
|
||||||
|
# target = opts.internal-port;
|
||||||
|
# protocol = protocol;
|
||||||
|
# }) opts.protocols) cfg.internal-port-map;
|
||||||
|
|
||||||
|
# make-entries = f: { src, target, protocol, ... }: f src target protocol;
|
||||||
|
|
||||||
|
# forward-entries = map (make-entries ip-forward-line) portmap-entries;
|
||||||
|
|
||||||
|
# unforward-entries = map (make-entries ip-unforward-line) portmap-entries;
|
||||||
|
|
||||||
|
# forward-ports-script = pkgs.writeShellScript "forward-internal-ports.sh"
|
||||||
|
# (concatStringsSep "\n" forward-entries);
|
||||||
|
|
||||||
|
# unforward-ports-script =
|
||||||
|
# pkgs.writeShellScript "unforward-internal-ports.sh"
|
||||||
|
# (concatStringsSep "\n"
|
||||||
|
# (map (make-entries ip-unforward-line) portmap-entries));
|
||||||
|
# in {
|
||||||
|
# wantedBy = [ "multi-user.target" ];
|
||||||
|
# after = [ "firewall.service" "nat.service" ];
|
||||||
|
# type = "oneshot";
|
||||||
|
# description = "Rules for forwarding external ports to local ports.";
|
||||||
|
# execStart = "${forward-ports-script}";
|
||||||
|
# execStop = "${unforward-ports-script}";
|
||||||
|
# requiredCapabilities =
|
||||||
|
# [ "CAP_DAC_READ_SEARCH" "CAP_NET_ADMIN" "CAP_NET_RAW" ];
|
||||||
|
# };
|
||||||
|
|
||||||
|
# networking.firewall = let
|
||||||
|
# iptables = "ip46tables";
|
||||||
|
# ip-forward-line = protocols: internal: external:
|
||||||
|
# concatStringsSep "\n" (map (protocol: ''
|
||||||
|
# ${iptables} -t nat -I PREROUTING -p ${protocol} --dport ${
|
||||||
|
# toString external
|
||||||
|
# } -j REDIRECT --to-ports ${toString internal}
|
||||||
|
# ${iptables} -t nat -I OUTPUT -s lo -p ${protocol} --dport ${
|
||||||
|
# toString external
|
||||||
|
# } -j REDIRECT --to-ports ${toString internal}
|
||||||
|
# '') protocols);
|
||||||
|
|
||||||
|
# ip-unforward-line = protocols: internal: external:
|
||||||
|
# concatStringsSep "\n" (map (protocol: ''
|
||||||
|
# ${iptables} -t nat -D PREROUTING -p ${protocol} --dport ${
|
||||||
|
# toString external
|
||||||
|
# } -j REDIRECT --to-ports ${toString internal}
|
||||||
|
# ${iptables} -t nat -D OUTPUT -s lo -p ${protocol} --dport ${
|
||||||
|
# toString external
|
||||||
|
# } -j REDIRECT --to-ports ${toString internal}
|
||||||
|
# '') protocols);
|
||||||
|
# in {
|
||||||
|
# enable = true;
|
||||||
|
|
||||||
|
# extraCommands = concatStringsSep "\n" (mapAttrsToList (name: opts:
|
||||||
|
# ip-forward-line opts.protocols opts.internal-port opts.external-port)
|
||||||
|
# cfg.internal-port-map);
|
||||||
|
|
||||||
|
# extraStopCommands = concatStringsSep "\n" (mapAttrsToList (name: opts:
|
||||||
|
# ip-unforward-line opts.protocols opts.internal-port opts.external-port)
|
||||||
|
# cfg.internal-port-map);
|
||||||
|
# };
|
||||||
|
|
||||||
|
# networking.nat.forwardPorts =
|
||||||
|
# let portmaps = (attrValues opts.external-port);
|
||||||
|
# in concatMap (opts:
|
||||||
|
# map (protocol: {
|
||||||
|
# destination = "127.0.0.1:${toString opts.internal-port}";
|
||||||
|
# sourcePort = opts.external-port;
|
||||||
|
# proto = protocol;
|
||||||
|
# }) opts.protocols) (attrValues cfg.internal-port-map);
|
||||||
|
|
||||||
|
# services.xinetd = mkIf ((length (attrNames cfg.internal-port-map)) > 0) {
|
||||||
|
# enable = true;
|
||||||
|
# services = let
|
||||||
|
# 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;
|
||||||
|
# port = opts.external-port;
|
||||||
|
# server = "${pkgs.coreutils}/bin/false";
|
||||||
|
# extraConfig = "redirect = localhost ${toString opts.internal-port}";
|
||||||
|
# protocol = opts.protocol;
|
||||||
|
# }) svcs-protocols;
|
||||||
|
# };
|
||||||
|
};
|
||||||
|
}
|
|
@ -154,6 +154,11 @@ let
|
||||||
default = null;
|
default = null;
|
||||||
description = "Command to run to launch the service.";
|
description = "Command to run to launch the service.";
|
||||||
};
|
};
|
||||||
|
execStop = mkOption {
|
||||||
|
type = nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = "Command to run to launch the service.";
|
||||||
|
};
|
||||||
protectSystem = mkOption {
|
protectSystem = mkOption {
|
||||||
type = enum [ "true" "false" "full" "strict" true false ];
|
type = enum [ "true" "false" "full" "strict" true false ];
|
||||||
default = "full";
|
default = "full";
|
||||||
|
@ -355,10 +360,7 @@ let
|
||||||
concatStringsSep " " allowed;
|
concatStringsSep " " allowed;
|
||||||
|
|
||||||
restrict-address-families = allowed:
|
restrict-address-families = allowed:
|
||||||
if (allowed == [ ]) then
|
if (allowed == [ ]) then [ "~AF_INET" "~AF_INET6" ] else allowed;
|
||||||
"~${concatStringsSep " " address-families}"
|
|
||||||
else
|
|
||||||
concatStringsSep " " allowed;
|
|
||||||
|
|
||||||
dirOpts = { path, ... }: {
|
dirOpts = { path, ... }: {
|
||||||
options = with types; {
|
options = with types; {
|
||||||
|
@ -380,25 +382,6 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
portMappingOpts = { name, ... }: {
|
|
||||||
options = with types; {
|
|
||||||
internal-port = mkOption {
|
|
||||||
type = port;
|
|
||||||
description = "Port on localhost to recieve traffic";
|
|
||||||
};
|
|
||||||
external-port = mkOption {
|
|
||||||
type = port;
|
|
||||||
description = "External port on which to listen for traffic.";
|
|
||||||
};
|
|
||||||
protocols = mkOption {
|
|
||||||
type = listOf str;
|
|
||||||
description =
|
|
||||||
"Protocols for which to forward ports. Default is tcp-only.";
|
|
||||||
default = [ "tcp" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
options.fudo.system = with types; {
|
options.fudo.system = with types; {
|
||||||
services = mkOption {
|
services = mkOption {
|
||||||
|
@ -418,86 +401,9 @@ in {
|
||||||
description = "A map of required directories to directory properties.";
|
description = "A map of required directories to directory properties.";
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
|
|
||||||
internal-port-map = mkOption {
|
|
||||||
type = attrsOf (submodule portMappingOpts);
|
|
||||||
description =
|
|
||||||
"Sets of external ports to internal (i.e. localhost) ports to forward.";
|
|
||||||
default = { };
|
|
||||||
example = {
|
|
||||||
sshmap = {
|
|
||||||
internal-port = 2222;
|
|
||||||
external-port = 22;
|
|
||||||
protocol = "udp";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
boot.kernel.sysctl = mkIf (cfg.internal-port-map != { }) {
|
|
||||||
"net.ipv4.conf.all.route_localnet" = "1";
|
|
||||||
};
|
|
||||||
|
|
||||||
# networking.firewall = let
|
|
||||||
# iptables = "ip46tables";
|
|
||||||
# ip-forward-line = protocols: internal: external:
|
|
||||||
# concatStringsSep "\n" (map (protocol: ''
|
|
||||||
# ${iptables} -t nat -I PREROUTING -p ${protocol} --dport ${
|
|
||||||
# toString external
|
|
||||||
# } -j REDIRECT --to-ports ${toString internal}
|
|
||||||
# ${iptables} -t nat -I OUTPUT -s lo -p ${protocol} --dport ${
|
|
||||||
# toString external
|
|
||||||
# } -j REDIRECT --to-ports ${toString internal}
|
|
||||||
# '') protocols);
|
|
||||||
|
|
||||||
# ip-unforward-line = protocols: internal: external:
|
|
||||||
# concatStringsSep "\n" (map (protocol: ''
|
|
||||||
# ${iptables} -t nat -D PREROUTING -p ${protocol} --dport ${
|
|
||||||
# toString external
|
|
||||||
# } -j REDIRECT --to-ports ${toString internal}
|
|
||||||
# ${iptables} -t nat -D OUTPUT -s lo -p ${protocol} --dport ${
|
|
||||||
# toString external
|
|
||||||
# } -j REDIRECT --to-ports ${toString internal}
|
|
||||||
# '') protocols);
|
|
||||||
# in {
|
|
||||||
# enable = true;
|
|
||||||
|
|
||||||
# extraCommands = concatStringsSep "\n" (mapAttrsToList (name: opts:
|
|
||||||
# ip-forward-line opts.protocols opts.internal-port opts.external-port)
|
|
||||||
# cfg.internal-port-map);
|
|
||||||
|
|
||||||
# extraStopCommands = concatStringsSep "\n" (mapAttrsToList (name: opts:
|
|
||||||
# ip-unforward-line opts.protocols opts.internal-port opts.external-port)
|
|
||||||
# cfg.internal-port-map);
|
|
||||||
# };
|
|
||||||
|
|
||||||
networking.nat.forwardPorts =
|
|
||||||
let portmaps = (attrValues opts.external-port);
|
|
||||||
in concatMap (opts:
|
|
||||||
map (protocol: {
|
|
||||||
destination = "127.0.0.1:${toString opts.internal-port}";
|
|
||||||
sourcePort = opts.external-port;
|
|
||||||
proto = protocol;
|
|
||||||
}) opts.protocols) (attrValues cfg.internal-port-map);
|
|
||||||
|
|
||||||
# Services.xinetd = mkIf ((length (attrNames cfg.internal-port-map)) > 0) {
|
|
||||||
# enable = true;
|
|
||||||
# services = let
|
|
||||||
# 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;
|
|
||||||
# port = opts.external-port;
|
|
||||||
# server = "${pkgs.coreutils}/bin/false";
|
|
||||||
# extraConfig = "redirect = localhost ${toString opts.internal-port}";
|
|
||||||
# protocol = opts.protocol;
|
|
||||||
# }) svcs-protocols;
|
|
||||||
# };
|
|
||||||
|
|
||||||
systemd.timers = mapAttrs (name: opts: {
|
systemd.timers = mapAttrs (name: opts: {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -533,7 +439,7 @@ in {
|
||||||
path = opts.path;
|
path = opts.path;
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
PrivateNetwork = opts.privateNetwork;
|
PrivateNetwork = opts.privateNetwork;
|
||||||
PrivateUsers = opts.privateUsers;
|
PrivateUsers = mkIf (opts.user == null) opts.privateUsers;
|
||||||
PrivateDevices = opts.privateDevices;
|
PrivateDevices = opts.privateDevices;
|
||||||
PrivateTmp = opts.privateTmp;
|
PrivateTmp = opts.privateTmp;
|
||||||
PrivateMounts = opts.privateMounts;
|
PrivateMounts = opts.privateMounts;
|
||||||
|
@ -546,11 +452,12 @@ in {
|
||||||
ProtectClock = opts.protectClock;
|
ProtectClock = opts.protectClock;
|
||||||
ProtectKernelLogs = opts.protectKernelLogs;
|
ProtectKernelLogs = opts.protectKernelLogs;
|
||||||
KeyringMode = opts.keyringMode;
|
KeyringMode = opts.keyringMode;
|
||||||
EnvironmentFile = opts.environment-file;
|
EnvironmentFile =
|
||||||
|
mkIf (opts.environment-file != null) opts.environment-file;
|
||||||
|
|
||||||
# This is more complicated than it looks...
|
# This is more complicated than it looks...
|
||||||
CapabilityBoundingSet = restrict-capabilities opts.requiredCapabilities;
|
# CapabilityBoundingSet = restrict-capabilities opts.requiredCapabilities;
|
||||||
Capabilities = opts.requiredCapabilities;
|
AmbientCapabilities = concatStringsSep " " opts.requiredCapabilities;
|
||||||
SecureBits = mkIf ((length opts.requiredCapabilities) > 0) "keep-caps";
|
SecureBits = mkIf ((length opts.requiredCapabilities) > 0) "keep-caps";
|
||||||
|
|
||||||
DynamicUser = mkIf (opts.user == null) opts.dynamicUser;
|
DynamicUser = mkIf (opts.user == null) opts.dynamicUser;
|
||||||
|
@ -568,6 +475,7 @@ in {
|
||||||
LockPersonality = opts.lockPersonality;
|
LockPersonality = opts.lockPersonality;
|
||||||
RestrictRealtime = opts.restrictRealtime;
|
RestrictRealtime = opts.restrictRealtime;
|
||||||
ExecStart = mkIf (opts.execStart != null) opts.execStart;
|
ExecStart = mkIf (opts.execStart != null) opts.execStart;
|
||||||
|
ExecStop = mkIf (opts.execStop != null) opts.execStop;
|
||||||
MemoryDenyWriteExecute = opts.memoryDenyWriteExecute;
|
MemoryDenyWriteExecute = opts.memoryDenyWriteExecute;
|
||||||
SystemCallFilter = restrict-syscalls opts.allowedSyscalls;
|
SystemCallFilter = restrict-syscalls opts.allowedSyscalls;
|
||||||
UMask = opts.maximumUmask;
|
UMask = opts.maximumUmask;
|
||||||
|
|
|
@ -3,20 +3,20 @@
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
systemUserOpts = { username, ... }: {
|
systemUserOpts = { username, ... }: {
|
||||||
options = {
|
options = with types; {
|
||||||
username = mkOption {
|
username = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description = "The system user's login name.";
|
description = "The system user's login name.";
|
||||||
default = username;
|
default = username;
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description = "Description of this system user's purpose or role";
|
description = "Description of this system user's purpose or role";
|
||||||
};
|
};
|
||||||
|
|
||||||
ldap-hashed-password = mkOption {
|
ldap-hashed-password = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description =
|
description =
|
||||||
"LDAP-formatted hashed password for this user. Generate with slappasswd.";
|
"LDAP-formatted hashed password for this user. Generate with slappasswd.";
|
||||||
};
|
};
|
||||||
|
@ -24,67 +24,67 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
userOpts = { username, ... }: {
|
userOpts = { username, ... }: {
|
||||||
options = {
|
options = with types; {
|
||||||
username = mkOption {
|
username = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description = "The user's login name.";
|
description = "The user's login name.";
|
||||||
default = username;
|
default = username;
|
||||||
};
|
};
|
||||||
|
|
||||||
uid = mkOption {
|
uid = mkOption {
|
||||||
type = types.int;
|
type = int;
|
||||||
description = "Unique UID number for the user.";
|
description = "Unique UID number for the user.";
|
||||||
};
|
};
|
||||||
|
|
||||||
common-name = mkOption {
|
common-name = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description = "The user's common or given name.";
|
description = "The user's common or given name.";
|
||||||
};
|
};
|
||||||
|
|
||||||
primary-group = mkOption {
|
primary-group = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description = "Primary group to which the user belongs.";
|
description = "Primary group to which the user belongs.";
|
||||||
};
|
};
|
||||||
|
|
||||||
login-shell = mkOption {
|
login-shell = mkOption {
|
||||||
type = with types; nullOr shellPackage;
|
type = nullOr shellPackage;
|
||||||
description = "The user's preferred shell.";
|
description = "The user's preferred shell.";
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
default = "Fudo Member";
|
default = "Fudo Member";
|
||||||
description = "A description of this user's role.";
|
description = "A description of this user's role.";
|
||||||
};
|
};
|
||||||
|
|
||||||
ldap-hashed-passwd = mkOption {
|
ldap-hashed-passwd = mkOption {
|
||||||
type = with types; nullOr str;
|
type = nullOr str;
|
||||||
description =
|
description =
|
||||||
"LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password.";
|
"LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
login-hashed-passwd = mkOption {
|
login-hashed-passwd = mkOption {
|
||||||
type = with types; nullOr str;
|
type = nullOr str;
|
||||||
description =
|
description =
|
||||||
"Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password.";
|
"Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
ssh-authorized-keys = mkOption {
|
ssh-authorized-keys = mkOption {
|
||||||
type = with types; listOf str;
|
type = listOf str;
|
||||||
description = "SSH public keys this user can use to log in.";
|
description = "SSH public keys this user can use to log in.";
|
||||||
default = [ ];
|
default = [ ];
|
||||||
};
|
};
|
||||||
|
|
||||||
home-manager-config = mkOption {
|
home-manager-config = mkOption {
|
||||||
type = with types; nullOr attrs;
|
type = nullOr attrs;
|
||||||
description = "Home Manager configuration for the given user.";
|
description = "Home Manager configuration for the given user.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
home-directory = mkOption {
|
home-directory = mkOption {
|
||||||
type = with types; nullOr str;
|
type = nullOr str;
|
||||||
description = "Default home directory for the given user.";
|
description = "Default home directory for the given user.";
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
@ -98,26 +98,26 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
groupOpts = { group-name, ... }: {
|
groupOpts = { group-name, ... }: {
|
||||||
options = {
|
options = with types; {
|
||||||
group-name = mkOption {
|
group-name = mkOption {
|
||||||
type = with types; nullOr str;
|
type = nullOr str;
|
||||||
default = group-name;
|
default = group-name;
|
||||||
description = "Group name.";
|
description = "Group name.";
|
||||||
};
|
};
|
||||||
|
|
||||||
description = mkOption {
|
description = mkOption {
|
||||||
type = types.str;
|
type = str;
|
||||||
description = "Description of the group or it's purpose.";
|
description = "Description of the group or it's purpose.";
|
||||||
};
|
};
|
||||||
|
|
||||||
members = mkOption {
|
members = mkOption {
|
||||||
type = with types; listOf str;
|
type = listOf str;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
description = "A list of users who are members of the current group.";
|
description = "A list of users who are members of the current group.";
|
||||||
};
|
};
|
||||||
|
|
||||||
gid = mkOption {
|
gid = mkOption {
|
||||||
type = types.int;
|
type = int;
|
||||||
description = "GID number of the group.";
|
description = "GID number of the group.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -225,8 +225,15 @@ in {
|
||||||
home-manager-users =
|
home-manager-users =
|
||||||
filterAttrs (username: userOpts: userOpts.home-manager-config != null)
|
filterAttrs (username: userOpts: userOpts.home-manager-config != null)
|
||||||
local-users;
|
local-users;
|
||||||
|
common-user-config = username: {
|
||||||
in mapAttrs (username: userOpts: userOpts.home-manager-config)
|
home.file.".k5login" = {
|
||||||
|
source = pkgs.writeText "${username}-k5login" ''
|
||||||
|
${concatStringsSep "\n" config.fudo.users.${username}.k5login}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in mapAttrs (username: userOpts:
|
||||||
|
userOpts.home-manager-config // (common-user-config username))
|
||||||
home-manager-users;
|
home-manager-users;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue