Lots of updates
This commit is contained in:
		
							parent
							
								
									8d9f4e247d
								
							
						
					
					
						commit
						e2558f6f0f
					
				@ -12,16 +12,16 @@ let
 | 
			
		||||
in {
 | 
			
		||||
  system = {
 | 
			
		||||
    # Don't do unsupervised upgrades...
 | 
			
		||||
    autoUpgrade.enable = mkForce false;
 | 
			
		||||
    # autoUpgrade.enable = mkForce false;
 | 
			
		||||
 | 
			
		||||
    # DO force all DNS traffic to use the local server
 | 
			
		||||
    activationScripts.force-local-dns = let
 | 
			
		||||
      wifi-ip =
 | 
			
		||||
        config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
 | 
			
		||||
    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 tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
 | 
			
		||||
    '';
 | 
			
		||||
    # # DO force all DNS traffic to use the local server
 | 
			
		||||
    # activationScripts.force-local-dns = let
 | 
			
		||||
    #   wifi-ip =
 | 
			
		||||
    #     config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
 | 
			
		||||
    # 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 tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
 | 
			
		||||
    # '';
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fudo.local-network = let
 | 
			
		||||
@ -77,6 +77,11 @@ in {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      externalInterface = "enp1s0";
 | 
			
		||||
      internalInterfaces = [ "intif0" ];
 | 
			
		||||
      forwardPorts = [{
 | 
			
		||||
        destination = "127.0.0.1:53";
 | 
			
		||||
        sourcePort = 53;
 | 
			
		||||
        proto = "udp";
 | 
			
		||||
      }];
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@ -89,7 +94,7 @@ in {
 | 
			
		||||
    auth.kdc = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      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 = {
 | 
			
		||||
        "niten" = { perms = [ "add" "change-password" "list" ]; };
 | 
			
		||||
        "*/root" = { perms = [ "all" ]; };
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,8 @@ in {
 | 
			
		||||
 | 
			
		||||
  boot.tmpOnTmpfs = true;
 | 
			
		||||
 | 
			
		||||
  system.autoUpgrade.enable = true;
 | 
			
		||||
 | 
			
		||||
  services.xserver = mkIf enable-gui {
 | 
			
		||||
    enable = true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,7 @@
 | 
			
		||||
with lib;
 | 
			
		||||
let
 | 
			
		||||
  # 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 {
 | 
			
		||||
  environment = {
 | 
			
		||||
@ -20,8 +20,6 @@ in {
 | 
			
		||||
  nixpkgs.config.allowUnfree = true;
 | 
			
		||||
  security.acme.acceptTerms = true;
 | 
			
		||||
 | 
			
		||||
  system.autoUpgrade.enable = true;
 | 
			
		||||
 | 
			
		||||
  krb5 = {
 | 
			
		||||
    enable = true;
 | 
			
		||||
 | 
			
		||||
@ -59,6 +57,16 @@ in {
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    lshd = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      portNumber = 2112;
 | 
			
		||||
      rootLogin = true;
 | 
			
		||||
      srpKeyExchange = true;
 | 
			
		||||
      tcpForwarding = false;
 | 
			
		||||
      publicKeyAuthentication = true;
 | 
			
		||||
      passwordAuthentication = false;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    fail2ban = {
 | 
			
		||||
      enable = true;
 | 
			
		||||
      bantime-increment.enable = true;
 | 
			
		||||
@ -74,6 +82,14 @@ in {
 | 
			
		||||
    # udev.packages = with pkgs; [ yubikey-personalization ];
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  networking.firewall = {
 | 
			
		||||
    # Allow mosh connections if the firewall is enabled
 | 
			
		||||
    allowedUDPPortRanges = [{
 | 
			
		||||
      from = 60000;
 | 
			
		||||
      to = 60100;
 | 
			
		||||
    }];
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  console.useXkbConfig = true;
 | 
			
		||||
 | 
			
		||||
  i18n.defaultLocale = "en_US.UTF-8";
 | 
			
		||||
 | 
			
		||||
@ -59,6 +59,8 @@ in {
 | 
			
		||||
      # noXlibs = lib.mkForce true;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    system.autoUpgrade.enable = false;
 | 
			
		||||
 | 
			
		||||
    security = { hideProcessInformation = true; };
 | 
			
		||||
 | 
			
		||||
    networking.networkmanager.enable = mkForce false;
 | 
			
		||||
 | 
			
		||||
@ -16,12 +16,13 @@
 | 
			
		||||
      home-manager-config =
 | 
			
		||||
        import ../home-manager/niten.nix { inherit config lib pkgs; };
 | 
			
		||||
      k5login = [
 | 
			
		||||
        "niten@FUDO.ORG"
 | 
			
		||||
        "niten/root@FUDO.ORG"
 | 
			
		||||
        "niten/admin@FUDO.ORG"
 | 
			
		||||
        "niten@INFORMIS.LAND"
 | 
			
		||||
        "niten/root@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";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ".k5login" = {
 | 
			
		||||
        source = pkgs.writeText "niten-k5login" ''
 | 
			
		||||
          niten@FUDO.ORG
 | 
			
		||||
          niten/root@FUDO.ORG
 | 
			
		||||
          niten@INFORMIS.LAND
 | 
			
		||||
          niten/root@INFORMIS.LAND
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
      # ".k5login" = {
 | 
			
		||||
      #   source = pkgs.writeText "niten-k5login" ''
 | 
			
		||||
      #     niten@FUDO.ORG
 | 
			
		||||
      #     niten/root@FUDO.ORG
 | 
			
		||||
      #     niten@INFORMIS.LAND
 | 
			
		||||
      #     niten/root@INFORMIS.LAND
 | 
			
		||||
      #   '';
 | 
			
		||||
      # };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    sessionVariables = {
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ in {
 | 
			
		||||
        source = pkgs.writeText "niten-k5login" ''
 | 
			
		||||
          niten/root@FUDO.ORG
 | 
			
		||||
          niten/root@INFORMIS.LAND
 | 
			
		||||
          reaper/root@FUDO.ORG
 | 
			
		||||
        '';
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,7 @@ with lib; {
 | 
			
		||||
    ./fudo/sites.nix
 | 
			
		||||
    ./fudo/slynk.nix
 | 
			
		||||
    ./fudo/system.nix
 | 
			
		||||
    ./fudo/system-networking.nix
 | 
			
		||||
    ./fudo/users.nix
 | 
			
		||||
    ./fudo/vpn.nix
 | 
			
		||||
    ./fudo/webmail.nix
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ let
 | 
			
		||||
        (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:
 | 
			
		||||
    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" ''
 | 
			
		||||
      if [ ! -e ${key-file} ]; then
 | 
			
		||||
        ${pkgs.heimdalFull}/bin/kstash --key-file=${key-file} --random-key
 | 
			
		||||
@ -36,6 +36,8 @@ let
 | 
			
		||||
        ${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=${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} ${db-name}
 | 
			
		||||
        #${pkgs.coreutils}/bin/chown ${user}:${group} ${iprop-log}
 | 
			
		||||
@ -61,7 +63,8 @@ let
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      [logging]
 | 
			
		||||
        default = SYSLOG
 | 
			
		||||
        kdc = FILE:/var/kerberos/kerberos.log
 | 
			
		||||
        default = FILE:/var/kerberos/kerberos.log
 | 
			
		||||
    '';
 | 
			
		||||
 | 
			
		||||
  aclEntry = { principal, ... }: {
 | 
			
		||||
@ -168,6 +171,12 @@ in {
 | 
			
		||||
      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 {
 | 
			
		||||
      type = port;
 | 
			
		||||
      description =
 | 
			
		||||
@ -175,12 +184,12 @@ in {
 | 
			
		||||
      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";
 | 
			
		||||
    };
 | 
			
		||||
    # 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;
 | 
			
		||||
@ -208,13 +217,14 @@ in {
 | 
			
		||||
 | 
			
		||||
    krb5 = {
 | 
			
		||||
      libdefaults = {
 | 
			
		||||
        k5login_directory = cfg.k5login-directory;
 | 
			
		||||
        # Stick to ~/.k5login
 | 
			
		||||
        # k5login_directory = cfg.k5login-directory;
 | 
			
		||||
        ticket_lifetime = cfg.max-ticket-lifetime;
 | 
			
		||||
        renew_lifetime = cfg.max-ticket-renewal;
 | 
			
		||||
      };
 | 
			
		||||
      realms = { ${cfg.realm} = { enable-http = false; }; };
 | 
			
		||||
      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 = {
 | 
			
		||||
        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" ];
 | 
			
		||||
          after = [ "network.target" ];
 | 
			
		||||
          description =
 | 
			
		||||
            "Heimdal Kerberos Key Distribution Center (ticket server).";
 | 
			
		||||
          execStart =
 | 
			
		||||
            "${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"; };
 | 
			
		||||
          execStart = command;
 | 
			
		||||
          user = cfg.user;
 | 
			
		||||
          group = cfg.group;
 | 
			
		||||
          workingDirectory = cfg.state-directory;
 | 
			
		||||
          privateNetwork = false;
 | 
			
		||||
          addressFamilies = [ "AF_INET" "AF_INET6" ];
 | 
			
		||||
          requiredCapabilities = [ "CAP_NET_BIND_SERVICE" ];
 | 
			
		||||
          environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        heimdal-kdc-init = {
 | 
			
		||||
          requires = [ "heimdal-kdc.service" ];
 | 
			
		||||
          wantedBy = [ "multi-user.target" ];
 | 
			
		||||
          description = "Initialization script for Heimdal KDC.";
 | 
			
		||||
          type = "oneshot";
 | 
			
		||||
          execStart = "${initialize-db cfg.realm cfg.user cfg.group kdc-conf
 | 
			
		||||
            cfg.master-key-file database-file cfg.max-ticket-lifetime
 | 
			
		||||
            cfg.max-ticket-renewal cfg.primary-keytab cfg.kadmin-keytab
 | 
			
		||||
            cfg.kpasswdd-keytab
 | 
			
		||||
            "${config.networking.hostName}.${toLower cfg.realm}"}";
 | 
			
		||||
          user = cfg.user;
 | 
			
		||||
          group = cfg.group;
 | 
			
		||||
          protectSystem = "full";
 | 
			
		||||
          addressFamilies = [ "AF_INET" "AF_INET6" ];
 | 
			
		||||
          workingDirectory = cfg.state-directory;
 | 
			
		||||
          environment = { KRB5_CONFIG = "/etc/krb5.conf"; };
 | 
			
		||||
        };
 | 
			
		||||
@ -295,7 +304,7 @@ in {
 | 
			
		||||
          server = "${pkgs.heimdalFull}/libexec/heimdal/kpasswdd";
 | 
			
		||||
          protocol = "udp";
 | 
			
		||||
          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 = {
 | 
			
		||||
      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 = {
 | 
			
		||||
 | 
			
		||||
      enable = true;
 | 
			
		||||
      suffix = cfg.base;
 | 
			
		||||
      rootdn = "cn=admin,${cfg.base}";
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										158
									
								
								lib/fudo/system-networking.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								lib/fudo/system-networking.nix
									
									
									
									
									
										Normal file
									
								
							@ -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;
 | 
			
		||||
          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 {
 | 
			
		||||
          type = enum [ "true" "false" "full" "strict" true false ];
 | 
			
		||||
          default = "full";
 | 
			
		||||
@ -355,10 +360,7 @@ let
 | 
			
		||||
      concatStringsSep " " allowed;
 | 
			
		||||
 | 
			
		||||
  restrict-address-families = allowed:
 | 
			
		||||
    if (allowed == [ ]) then
 | 
			
		||||
      "~${concatStringsSep " " address-families}"
 | 
			
		||||
    else
 | 
			
		||||
      concatStringsSep " " allowed;
 | 
			
		||||
    if (allowed == [ ]) then [ "~AF_INET" "~AF_INET6" ] else allowed;
 | 
			
		||||
 | 
			
		||||
  dirOpts = { path, ... }: {
 | 
			
		||||
    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 {
 | 
			
		||||
  options.fudo.system = with types; {
 | 
			
		||||
    services = mkOption {
 | 
			
		||||
@ -418,86 +401,9 @@ in {
 | 
			
		||||
      description = "A map of required directories to directory properties.";
 | 
			
		||||
      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 = {
 | 
			
		||||
    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: {
 | 
			
		||||
      enable = true;
 | 
			
		||||
@ -533,7 +439,7 @@ in {
 | 
			
		||||
      path = opts.path;
 | 
			
		||||
      serviceConfig = {
 | 
			
		||||
        PrivateNetwork = opts.privateNetwork;
 | 
			
		||||
        PrivateUsers = opts.privateUsers;
 | 
			
		||||
        PrivateUsers = mkIf (opts.user == null) opts.privateUsers;
 | 
			
		||||
        PrivateDevices = opts.privateDevices;
 | 
			
		||||
        PrivateTmp = opts.privateTmp;
 | 
			
		||||
        PrivateMounts = opts.privateMounts;
 | 
			
		||||
@ -546,11 +452,12 @@ in {
 | 
			
		||||
        ProtectClock = opts.protectClock;
 | 
			
		||||
        ProtectKernelLogs = opts.protectKernelLogs;
 | 
			
		||||
        KeyringMode = opts.keyringMode;
 | 
			
		||||
        EnvironmentFile = opts.environment-file;
 | 
			
		||||
        EnvironmentFile =
 | 
			
		||||
          mkIf (opts.environment-file != null) opts.environment-file;
 | 
			
		||||
 | 
			
		||||
        # This  is more complicated than it looks...
 | 
			
		||||
        CapabilityBoundingSet = restrict-capabilities opts.requiredCapabilities;
 | 
			
		||||
        Capabilities = opts.requiredCapabilities;
 | 
			
		||||
        # CapabilityBoundingSet = restrict-capabilities opts.requiredCapabilities;
 | 
			
		||||
        AmbientCapabilities = concatStringsSep " " opts.requiredCapabilities;
 | 
			
		||||
        SecureBits = mkIf ((length opts.requiredCapabilities) > 0) "keep-caps";
 | 
			
		||||
 | 
			
		||||
        DynamicUser = mkIf (opts.user == null) opts.dynamicUser;
 | 
			
		||||
@ -568,6 +475,7 @@ in {
 | 
			
		||||
        LockPersonality = opts.lockPersonality;
 | 
			
		||||
        RestrictRealtime = opts.restrictRealtime;
 | 
			
		||||
        ExecStart = mkIf (opts.execStart != null) opts.execStart;
 | 
			
		||||
        ExecStop = mkIf (opts.execStop != null) opts.execStop;
 | 
			
		||||
        MemoryDenyWriteExecute = opts.memoryDenyWriteExecute;
 | 
			
		||||
        SystemCallFilter = restrict-syscalls opts.allowedSyscalls;
 | 
			
		||||
        UMask = opts.maximumUmask;
 | 
			
		||||
 | 
			
		||||
@ -3,20 +3,20 @@
 | 
			
		||||
with lib;
 | 
			
		||||
let
 | 
			
		||||
  systemUserOpts = { username, ... }: {
 | 
			
		||||
    options = {
 | 
			
		||||
    options = with types; {
 | 
			
		||||
      username = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description = "The system user's login name.";
 | 
			
		||||
        default = username;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      description = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description = "Description of this system user's purpose or role";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ldap-hashed-password = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description =
 | 
			
		||||
          "LDAP-formatted hashed password for this user. Generate with slappasswd.";
 | 
			
		||||
      };
 | 
			
		||||
@ -24,67 +24,67 @@ let
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  userOpts = { username, ... }: {
 | 
			
		||||
    options = {
 | 
			
		||||
    options = with types; {
 | 
			
		||||
      username = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description = "The user's login name.";
 | 
			
		||||
        default = username;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      uid = mkOption {
 | 
			
		||||
        type = types.int;
 | 
			
		||||
        type = int;
 | 
			
		||||
        description = "Unique UID number for the user.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      common-name = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description = "The user's common or given name.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      primary-group = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description = "Primary group to which the user belongs.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      login-shell = mkOption {
 | 
			
		||||
        type = with types; nullOr shellPackage;
 | 
			
		||||
        type = nullOr shellPackage;
 | 
			
		||||
        description = "The user's preferred shell.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      description = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        default = "Fudo Member";
 | 
			
		||||
        description = "A description of this user's role.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ldap-hashed-passwd = mkOption {
 | 
			
		||||
        type = with types; nullOr str;
 | 
			
		||||
        type = nullOr str;
 | 
			
		||||
        description =
 | 
			
		||||
          "LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password.";
 | 
			
		||||
        default = null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      login-hashed-passwd = mkOption {
 | 
			
		||||
        type = with types; nullOr str;
 | 
			
		||||
        type = nullOr str;
 | 
			
		||||
        description =
 | 
			
		||||
          "Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password.";
 | 
			
		||||
        default = null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      ssh-authorized-keys = mkOption {
 | 
			
		||||
        type = with types; listOf str;
 | 
			
		||||
        type = listOf str;
 | 
			
		||||
        description = "SSH public keys this user can use to log in.";
 | 
			
		||||
        default = [ ];
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      home-manager-config = mkOption {
 | 
			
		||||
        type = with types; nullOr attrs;
 | 
			
		||||
        type = nullOr attrs;
 | 
			
		||||
        description = "Home Manager configuration for the given user.";
 | 
			
		||||
        default = null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      home-directory = mkOption {
 | 
			
		||||
        type = with types; nullOr str;
 | 
			
		||||
        type = nullOr str;
 | 
			
		||||
        description = "Default home directory for the given user.";
 | 
			
		||||
        default = null;
 | 
			
		||||
      };
 | 
			
		||||
@ -98,26 +98,26 @@ let
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  groupOpts = { group-name, ... }: {
 | 
			
		||||
    options = {
 | 
			
		||||
    options = with types; {
 | 
			
		||||
      group-name = mkOption {
 | 
			
		||||
        type = with types; nullOr str;
 | 
			
		||||
        type = nullOr str;
 | 
			
		||||
        default = group-name;
 | 
			
		||||
        description = "Group name.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      description = mkOption {
 | 
			
		||||
        type = types.str;
 | 
			
		||||
        type = str;
 | 
			
		||||
        description = "Description of the group or it's purpose.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      members = mkOption {
 | 
			
		||||
        type = with types; listOf str;
 | 
			
		||||
        type = listOf str;
 | 
			
		||||
        default = [ ];
 | 
			
		||||
        description = "A list of users who are members of the current group.";
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      gid = mkOption {
 | 
			
		||||
        type = types.int;
 | 
			
		||||
        type = int;
 | 
			
		||||
        description = "GID number of the group.";
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
@ -225,8 +225,15 @@ in {
 | 
			
		||||
      home-manager-users =
 | 
			
		||||
        filterAttrs (username: userOpts: userOpts.home-manager-config != null)
 | 
			
		||||
        local-users;
 | 
			
		||||
 | 
			
		||||
    in mapAttrs (username: userOpts: userOpts.home-manager-config)
 | 
			
		||||
      common-user-config = username: {
 | 
			
		||||
        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;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user