aboutsummaryrefslogtreecommitdiff
path: root/flakes/private/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'flakes/private/ssh')
-rw-r--r--flakes/private/ssh/flake.lock36
-rw-r--r--flakes/private/ssh/flake.nix107
-rwxr-xr-xflakes/private/ssh/ldap_authorized_keys.sh62
3 files changed, 205 insertions, 0 deletions
diff --git a/flakes/private/ssh/flake.lock b/flakes/private/ssh/flake.lock
new file mode 100644
index 0000000..bbb2011
--- /dev/null
+++ b/flakes/private/ssh/flake.lock
@@ -0,0 +1,36 @@
1{
2 "nodes": {
3 "environment": {
4 "locked": {
5 "lastModified": 1,
6 "narHash": "sha256-rMKbM7fHqWQbI7y59BsPG8KwoDj2jyrvN2niPWB24uE=",
7 "path": "../environment",
8 "type": "path"
9 },
10 "original": {
11 "path": "../environment",
12 "type": "path"
13 }
14 },
15 "root": {
16 "inputs": {
17 "environment": "environment",
18 "secrets": "secrets"
19 }
20 },
21 "secrets": {
22 "locked": {
23 "lastModified": 1,
24 "narHash": "sha256-5AakznhrJFmwCD7lr4JEh55MtdAJL6WA/YuBks6ISSE=",
25 "path": "../../secrets",
26 "type": "path"
27 },
28 "original": {
29 "path": "../../secrets",
30 "type": "path"
31 }
32 }
33 },
34 "root": "root",
35 "version": 7
36}
diff --git a/flakes/private/ssh/flake.nix b/flakes/private/ssh/flake.nix
new file mode 100644
index 0000000..0ca6d67
--- /dev/null
+++ b/flakes/private/ssh/flake.nix
@@ -0,0 +1,107 @@
1{
2 inputs.environment.url = "path:../environment";
3 inputs.secrets.url = "path:../../secrets";
4 outputs = { self, environment, secrets }: {
5 nixosModule = self.nixosModules.ssh;
6 nixosModules.ssh = { lib, pkgs, config, ... }:
7 let
8 cfg = config.myServices.ssh;
9 in
10 {
11 imports = [
12 environment.nixosModule
13 secrets.nixosModule
14 ];
15 options.myServices.ssh = let
16 module = lib.types.submodule {
17 options = {
18 vars = lib.mkOption {
19 type = lib.types.attrsOf lib.types.lines;
20 default = {};
21 description = ''
22 variables to interpolate in the script. A `name_` prefix will be prepended
23 '';
24 };
25 snippet = lib.mkOption {
26 type = lib.types.lines;
27 description = ''
28 Snippet to use
29 '';
30 };
31 dependencies = lib.mkOption {
32 type = lib.types.listOf lib.types.package;
33 default = [];
34 description = ''
35 Dependencies of the package
36 '';
37 };
38 };
39 };
40 in {
41 modules = lib.mkOption {
42 type = lib.types.attrsOf module;
43 default = {};
44 description = ''
45 List of modules to enable
46 '';
47 };
48 };
49 config = lib.mkIf (builtins.length (builtins.attrValues cfg.modules) > 0) {
50
51 services.openssh.extraConfig = ''
52 AuthorizedKeysCommand /etc/ssh/ldap_authorized_keys
53 AuthorizedKeysCommandUser nobody
54 '';
55
56 secrets.keys."ssh-ldap" = {
57 user = "nobody";
58 group = "nogroup";
59 permissions = "0400";
60 text = config.myEnv.sshd.ldap.password;
61 };
62 secrets.keys."ssh-psql" = {
63 user = "nobody";
64 group = "nogroup";
65 permissions = "0400";
66 text = config.myEnv.sshd.psql.password;
67 };
68 system.activationScripts.sshd = {
69 deps = [ "secrets" ];
70 text = ''
71 install -Dm400 -o nobody -g nogroup -T ${config.secrets.fullPaths."ssh-ldap"} /etc/ssh/ldap_password
72 install -Dm400 -o nobody -g nogroup -T ${config.secrets.fullPaths."ssh-psql"} /etc/ssh/psql_password
73 '';
74 };
75 # ssh is strict about parent directory having correct rights, don't
76 # move it in the nix store.
77 environment.etc."ssh/ldap_authorized_keys" = let
78 deps = lib.lists.unique (
79 [ pkgs.which pkgs.openldap pkgs.stdenv.shellPackage pkgs.gnugrep pkgs.gnused pkgs.coreutils pkgs.postgresql ]
80 ++ lib.flatten (map (v: v.dependencies) (builtins.attrValues cfg.modules))
81 );
82 vars = lib.concatMapAttrs (n: v: (
83 lib.mapAttrs' (n': lib.nameValuePair "${n}_${n'}") v.vars
84 )) cfg.modules;
85 fullScript = pkgs.runCommand "ldap_authorized_keys" (vars // {
86 snippets = builtins.concatStringsSep "\n" (map (v: v.snippet) (builtins.attrValues cfg.modules));
87 }) ''
88 substituteAll ${./ldap_authorized_keys.sh} $out
89 # Second call for the included snippets
90 substituteAllInPlace $out
91 chmod a+x $out
92 '';
93 ldap_authorized_keys = pkgs.runCommand "ldap_authorized_keys" {
94 buildInputs = [ pkgs.makeWrapper ];
95 } ''
96 makeWrapper "${fullScript}" "$out" --prefix PATH : ${lib.makeBinPath deps}
97 '';
98 in {
99 enable = true;
100 mode = "0755";
101 user = "root";
102 source = ldap_authorized_keys;
103 };
104 };
105 };
106 };
107}
diff --git a/flakes/private/ssh/ldap_authorized_keys.sh b/flakes/private/ssh/ldap_authorized_keys.sh
new file mode 100755
index 0000000..f4395be
--- /dev/null
+++ b/flakes/private/ssh/ldap_authorized_keys.sh
@@ -0,0 +1,62 @@
1#!/usr/bin/env bash
2
3LDAPSEARCH=ldapsearch
4KEY="immaeSshKey"
5LDAP_BIND="cn=ssh,ou=services,dc=immae,dc=eu"
6LDAP_PASS=$(cat /etc/ssh/ldap_password)
7LDAP_HOST="ldap://ldap.immae.eu"
8LDAP_BASE="dc=immae,dc=eu"
9USER_LDAP_BASE="ou=users,dc=immae,dc=eu"
10
11PSQL_BASE="immae"
12PSQL_HOST="localhost"
13PSQL_USER="immae_auth_read"
14PSQL_PASS=$(cat /etc/ssh/psql_password)
15
16suitable_for() {
17 type_for="$1"
18 key="$2"
19
20 if [[ $key != *$'\n'* ]] && [[ $key == ssh-* ]]; then
21 echo "$key"
22 else
23 key_type=$(cut -d " " -f 1 <<< "$key")
24
25 if grep -q "\b-$type_for\b" <<< "$key_type"; then
26 echo ""
27 elif grep -q "\b$type_for\b" <<< "$key_type"; then
28 echo $(sed -e "s/^[^ ]* //g" <<< "$key")
29 else
30 echo ""
31 fi
32 fi
33}
34
35clean_key_line() {
36 type_for="$1"
37 line="$2"
38
39 if [[ "$line" == $KEY::* ]]; then
40 # base64 keys should't happen, unless wrong copy-pasting
41 key=""
42 else
43 key=$(sed -e "s/^$KEY: *//" -e "s/ *$//" <<< "$line")
44 fi
45
46 suitable_for "$type_for" "$key"
47}
48
49ldap_search() {
50 $LDAPSEARCH -H $LDAP_HOST -ZZ -b $LDAP_BASE -D $LDAP_BIND -w "$LDAP_PASS" -x -o ldif-wrap=no -LLL "$@"
51}
52
53psql_search() {
54 PGPASSWORD="$PSQL_PASS" psql -U "$PSQL_USER" -h "$PSQL_HOST" -X -A -t -d "$PSQL_BASE" -c "$@"
55}
56
57ldap_keys() {
58 user=$1;
59 @snippets@
60}
61
62ldap_keys $@