From dbd312e9bdbab2bf74cb6f3b9c4db05a2d0d7dba Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 28 Jun 2023 03:57:57 +0000 Subject: [PATCH] guest: enable access to shelvacu --- hosts/by-name/desko/default.nix | 2 ++ hosts/common/secrets.nix | 8 +++++-- hosts/common/users/guest.nix | 12 ++--------- modules/lib/path.nix | 8 +++++++ secrets/desko/README.md | 2 ++ secrets/desko/guest/authorized_keys.bin | 28 +++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 secrets/desko/guest/authorized_keys.bin diff --git a/hosts/by-name/desko/default.nix b/hosts/by-name/desko/default.nix index f83b0f77..9f6dfae4 100644 --- a/hosts/by-name/desko/default.nix +++ b/hosts/by-name/desko/default.nix @@ -4,6 +4,8 @@ ./fs.nix ]; + sane.guest.enable = true; + # TODO: make sure this plays nice with impermanence services.distccd.enable = true; sane.programs.distcc.enableFor.user.guest = true; diff --git a/hosts/common/secrets.nix b/hosts/common/secrets.nix index 5759be87..99a17569 100644 --- a/hosts/common/secrets.nix +++ b/hosts/common/secrets.nix @@ -29,14 +29,18 @@ let inherit (lib.strings) hasSuffix removeSuffix; - secretsForHost = host: sane-lib.joinAttrsets ( + secretsForHost = host: let + extraAttrsForPath = path: lib.optionalAttrs (sane-lib.path.isChild "guest" path) { + owner = "guest"; + }; + in sane-lib.joinAttrsets ( map (path: lib.optionalAttrs (hasSuffix ".bin" path) (sane-lib.nameValueToAttrs { name = removeSuffix ".bin" path; value = { sopsFile = ../../secrets/${host}/${path}; format = "binary"; - }; + } // (extraAttrsForPath path); })) (sane-lib.enumerateFilePaths ../../secrets/${host}) ); diff --git a/hosts/common/users/guest.nix b/hosts/common/users/guest.nix index 5a306c22..daf9fd29 100644 --- a/hosts/common/users/guest.nix +++ b/hosts/common/users/guest.nix @@ -9,15 +9,6 @@ in default = false; type = types.bool; }; - sane.guest.authorizedKeys = mkOption { - default = []; - type = types.listOf types.str; - description = '' - list of " " keys. - e.g. - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX colin@desko - ''; - }; }; config = { @@ -30,9 +21,10 @@ in group = "users"; initialPassword = lib.mkDefault ""; shell = pkgs.zsh; - openssh.authorizedKeys.keys = cfg.authorizedKeys; }; + sane.users.guest.fs.".ssh/authorized_keys".symlink.target = config.sops.secrets."guest/authorized_keys".path or "/dev/null"; + sane.persist.sys.plaintext = lib.mkIf cfg.enable [ # intentionally allow other users to write to the guest folder { directory = "/home/guest"; user = "guest"; group = "users"; mode = "0775"; } diff --git a/modules/lib/path.nix b/modules/lib/path.nix index 6bdef6a2..2f118366 100644 --- a/modules/lib/path.nix +++ b/modules/lib/path.nix @@ -24,6 +24,8 @@ let path = rec { # return the last path component; error on the empty path leaf = str: lib.last (split str); + # XXX: this is bugged in that + # from "/foo/bar" "/foo/barbag" => "/bag" from = start: end: let s = path.norm start; e = path.norm end; @@ -32,6 +34,12 @@ let path = rec { "/" + (lib.removePrefix s e) ); + isChild = parent: child: + lib.any + (p: p == norm parent) + (walk "/" child) + ; + # yield every node between start and end, including each the endpoints # e.g. walk "/foo" "/foo/bar/baz" => [ "/foo" "/foo/bar" "/foo/bar/baz" ] # XXX: assumes input paths are normalized diff --git a/secrets/desko/README.md b/secrets/desko/README.md index f6b8467d..51e5fb3b 100644 --- a/secrets/desko/README.md +++ b/secrets/desko/README.md @@ -4,3 +4,5 @@ - see - update by running `sudo passwd colin` and then taking the 2nd item from the colin: line in /etc/shadow - N.B.: you MUST do `sudo passwd colin` instead of just `passwd`, i guess because of immutable users or something +- guest/authorized_keys.bin + - who's allowed to login to the guest account diff --git a/secrets/desko/guest/authorized_keys.bin b/secrets/desko/guest/authorized_keys.bin new file mode 100644 index 00000000..cef1863a --- /dev/null +++ b/secrets/desko/guest/authorized_keys.bin @@ -0,0 +1,28 @@ +{ + "data": "ENC[AES256_GCM,data:Ny0DzkX975vtS9IY9a0pzmq99RqYquwV8SBDXpDh2dhJo9gW0vbtyvww8zdHN+vtMSL7oriDIORdNa1kpQnppo6mIto0mIh2ZolRRbIySm6ppIrWP+I+P3XMpYH1jwY0RfeHwSHcPXBmL7XFhIdSPu+LwYAfPw9AVzIFDBLMNZUeKpxYqcLtXG0SVDTVzAV1KBrSrFKpz54Rw9rs4dBtj28ZiejGGrI3zBly423vDtuthkMB1R/uI7mxXWVNbufBYwGn97WiVWfu68kL13Q/js3rX4QcO4jccVwf7BYgKV3wSLBACUbl9h9eebxKLNf+UncrWf3wIAywjYYD2ElMMQ0Kn+cjd2FOzuN0E84HMgfFD/EXB010bSUhggwelH4qrmky5DvnS9QtHm4vRAdDfv+5+j98hl+Lcct7h7cKME5RLCZ4OmCo/U7RIjMqgUhSgWCAKVC4uVkhp8WJUH5IETAY8w2CqCN92H9bH0rz7ngdGzlh084vQXLt4hZzZ45cv2wsPUiL2ASy7MQMBcuU2IKKxpHlPMunzbeOD9QpdjOkZLN6m6ySO+7KmwE08LZf4qTiV6JdMpBsuDySJQRCalbHf9gHgdVGnTN9u3NdaHh2gm0Sn6KOxyMktAwmiqLZBbwmKBLtYbyHWTG5qVOP5JIy,iv:hz1CO7t8as7G3oYbHKp412lPqJoUeb+A/Y36g/yAktk=,tag:AkEEapeEAjsFJok42Aq+tw==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4MU5TbTFMSFlmTG0xK0hi\nQmtialJRV21XbWpuYVJXOWFiVkZMNXkrRERnCkRpK1R2K0p2dzdvV0dUcEpzaFBL\nbWx2WDVRSlNoL0ErOXdqV1lFYU4zVVUKLS0tIFQxZUwyS0JVRVN3aTlEa3JQdTA5\nSjQ3cjhyYitvRkI0dVBoZk41cXAxb0EKmnP7UrqX57nLfD+6FNT29nPqHyk/O9Tg\n7Jut7DD1S9yZu0C4FW/iuNspjV3kVbtZ4B0h2AYBwl1EFEv7mL65Gw==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWMWF5VnZRQVhLYnREOUV2\nUDJkQWxJSGEweXRNU2xMUEVqb0NOSVlZTjNRCjlMUWxhMmtrODNtbms1VitwbnpZ\nOCtOMnZ1bEtWb1FIVDVEQzRlQS9IbVUKLS0tIEtZL2ZqNHRJNmFXM3BsbnhUbHYw\nQTNKUTZZWFZPUko5TFBZek9MMHBEZlUKyzrEJjTnMcnuyYrVAwb36WDVBRCDKLMe\n5eiKYepLa1+AH93wHAgoAW9kv1pmFfMOLfGhV1CALb2v8yabHmlVMg==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1vnw7lnfpdpjn62l3u5nyv5xt2c965k96p98kc43mcnyzpetrts9q54mc9v", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByakhjME1WcTU5U241aTdu\nMzg1QlViTUEvcGtBNVFPTHV5ZWNyS3FEVm1BCjFicDFwcDY2N3orQjB0UFd2eEF0\nUVBodnBPSThtbUFUcmxnWG5RWDluNVkKLS0tIHJCWXNxdDdqMlRsY3o5Q2dWVlB2\na3BtQjBzc1MyeTNLcEcyTWFWTytlMjQKs74/B41lR4FXuUomschiy9pgvsO7RKQ6\nVESvelgDNWvB4HikXj0CCC7vWR43X0dggFsxoDaQhU87CI6g3mauNQ==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2023-06-29T02:50:40Z", + "mac": "ENC[AES256_GCM,data:wNgxe6nBYoT00Sg28VOOzvgoGbcXUvtEfsqx+mxGviSidDrMImvBkOgEs/eKNdXvZyRj2TjKEFBLWLZfqpPCczKQbPUMmAQD8SQjWIBOotiMgKLHfLzC+cGM6uPxcrJruXKJJv8U1QmznV+X+x2uaQjqDvtnGJFwl8X1qHy2uCQ=,iv:KpUPOpS45/K8zONOFoeZUQ7rdPDBJyOGlpjVMCLcdic=,tag:uvBu+bnG2nVO79n8IsMZDQ==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.7.3" + } +} \ No newline at end of file