summaryrefslogtreecommitdiff
path: root/sys/auth
diff options
context:
space:
mode:
Diffstat (limited to 'sys/auth')
-rw-r--r--sys/auth/default.nix7
-rw-r--r--sys/auth/login.nix22
-rw-r--r--sys/auth/oath.nix38
-rw-r--r--sys/auth/openssh.nix193
-rw-r--r--sys/auth/ssh-key.pub1
5 files changed, 261 insertions, 0 deletions
diff --git a/sys/auth/default.nix b/sys/auth/default.nix
new file mode 100644
index 0000000..ca2778a
--- /dev/null
+++ b/sys/auth/default.nix
@@ -0,0 +1,7 @@
+{
+ imports = [
+ ./login.nix
+ ./oath.nix
+ ./openssh.nix
+ ];
+}
diff --git a/sys/auth/login.nix b/sys/auth/login.nix
new file mode 100644
index 0000000..f252c1c
--- /dev/null
+++ b/sys/auth/login.nix
@@ -0,0 +1,22 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; {
+ # TODO
+ config = mkIf true {
+ security.pam = {
+ # TODO: altamente inseguro, ver problema con ~/.ssh/authorized_keys
+ # si es editado por un proceso malicioso
+ rssh = {
+ enable = true;
+
+ settings = {
+ cue = true;
+ };
+ };
+ };
+ };
+}
diff --git a/sys/auth/oath.nix b/sys/auth/oath.nix
new file mode 100644
index 0000000..6b00680
--- /dev/null
+++ b/sys/auth/oath.nix
@@ -0,0 +1,38 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.local.auth.oath;
+in {
+ options.local.auth.oath = {
+ enable = lib.mkEnableOption "pam-oath";
+ };
+
+ config = lib.mkIf cfg.enable {
+ security.pam = {
+ oath = {
+ digits = 6;
+ window = 30;
+
+ usersFile = "/var/trust/auth/users.oath";
+ };
+
+ services.sshd.oathAuth = true;
+ };
+
+ users.users.tunnel = {
+ uid = 1100;
+ group = "nogroup";
+ isSystemUser = true;
+
+ # Requiere oath
+ password = "tunnel";
+
+ home = "/var/empty";
+ shell = "${pkgs.coreutils}/bin/true";
+ };
+ };
+}
diff --git a/sys/auth/openssh.nix b/sys/auth/openssh.nix
new file mode 100644
index 0000000..44fb49a
--- /dev/null
+++ b/sys/auth/openssh.nix
@@ -0,0 +1,193 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+with lib; let
+ cfg = config.local.auth.openssh;
+ withOath = config.local.auth.oath.enable;
+ withPassword = config.local.auth.openssh.passwordAuthentication;
+
+ port =
+ if cfg.shiftPortNumber
+ then 2234
+ else 22;
+ restrict = cfg.restrictListen;
+
+ exemptList = optionals config.local.net.fail2ban.enable config.services.fail2ban.ignoreIP;
+in {
+ options.local.auth.openssh = {
+ enable = mkEnableOption "openssh";
+ tunnel.enable = mkEnableOption "ssh tunnel user";
+
+ #TODO: Desfasar ecdsa, inseguro
+ hostKeys = listToAttrs (map
+ (name: {
+ inherit name;
+
+ value = mkOption {
+ type = types.bool;
+ default = false;
+ };
+ }) ["ecdsa" "ed25519" "rsa"]);
+
+ restrictListen = mkOption {
+ default = null;
+
+ type = with types;
+ nullOr (submodule {
+ options = {
+ addresses = mkOption {
+ type = listOf str;
+ };
+
+ interface = mkOption {
+ type = nullOr str;
+ default = null;
+ };
+
+ vsockCid = mkOption {
+ type = nullOr ints.u32;
+ default = null;
+ };
+ };
+ });
+ };
+
+ passwordAuthentication = mkOption {
+ type = types.bool;
+ default = false;
+ };
+
+ shiftPortNumber = mkOption {
+ type = types.bool;
+ default = true;
+ };
+
+ withDeployKeys = mkOption {
+ type = types.bool;
+ default = false;
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = cfg.tunnel.enable -> withOath;
+ message = "SSH tunnel requires oath";
+ }
+ {
+ assertion = restrict != null -> (restrict.vsockCid != null -> (restrict.interface == null && restrict.addresses == []));
+ message = "SSH vsock restrict requires disabling inet";
+ }
+ {
+ assertion = restrict != null -> (restrict.vsockCid != null -> config.services.openssh.startWhenNeeded);
+ message = "SSH vsock restrict requires socket activation";
+ }
+ {
+ assertion = restrict != null -> (restrict.vsockCid != null -> config.local.virt.enable);
+ message = "SSH vsock restrict requires nixvirt";
+ }
+ {
+ assertion = any (key: key) (attrValues cfg.hostKeys);
+ message = "No OpenSSH host keys were enabled";
+ }
+ ];
+
+ local.boot.impermanence.files =
+ flatten (map (key: [key.path "${key.path}.pub"]) config.services.openssh.hostKeys);
+
+ networking.firewall = {
+ interfaces = optionalAttrs (restrict != null && restrict.interface != null) {
+ ${restrict.interface}.allowedTCPPorts = [port];
+ };
+
+ allowedTCPPorts = optional (restrict == null || restrict.interface == null) port;
+ };
+
+ services.openssh = {
+ enable = true;
+
+ ports = optional (restrict != null -> restrict.addresses != []) port;
+ startWhenNeeded = mkDefault (!config.services.fail2ban.enable);
+
+ extraConfig =
+ optionalString (exemptList != []) ''
+ PerSourcePenaltyExemptList ${concatStringsSep "," exemptList}
+ ''
+ + optionalString cfg.tunnel.enable ''
+ # User 'tunnel' has no password. Use PAM OATH
+ # and connect with -N, forward with -R.
+ Match User tunnel
+ AllowTcpForwarding remote
+ AllowStreamLocalForwarding no
+ X11Forwarding no
+ PermitTunnel no
+ GatewayPorts no
+ AllowAgentForwarding no
+ PermitOpen none
+ PermitListen 60220 60221 60222 60223 60224 60225 60226 60227 60228 60229
+
+ Banner ${pkgs.writeText "tunnel-banner" ''
+ This is a reverse tunnel
+ ''}
+ '';
+
+ hostKeys =
+ map
+ (name:
+ {
+ path = "/etc/ssh/ssh_host_${name}_key";
+ type = name;
+ }
+ // optionalAttrs (name == "rsa") {
+ bits = 4096;
+ })
+ (attrNames (filterAttrs (name: enable: enable) cfg.hostKeys));
+
+ settings = {
+ X11Forwarding = config.local.seat.enable && config.local.seat.graphical;
+ PermitRootLogin = "prohibit-password";
+ PasswordAuthentication = withOath || withPassword; # Necesario para oath, no reemplaza a oath
+ };
+
+ listenAddresses =
+ mkIf (restrict != null)
+ (map (addr: {inherit addr;}) restrict.addresses);
+ };
+
+ systemd.sockets = mkIf (restrict != null && restrict.vsockCid != null) {
+ sshd = let
+ kernelMod = "modprobe@${
+ if restrict.vsockCid == 2
+ then "vhost_"
+ else ""
+ }vsock.service";
+ in {
+ after = [kernelMod];
+ wants = [kernelMod];
+
+ socketConfig.ListenStream = mkForce ["vsock:${toString restrict.vsockCid}:${toString port}"];
+ };
+ };
+
+ users.users = {
+ root = mkIf cfg.withDeployKeys {
+ openssh.authorizedKeys.keyFiles = [./ssh-key.pub];
+ };
+
+ tunnel = mkIf cfg.tunnel.enable {
+ uid = 1100;
+ group = "nogroup";
+ isSystemUser = true;
+
+ # Requiere oath
+ password = "tunnel";
+
+ home = "/var/empty";
+ shell = "${pkgs.coreutils}/bin/true";
+ };
+ };
+ };
+}
diff --git a/sys/auth/ssh-key.pub b/sys/auth/ssh-key.pub
new file mode 100644
index 0000000..1bb3788
--- /dev/null
+++ b/sys/auth/ssh-key.pub
@@ -0,0 +1 @@
+# This file has been lustrated.