summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2018-04-06 13:14:59 +0200
committerGregor Kleen <gkleen@yggdrasil.li>2018-04-06 13:14:59 +0200
commite1b0869fde7c084961fb11c80afc8e6fbe7c7afa (patch)
tree2d7f5ac4f6af66312ff5ee10b926eb59b318656b
parent3c0f7675064548b9f1c95f1034cb31d517f5dc9c (diff)
downloadnixos-e1b0869fde7c084961fb11c80afc8e6fbe7c7afa.tar
nixos-e1b0869fde7c084961fb11c80afc8e6fbe7c7afa.tar.gz
nixos-e1b0869fde7c084961fb11c80afc8e6fbe7c7afa.tar.bz2
nixos-e1b0869fde7c084961fb11c80afc8e6fbe7c7afa.tar.xz
nixos-e1b0869fde7c084961fb11c80afc8e6fbe7c7afa.zip
Overhaul uucp
-rw-r--r--custom/uucp-mediaserver.nix2
-rw-r--r--custom/uucp.nix114
-rw-r--r--hel.nix29
-rw-r--r--odin.nix24
-rw-r--r--ymir.nix23
5 files changed, 119 insertions, 73 deletions
diff --git a/custom/uucp-mediaserver.nix b/custom/uucp-mediaserver.nix
index 23b43118..5ed3b5ed 100644
--- a/custom/uucp-mediaserver.nix
+++ b/custom/uucp-mediaserver.nix
@@ -61,6 +61,6 @@ in {
61 environment.systemPackages = [ scripts ]; 61 environment.systemPackages = [ scripts ];
62 62
63 services.uucp.commandPath = [ "${scripts}/bin" ]; 63 services.uucp.commandPath = [ "${scripts}/bin" ];
64 services.uucp.commands = genAttrs cfg.remoteNodes (name: ["mediaspace.${name}"] ); 64 services.uucp.remoteNodes = genAttrs cfg.remoteNodes (name: { commands = ["mediaspace.${name}"]; } );
65 }; 65 };
66} 66}
diff --git a/custom/uucp.nix b/custom/uucp.nix
index f5b89bfe..61e42119 100644
--- a/custom/uucp.nix
+++ b/custom/uucp.nix
@@ -3,23 +3,72 @@
3with lib; 3with lib;
4 4
5let 5let
6 portSpec = name: '' 6 portSpec = name: node: concatStringsSep "\n" (mapAttrsToList (portName: port: ''
7 port ${name} 7 port ${name}.${portName}
8 type pipe 8 type pipe
9 protocol ${if builtins.hasAttr name cfg.protocols then cfg.protocols."${name}" else cfg.defaultProtocol} 9 protocol ${node.protocols}
10 reliable true 10 reliable true
11 command ${pkgs.openssh}/bin/ssh -x -o batchmode=yes ${name} 11 command ${pkgs.openssh}/bin/ssh -x -o batchmode=yes ${name}.${portName}
12 ''; 12 '') node.hostnames);
13 sysSpec = name: '' 13 sysSpec = name: ''
14 system ${name} 14 system ${name}
15 time Any 15 time Any
16 port ${name}
17 chat "" 16 chat ""
18 protocol ${if builtins.hasAttr name cfg.protocols then cfg.protocols."${name}" else cfg.defaultProtocol}
19 command-path ${concatStringsSep " " cfg.commandPath} 17 command-path ${concatStringsSep " " cfg.commandPath}
20 commands ${concatStringsSep " " (if builtins.hasAttr name cfg.commands then unique (cfg.defaultCommands ++ cfg.commands."${name}") else cfg.defaultCommands)} 18 commands ${concatStringsSep " " node.commands}
19 ${concatStringsSep "\nalternate\n" (mapAttrsToList (portName: port: ''
20 port ${name}.${portName}
21 '') node.hostnames)}
22 '';
23 sshConfig = name: node: concatStringsSep "\n" (mapAttrsToList (portName: port: ''
24 Host ${name}.${portName}
25 Hostname ${port}
26 IdentitiesOnly Yes
27 IdentityFile ${cfg.sshKeyDir}/${name}.pub
28 '') node.hostnames);
29 sshKeyGen = name: node: ''
30 if [[ ! -e ${cfg.sshKeyDir}/${name} ]]; then
31 ssh-keygen ${escapeShellArgs node.generateKey} -f ${cfg.sshKeyDir}/${name}
32 fi
33 '';
34 restrictKey = key: ''
35 restrict,command="${config.security.wrapperDir}/uucico" ${key}
21 ''; 36 '';
22 37
38 nodeCfg = {
39 options = {
40 commands = mkOption {
41 type = types.listOf types.string;
42 default = cfg.defaultCommands;
43 description = "Commands to allow for this remote";
44 };
45
46 protocols = mkOption {
47 type = types.string;
48 default = cfg.defaultProtocols;
49 description = "UUCP protocols to use for this remote";
50 };
51
52 publicKeys = mkOption {
53 type = types.listOf types.string;
54 default = [];
55 description = "SSH public keys for this node";
56 };
57
58 generateKey = mkOption {
59 type = types.listOf types.string;
60 default = [ "-t ed25519" ];
61 description = "Arguments to pass to `ssh-keygen` to generate a keypair for communication with this host";
62 };
63
64 hostnames = mkOption {
65 type = types.attrsOf types.string;
66 default = {};
67 description = "";
68 };
69 };
70 };
71
23 cfg = config.services.uucp; 72 cfg = config.services.uucp;
24in { 73in {
25 options = { 74 options = {
@@ -44,14 +93,14 @@ in {
44 description = "Overrides for the local uucp linux-user"; 93 description = "Overrides for the local uucp linux-user";
45 }; 94 };
46 95
47 sshConfig = mkOption { 96 extraSSHConfig = mkOption {
48 type = types.str; 97 type = types.str;
49 default = ""; 98 default = "";
50 description = "~uucp/.ssh/config"; 99 description = "Extra SSH config";
51 }; 100 };
52 101
53 remoteNodes = mkOption { 102 remoteNodes = mkOption {
54 type = types.listOf types.str; 103 type = types.attrsOf (types.submodule nodeCfg);
55 default = {}; 104 default = {};
56 description = '' 105 description = ''
57 Ports to set up 106 Ports to set up
@@ -73,22 +122,22 @@ in {
73 description = "Commands allowed for remotes without explicit override"; 122 description = "Commands allowed for remotes without explicit override";
74 }; 123 };
75 124
76 commands = mkOption { 125 defaultProtocols = mkOption {
77 type = types.attrsOf (types.listOf types.string);
78 default = {};
79 description = "Override commands for specific remotes";
80 };
81
82 defaultProtocol = mkOption {
83 type = types.string; 126 type = types.string;
84 default = "e"; 127 default = "e";
85 description = "UUCP protocol to use within ssh unless overriden"; 128 description = "UUCP protocol to use within ssh unless overriden";
86 }; 129 };
87 130
88 protocols = mkOption { 131 homeDir = mkOption {
89 type = types.attrsOf types.string; 132 type = types.path;
90 default = {}; 133 default = "/var/uucp";
91 description = "UUCP protocols to use for specific remotes"; 134 description = "Home of the uucp user";
135 };
136
137 sshKeyDir = mkOption {
138 type = types.path;
139 default = "${cfg.homeDir}/.ssh/";
140 description = "Directory to store ssh keypairs";
92 }; 141 };
93 142
94 spoolDir = mkOption { 143 spoolDir = mkOption {
@@ -184,16 +233,27 @@ in {
184 isSystemUser = true; 233 isSystemUser = true;
185 isNormalUser = false; 234 isNormalUser = false;
186 createHome = true; 235 createHome = true;
187 home = cfg.spoolDir; 236 home = cfg.homeDir;
188 description = "User for uucp over ssh"; 237 description = "User for uucp over ssh";
189 useDefaultShell = true; 238 useDefaultShell = true;
239 openssh.authorizedKeys.keys = map restrictKey (concat (mapAttrsToList (name: node: node.publicKeys) cfg.remoteNodes));
190 } // cfg.sshUser; 240 } // cfg.sshUser;
191 241
192 system.activationScripts."uucp-sshconfig" = '' 242 system.activationScripts."uucp-sshconfig" = ''
193 mkdir -p ${config.users.users."uucp".home}/.ssh 243 mkdir -p ${config.users.users."uucp".home}/.ssh
194 chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.users.users."uucp".home}/.ssh 244 chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${config.users.users."uucp".home}/.ssh
195 chmod 700 ${config.users.users."uucp".home}/.ssh 245 chmod 700 ${config.users.users."uucp".home}/.ssh
196 ln -fs ${builtins.toFile "ssh-config" cfg.sshConfig} ${config.users.users."uucp".home}/.ssh/config 246 ln -fs ${builtins.toFile "ssh-config" ''
247 ${concatStringsSpec "\n" (mapAttrsToList sshConfig cfg.remoteNodes)}
248
249 ${cfg.extraSSHConfig}
250 ''} ${config.users.users."uucp".home}/.ssh/config
251
252 mkdir -p ${cfg.sshKeyDir}
253 chown ${config.users.users."uucp".name}:${config.users.users."uucp".group} ${cfg.sshKeyDir}
254 chmod 700 ${config.sshKeyDir}
255
256 ${concatStringsSep "\n" (mapAttrsToList sshKeyGen cfg.remoteNodes)}
197 ''; 257 '';
198 258
199 system.activationScripts."uucp-logs" = '' 259 system.activationScripts."uucp-logs" = ''
@@ -213,10 +273,10 @@ in {
213 port ssh 273 port ssh
214 type stdin 274 type stdin
215 protocol e 275 protocol e
216 '' + concatStringsSep "\n" (map portSpec cfg.remoteNodes); 276 '' + concatStringsSep "\n" (mapAttrsToList portSpec cfg.remoteNodes);
217 }; 277 };
218 environment.etc."uucp/sys" = { 278 environment.etc."uucp/sys" = {
219 text = cfg.extraSys + "\n" + concatStringsSep "\n" (map sysSpec cfg.remoteNodes); 279 text = cfg.extraSys + "\n" + concatStringsSep "\n" (mapAttrsToList sysSpec cfg.remoteNodes);
220 }; 280 };
221 281
222 security.wrappers = let 282 security.wrappers = let
@@ -301,7 +361,7 @@ in {
301 361
302 case "''${2}" in 362 case "''${2}" in
303 (?(vpn-)up) 363 (?(vpn-)up)
304 ${concatMapStringsSep "\n " (name: "${pkgs.systemd}/bin/systemctl start uucico@${name}.service") cfg.remoteNodes} 364 ${concatStringsSep "\n " (mapAttrsToList (name: node: "${pkgs.systemd}/bin/systemctl start uucico@${name}.service") cfg.remoteNodes)}
305 ;; 365 ;;
306 esac 366 esac
307 ''; 367 '';
diff --git a/hel.nix b/hel.nix
index 0c1ae69a..c6f02471 100644
--- a/hel.nix
+++ b/hel.nix
@@ -202,25 +202,20 @@
202 uucp = { 202 uucp = {
203 enable = true; 203 enable = true;
204 nodeName = "hel"; 204 nodeName = "hel";
205 remoteNodes = ["odin" "ymir"]; 205 remoteNodes = {
206 sshUser = { 206 "odin" = {
207 openssh.authorizedKeys.keys = [ ''restrict,command="${config.security.wrapperDir}/uucico" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFH1QWdgoC03nzW5GBuCl2pqASHeIXIYtE9IInHdaKcO uucp@ymir'' 207 publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKcDj49TqmflGTmtGBqDawxmCBWW1txj61CZ7KT0hTHK uucp@odin"];
208 ''restrict,command="${config.security.wrapperDir}/uucico" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKcDj49TqmflGTmtGBqDawxmCBWW1txj61CZ7KT0hTHK uucp@odin'' 208 hostnames = ["odin.asgard.yggdrasil"];
209 ]; 209 commands = lib.mkForce ["recv-media" "notify-gkleen"];
210 };
211 "ymir" = {
212 publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFH1QWdgoC03nzW5GBuCl2pqASHeIXIYtE9IInHdaKcO uucp@ymir"];
213 hostnames = ["ymir.yggdrasil.li" "ymir.niflheim.yggdrasil"];
214 };
210 }; 215 };
211 sshConfig = '' 216
212 Host odin
213 Hostname odin.asgard.yggdrasil
214 IdentityFile ~/.ssh/odin
215 Host ymir
216 Hostname ymir.niflheim.yggdrasil
217 IdentityFile ~/.ssh/ymir
218 '';
219 commandPath = [ "${pkgs.callPackage ./hel/recv-media.nix {}}/bin" config.security.wrapperDir ]; 217 commandPath = [ "${pkgs.callPackage ./hel/recv-media.nix {}}/bin" config.security.wrapperDir ];
220 defaultCommands = []; 218 defaultCommands = lib.mkForce [];
221 commands = {
222 "odin" = ["recv-media" "notify-gkleen"];
223 };
224 }; 219 };
225 220
226 postfix = { 221 postfix = {
diff --git a/odin.nix b/odin.nix
index 11a3c934..f92556de 100644
--- a/odin.nix
+++ b/odin.nix
@@ -78,22 +78,16 @@
78 services.uucp = { 78 services.uucp = {
79 enable = true; 79 enable = true;
80 nodeName = "odin"; 80 nodeName = "odin";
81 remoteNodes = [ "ymir" "hel" ]; 81 remoteNodes = {
82 sshUser = { 82 "ymir" = {
83 openssh.authorizedKeys.keys = [ ''restrict,command="${config.security.wrapperDir}/uucico" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKD8ycFGfVkBL9wjA5Kc33cl6Qt5K2505G/38oH8Cy/e uucp@hel'' 83 publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGANj+LJ4CI6VrAgBRocKCGq74kZnwD1PdKr/gdlfVr1 uucp@ymir"];
84 ''restrict,command="${config.security.wrapperDir}/uucico" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGANj+LJ4CI6VrAgBRocKCGq74kZnwD1PdKr/gdlfVr1 uucp@ymir'' 84 hostnames = ["ymir.yggdrasil.li" "ymir.niflheim.yggdrasil"];
85 ]; 85 };
86 "hel" = {
87 publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKD8ycFGfVkBL9wjA5Kc33cl6Qt5K2505G/38oH8Cy/e uucp@hel"];
88 hostnames = ["hel.asgard.yggdrasil" "hel.midgard.yggdrasil"];
89 };
86 }; 90 };
87 sshConfig = ''
88 Host ymir
89 Hostname ymir.niflheim.yggdrasil
90 IdentityFile ~/.ssh/ymir
91 Host hel
92 Hostname hel.midgard.yggdrasil
93 IdentityFile ~/.ssh/hel
94 '';
95 commandPath = ["${pkgs.rmail}/bin"];
96 defaultCommands = ["rmail"];
97 91
98 media-server = { 92 media-server = {
99 enable = true; 93 enable = true;
diff --git a/ymir.nix b/ymir.nix
index c0faba6b..192bc27b 100644
--- a/ymir.nix
+++ b/ymir.nix
@@ -852,20 +852,17 @@ in rec {
852 services.uucp = { 852 services.uucp = {
853 enable = true; 853 enable = true;
854 nodeName = "ymir"; 854 nodeName = "ymir";
855 remoteNodes = [ "odin" "hel" ]; 855 remoteNodes = {
856 sshUser = { 856 "odin" = {
857 openssh.authorizedKeys.keys = [ ''restrict,command="${config.security.wrapperDir}/uucico" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKT/BsAMLJs9NYhKIso4J3EF+VzRBm3c+qCQ5ONKc/1s uucp@odin'' 857 publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKT/BsAMLJs9NYhKIso4J3EF+VzRBm3c+qCQ5ONKc/1s uucp@odin"];
858 ''restrict,command="${config.security.wrapperDir}/uucico" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOWBybBQKbPucqBgULQ1phv7IKFWl1Xc4drkCx3D5mIz uucp@hel'' 858 hostnames = ["odin.asgard.yggdrasil"];
859 ]; 859 };
860 "hel" = {
861 publicKeys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOWBybBQKbPucqBgULQ1phv7IKFWl1Xc4drkCx3D5mIz uucp@hel"];
862 hostnames = ["hel.midgard.yggdrasil"];
863 };
860 }; 864 };
861 sshConfig = '' 865
862 Host odin
863 Hostname odin.asgard.yggdrasil
864 IdentityFile ~/.ssh/odin
865 Host hel
866 Hostname hel.midgard.yggdrasil
867 IdentityFile ~/.ssh/hel
868 '';
869 commandPath = ["${pkgs.rmail}/bin" "${pkgs.push2bin}/bin"]; 866 commandPath = ["${pkgs.rmail}/bin" "${pkgs.push2bin}/bin"];
870 defaultCommands = ["rmail" "push2bin"]; 867 defaultCommands = ["rmail" "push2bin"];
871 }; 868 };