From b658b93c649c186058e6961300cdaa2dd5d2a3a7 Mon Sep 17 00:00:00 2001 From: colin Date: Sun, 23 Oct 2022 06:48:39 -0700 Subject: [PATCH] lappy: store the hashed user passwd in git and decrypt it into /etc/passwd on boot this approach lets me persist the password. persisting /etc/shadow directly wasn't so feasible. populating /etc/shadow at activation time is something nix already does and is easy to plug into. so we store the passwd hash in this repo, but encrypt it to the destination machine's ssh pubkey to add enough entropy that it's not brute-forceable through the public git repo. --- .sops.yaml | 6 +++++ machines/lappy/default.nix | 5 ++++- modules/impermanence.nix | 20 +++++++++++++++++ modules/universal/secrets.nix | 2 +- modules/universal/users.nix | 5 +++++ secrets/lappy.yaml | 42 +++++++++++++++++++++++++++++++++++ 6 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 secrets/lappy.yaml diff --git a/.sops.yaml b/.sops.yaml index 9ae1053e..2c199de2 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -31,3 +31,9 @@ creation_rules: - *user_desko_colin - *user_lappy_colin - *host_desko + - path_regex: secrets/lappy.yaml$ + key_groups: + - age: + - *user_lappy_colin + - *user_desko_colin + - *host_lappy diff --git a/machines/lappy/default.nix b/machines/lappy/default.nix index ff000cd8..ad44be8d 100644 --- a/machines/lappy/default.nix +++ b/machines/lappy/default.nix @@ -11,7 +11,10 @@ boot.loader.efi.canTouchEfiVariables = false; sane.image.extraBootFiles = [ pkgs.bootpart-uefi-x86_64 ]; - users.users.colin.initialPassword = "147147"; + sops.secrets.colin-passwd = { + sopsFile = ../../secrets/lappy.yaml; + neededForUsers = true; + }; # default config: https://man.archlinux.org/man/snapper-configs.5 # defaults to something like: diff --git a/modules/impermanence.nix b/modules/impermanence.nix index 6c253155..fd462990 100644 --- a/modules/impermanence.nix +++ b/modules/impermanence.nix @@ -7,6 +7,8 @@ with lib; let cfg = config.sane.impermanence; + # taken from sops-nix code: checks if any secrets are needed to create /etc/shadow + secretsForUsers = (lib.filterAttrs (_: v: v.neededForUsers) config.sops.secrets) != {}; in { options = { @@ -84,6 +86,24 @@ in # secret decoding depends on /etc/ssh keys, which are persisted system.activationScripts.setupSecrets.deps = [ "persist-files" ]; + # `setupSecretsForUsers` should depend on `persist-files`, + # but `persist-files` itself depends on `users`, to this would be circular. + # we work around that by manually mounting the ssh host key. + # strictly speaking, this makes the `setupSecrets -> persist-files` dep extraneous, + # but it's a decent safety net in case something goes wrong. + # system.activationScripts.setupSecretsForUsers.deps = [ "persist-files" ]; + system.activationScripts.setupSecretsForUsers= lib.mkIf secretsForUsers { + deps = [ "persist-ssh-host-key" ]; + }; + system.activationScripts.persist-ssh-host-key = lib.mkIf secretsForUsers ( + let + key = "/etc/ssh/ssh_host_ed25519_key"; + in '' + mkdir -p /etc/ssh + touch ${key} + mount -o bind /nix/persist${key} ${key} + '' + ); }; } diff --git a/modules/universal/secrets.nix b/modules/universal/secrets.nix index ffa85a4f..b618c117 100644 --- a/modules/universal/secrets.nix +++ b/modules/universal/secrets.nix @@ -36,8 +36,8 @@ # This will automatically import SSH keys as age keys sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" - # "/home/colin/.ssh/id_ed25519_dec" ]; + sops.gnupg.sshKeyPaths = []; # disable RSA key import # This is using an age key that is expected to already be in the filesystem # sops.age.keyFile = "/home/colin/.ssh/age.pub"; # sops.age.keyFile = "/var/lib/sops-nix/key.txt"; diff --git a/modules/universal/users.nix b/modules/universal/users.nix index e2985516..ef51a97a 100644 --- a/modules/universal/users.nix +++ b/modules/universal/users.nix @@ -43,7 +43,12 @@ in "feedbackd" "dialout" # required for modem access ]; + + # initial password is empty, in case anything goes wrong. + # if `colin-passwd` (a password hash) is successfully found/decrypted, that becomes the password at boot. initialPassword = lib.mkDefault ""; + passwordFile = lib.mkIf (config.sops.secrets ? "colin-passwd") config.sops.secrets.colin-passwd.path; + shell = pkgs.zsh; # shell = pkgs.bashInteractive; # XXX colin: create ssh key for THIS user by logging in and running: diff --git a/secrets/lappy.yaml b/secrets/lappy.yaml new file mode 100644 index 00000000..3271d495 --- /dev/null +++ b/secrets/lappy.yaml @@ -0,0 +1,42 @@ +#ENC[AES256_GCM,data:s512crIo2ylwy1pWPDs6324+NpP3dHvW0QmuZzvOOyrepTQvmB4NW07NFXYzY/UUPn7E4HrB7mzhvQYxVYDBlZKAMr9llT80Nnpt0AqrxnLiqnnY79EvP+aXvNmi0yWsTGqh6k36BWNTUyPSzgjGtvjQgTLSvr9uRzfy9e4C6NVWBm5sTEbYg9y3ZslToVSsEyGHYMVT6fSKM7ewH8wV,iv:sbBWcHYP5Ak4h7gWbdu8JyL2SEeUgrvkjji11Sp2GoA=,tag:yQTWlrrcBxotdKBbB54x5g==,type:comment] +#ENC[AES256_GCM,data:XcQaEDhsAG2kY0Rdw2AKOwaHQIm3/zrWMjpQlU8pWlifNY9eoPqndzIbCNDKhbEJqrzeAuxGYFRBgohRcHQz2O/cbgr8GwTZ3Uo+NHsX6qcoUhzUKd1xlUnIKLjNcV7vlxofrmXikQ==,iv:OKSw1bw2TiPweUJeqCqwr8V+A+ovIT+meygH9l9m4cI=,tag:aTROLuGpTgoxF1JV/w2Cpw==,type:comment] +#ENC[AES256_GCM,data:GFdHTjsr2DJtg/BIyOSeM6EQw92Q/8JFdqXLwpg/FWn9olTws2KDchSWRDlkrEbgoXSMP3Atd33YgckUebDYMIK8ctJai2SUxLJK5fW8LX1JbKUAC5PHUygAIkWYsHlNse7Qbgrw1rtBuR43L6NbMw==,iv:5beGhtM2wja2GgrLCzizsqamfakDIBlZ74ZJhNr33lg=,tag:Ej1za572vRpPcvcHXliQDA==,type:comment] +colin-passwd: ENC[AES256_GCM,data:QiO9RQnaveqScqf8n1cjWLduQ72GN5jztlHB9I9hNLl/Wuyd32QSkpQzylhFbE1z+G+R02opHdanWAQKicbCXwfW6E0gjBSCS0qb5yZNuTwT+KCtr6U+73pkPduX+8VT0XbVpFCijqjN0g==,iv:m/lS30RChEZ7gFrlt2U4MhVwn/mVxNu6WvzySTZ59co=,tag:R3XEMyfe4yIqA4xBciMnnA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1j2pqnl8j0krdzk6npe93s4nnqrzwx978qrc0u570gzlamqpnje9sc8le2g + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4bzFLUFloMU1uUWRmdkZu + TllhSGxvNzBJQTZRaE9EbTA3R3JLNGpVT25nCmd0SG1BWEJWL1JlKzhmSFdFS3Fk + SnRGbUFqdzVFTy95eVhiZGN6a3VMOGcKLS0tIHFJQUtEYVhGWWlTRlQrbEpoQ2h1 + VXJ5SXNlS1ZNNjhuVDFrMnlrVHp2NlUKwD3ZznQVcz1ZLb/weULpXET9uZb4aj/U + FnY9ktEEtKeSl10jzU3/sUla6Ap6K6b9KLmmqd5Rnp0ZhbxVOR8rkg== + -----END AGE ENCRYPTED FILE----- + - recipient: age1tnl4jfgacwkargzeqnhzernw29xx8mkv73xh6ufdyde6q7859slsnzf24x + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOa1dpZHVoY2tTWVJ2bG1J + Z0xjVGplMGZqajFlcWtPL0YwUXcxWThNOWcwCmQvZllaZ1JSK3N1WmIvV2F6YjZv + U1ZtMVVSSU1LZ3M4SWExSm9yRzRTR3MKLS0tIFU1dERKdko1SVZLcmVXQXMydExm + OWVEdDJsbENOYkJNSzc5MzlEanVSL0EKbKVgN0/LUiC92N9/MvoXJouiIRHE5aWO + R7xPtxYG91vC+HVj8ThHbu0fcUIqD7LTX82XCrWoYMwkplbTC/F2cw== + -----END AGE ENCRYPTED FILE----- + - recipient: age1w7mectcjku6x3sd8plm8wkn2qfrhv9n6zhzlf329e2r2uycgke8qkf9dyn + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3SGk4YzhEaldpcTBRSG1T + Nkpla0s3d2ZRU2RsK2ZDRlhEdVY0NkRYUVU0CjYrTjhxZDVyYUlmbnRQQXBQZVhD + OTcrbmV0YjdyeEhEaHVRUm03Z2hTNTQKLS0tIGVrTjhCL3RlZ2dIOFduVVdSbnJ3 + L2JhVWhmQk9qZzdnYkYrQTBCZnI3eE0KHju7x28mP5jLt4u6T6CnQ3ThiEYFhG5P + D7c0h2YhqeqdewuwQWjqJMbUc308N5f0Hz/BsUgYZNanl9qqQRXkrA== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2022-10-23T12:29:53Z" + mac: ENC[AES256_GCM,data:aa97qTkzP6rE4Pq/hdKAITUhWW7GzAs8iC7W6dzYZHJp/k1vYTOqcJ6JZnLva2e8LZKSlsKTEu/0nu3gmY4YgNw0/o0UlWSN7v58bA6Ybzb/ABiQfVv7FxnWD3978xCTNkzCd9wB53LtP01kAQ42lJx1R+AkohsHBN7pHsQg54w=,iv:BZZuEC5dGsMzXYNHK7UgA52yDhYfl1WHzYUzaTsq+qM=,tag:gYzH9dNe5OAc/dccN/d6GQ==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.7.3