diff --git a/README.md b/README.md index 3d9a7f3..bac89b1 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,13 @@ imports = [ ] ``` -For how to deploy services, check the examples below. +For how to configure the services, check the sections below. + +## Demos + +Demos that start and deploy on a Virtual Machine on your computer are located under the +[demo](./demo/) folder. These show the onboarding experience you would get if you deployed +selfhostblocks on your own server. ## Examples diff --git a/demo/homeassistant/README.md b/demo/homeassistant/README.md index 719e82d..1af42fc 100644 --- a/demo/homeassistant/README.md +++ b/demo/homeassistant/README.md @@ -1,12 +1,12 @@ -# Home Assistant Example +# Home Assistant Demo -This `flake.nix` file sets up Home Assistant server that uses a LDAP server to -setup users with only about [15 lines](./flake.nix#L39-L55) of related code. +The [`flake.nix`](./flake.nix) file sets up Home Assistant server that uses a LDAP server to +setup users in only about [15 lines](./flake.nix#L29-L45) of related code. This guide will show how to deploy this setup to a Virtual Machine, like showed [here](https://nixos.wiki/wiki/NixOS_modules#Developing_modules), in 5 commands. -## Launch VM +## Deploy to the VM Build VM with: @@ -20,24 +20,6 @@ Start VM with (this call is blocking): QEMU_NET_OPTS="hostfwd=tcp::2222-:2222,hostfwd=tcp::8080-:80" ./result/bin/run-nixos-vm ``` -User and password are both `nixos`, as setup in the [`configuration.nix`](./configuration.nix) file under -`user.users.nixos.initialPassword`. - -You can login with `ssh -F ssh_config example`. You just need to accept the fingerprint. - -## Make VM able to decrypt the secrets.yaml file - -The [`sops.yaml`](./sops.yaml) file describes what private keys can decrypt and encrypt the -[`secrets.yaml`](./secrets.yaml) file containing the application secrets. Usually, you will add -secrets to that secrets file and when deploying, it will be decrypted and the secrets will be copied -in the `/run/secrets` folder on the VM. We thus need one private key for you to edit the -[`secrets.yaml`](./secrets.yaml) file and one in the VM for it to decrypt the secrets. - -Your private key is already pre-generated in this repo, it's the [`sshkey`](./sshkey) file. But when -creating the VM in the step above, a new private key and its accompanying public key were -automatically generated under `/etc/ssh/ssh_host_ed25519_key` in the VM. We just need to get the -public key. - With the VM started, print the VM's public age key with the following command. The value you need is the one staring with `age`. @@ -61,26 +43,15 @@ SOPS_AGE_KEY_FILE=keys.txt nix run --impure nixpkgs#sops -- \ secrets.yaml ``` -Later on, when the server is deployed, you will need to login to the LDAP server with the admin account. -You can find the secret `lldap.user_password` field in the [`secrets.yaml`](./secrets.yaml) file. To open it, run: - -```bash -SOPS_AGE_KEY_FILE=keys.txt nix run --impure nixpkgs#sops -- \ - --config sops.yaml \ - secrets.yaml -``` - -## Deploy - -Now, deploy with: +Finally, deploy with: ```bash SSH_CONFIG_FILE=ssh_config nix run nixpkgs#colmena --impure -- apply ``` -Took a few minutes for first deploy on my machine. Next deploys take about 12 seconds. +This step will require you to accept the host's fingerprint. The deploy will take a few minutes the first time and subsequent deploys will take around 15 seconds. -## Access apps through your browser +## Access Home Assistant Through Your Browser Add the following entry to your `/etc/hosts` file: @@ -99,31 +70,64 @@ $ cat /etc/hosts Go to [http://ldap.example.com:8080](http://ldap.example.com:8080) and login with: - username: `admin` -- password: the value of the field `lldap.user_password` in the `secrets.yaml` file. +- password: the value of the field `lldap.user_password` in the `secrets.yaml` file which is. Create the group `homeassistant_user` and a user assigned to that group. -Go to [http://ha.example.com:8080](http://ha.example.com:8080) and login with the user and password you just created above. +Go to [http://ha.example.com:8080](http://ha.example.com:8080) and login with the +user and password you just created above. -## Prepare the VM +## In More Details -This section documents how the various files were created to provide the nearly out of the box -experience described in the previous section. I need to clean this up a bit. +### Files -### Private and Public Key +- [`flake.nix`](./flake.nix): nix entry point, defines one target host for + [colmena](https://colmena.cli.rs) to deploy to as well as the selfhostblock's config for + setting up the home assistant server paired with the LDAP server. +- [`configuration.nix`](./configuration.nix): defines all configuration required for colmena + to deploy to the VM. The file has comments if you're interested. +- [`hardware-configuration.nix`](./hardware-configuration.nix): defines VM specific layout. + This was generated with nixos-generate-config on the VM. +- Secrets related files: + - [`keys.txt`](./keys.txt): your private key for sops-nix, allows you to edit the `secrets.yaml` + file. This file should never be published but here I did it for convenience, to be able to + deploy to the VM in less steps. + - [`secrets.yaml`](./secrets.yaml): encrypted file containing required secrets for Home Assistant + and the LDAP server. This file can be publicly accessible. + - [`sops.yaml`](./sops.yaml): describes how to create the `secrets.yaml` file. Can be publicly + accessible. +- SSH related files: + - [`sshkey(.pub)`](./sshkey): your private and public ssh keys. Again, the private key should usually not + be published as it is here but this makes it possible to deploy to the VM in less steps. + - [`ssh_config`](./ssh_config): the ssh config allowing you to ssh into the VM by just using the + hostname `example`. Usually you would store this info in your `~/.ssh/config` file but it's + provided here to avoid making you do that. -Create the private key in the `keys.txt` file and print the public key used for `admin`: +### Virtual Machine + +_More info about the VM._ + +We use `build-vm-with-bootloader` instead of just `build-vm` as that's the only way to deploy to the VM. + +The VM's User and password are both `nixos`, as setup in the [`configuration.nix`](./configuration.nix) file under +`user.users.nixos.initialPassword`. + +You can login with `ssh -F ssh_config example`. You just need to accept the fingerprint. + +### Secrets + +_More info about the secrets._ + +The private key in the `keys.txt` file is created with: ```bash $ nix shell nixpkgs#age --command age-keygen -o keys.txt Public key: age1algdv9xwjre3tm7969eyremfw2ftx4h8qehmmjzksrv7f2qve9dqg8pug7 ``` -Update `admin` and `vm` keys in `sops.yaml`. +We use the printed public key in the `admin` field in `sops.yaml` file. -Then, you can create the secrets.yaml with: - -That file must follow the format: +The `secrets.yaml` file must follow the format: ```yaml home-assistant: | @@ -138,18 +142,45 @@ lldap: jwt_secret: YYY... ``` -You can generate secrets with: +You can generate random secrets with: ```bash $ nix run nixpkgs#openssl -- rand -hex 64 ``` -TODO: add instructions to create ssh private and public key: +#### Why do we need the VM's public key + +The [`sops.yaml`](./sops.yaml) file describes what private keys can decrypt and encrypt the +[`secrets.yaml`](./secrets.yaml) file containing the application secrets. Usually, you will create and add +secrets to that file and when deploying, it will be decrypted and the secrets will be copied +in the `/run/secrets` folder on the VM. We thus need one private key for you to edit the +[`secrets.yaml`](./secrets.yaml) file and one in the VM for it to decrypt the secrets. + +Your private key is already pre-generated in this repo, it's the [`sshkey`](./sshkey) file. But when +creating the VM in the step above, a new private key and its accompanying public key were +automatically generated under `/etc/ssh/ssh_host_ed25519_key` in the VM. We just need to get the +public key and add it to the `secrets.yaml` which we did in the Deploy section. + +To open the `secrets.yaml` file and optionnally edit it, run: ```bash +SOPS_AGE_KEY_FILE=keys.txt nix run --impure nixpkgs#sops -- \ + --config sops.yaml \ + secrets.yaml ``` -You don't need to copy over the ssh public key with the following command as we set the `keyFiles` option. I still leave it here for reference. +### SSH + +The private and public ssh keys were created with: + +```bash +ssh-keygen -t ed25519 -f sshkey +``` + +You don't need to copy over the ssh public key over to the VM as we set the `keyFiles` option which copies the public key when the VM gets created. +This allows us also to disable ssh password authentication. + +For reference, here is what you would need to do if you didn't use the option: ```bash $ nix shell nixpkgs#openssh --command ssh-copy-id -i sshkey -F ssh_config example @@ -157,7 +188,7 @@ $ nix shell nixpkgs#openssh --command ssh-copy-id -i sshkey -F ssh_config exampl ### Deploy -If you get a NAR hash mismatch error like so, you need to run `nix flake lock --update-input selfhostblocks`: +If you get a NAR hash mismatch error like herunder, you need to run `nix flake lock --update-input selfhostblocks`. ``` error: NAR hash mismatch in input ... diff --git a/demo/homeassistant/configuration.nix b/demo/homeassistant/configuration.nix index 99acf5a..25af783 100644 --- a/demo/homeassistant/configuration.nix +++ b/demo/homeassistant/configuration.nix @@ -20,20 +20,29 @@ # Options above are needed to deploy in a VM. - # As we intend to run this example using `nixos-rebuild build-vm`, we need to setup the user - # ourselves, see https://nixos.wiki/wiki/NixOS:nixos-rebuild_build-vm - users.users.nixos = { + nix.settings.experimental-features = [ "nix-command" "flakes" ]; + + # Used by colmena to know which target host to deploy to. + deployment = { + targetHost = "example"; + targetPort = 2222; + targetUser = "nixos"; + }; + + # We need to create the user we will deploy with. + users.users.${config.deployment.targetUser} = { isNormalUser = true; extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. initialPassword = "nixos"; - # With this option, you don't need to use ssh-copy-id. + # With this option, you don't need to use ssh-copy-id to copy the public ssh key to the VM. openssh.authorizedKeys.keyFiles = [ ./sshkey.pub ]; }; + # The user we're deploying with must be able to run sudo without password. security.sudo.extraRules = [ - { users = [ "nixos" ]; + { users = [ config.deployment.targetUser ]; commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; @@ -42,15 +51,16 @@ } ]; - nix.settings.experimental-features = [ "nix-command" "flakes" ]; + # Needed to allow the user we're deploying with to write to the nix store. nix.settings.trusted-users = [ - "nixos" + config.deployment.targetUser ]; + # We need to enable the ssh daemon to be able to deploy. services.openssh = { enable = true; - ports = [ 2222 ]; + ports = [ config.deployment.targetPort ]; permitRootLogin = "no"; - passwordAuthentication = true; + passwordAuthentication = false; }; } diff --git a/demo/homeassistant/flake.nix b/demo/homeassistant/flake.nix index d48501e..843c08a 100644 --- a/demo/homeassistant/flake.nix +++ b/demo/homeassistant/flake.nix @@ -20,22 +20,12 @@ }; myserver = { config, ... }: { - deployment = { - targetHost = "example"; - targetPort = 2222; - targetUser = "nixos"; - }; - imports = [ ./configuration.nix sops-nix.nixosModules.default selfhostblocks.nixosModules.x86_64-linux.default ]; - # Set to true for more debug info with `journalctl -f -u nginx`. - shb.nginx.accessLog = true; - shb.nginx.debugLog = true; - shb.ldap = { enable = true; domain = "example.com"; @@ -54,10 +44,9 @@ sopsFile = ./secrets.yaml; }; - nix.settings.experimental-features = [ "nix-command" "flakes" ]; - nix.settings.trusted-users = [ - "nixos" - ]; + # Set to true for more debug info with `journalctl -f -u nginx`. + shb.nginx.accessLog = false; + shb.nginx.debugLog = false; }; }; }; diff --git a/demo/homeassistant/sops.yaml b/demo/homeassistant/sops.yaml index d2d10b2..b9f8700 100644 --- a/demo/homeassistant/sops.yaml +++ b/demo/homeassistant/sops.yaml @@ -1,9 +1,7 @@ keys: - &admin age1algdv9xwjre3tm7969eyremfw2ftx4h8qehmmjzksrv7f2qve9dqg8pug7 - - &vm age18jrfv0ndtrad7ee4dzdfhhuca4wuce059txltdaxuxcnjkc37s5qj9mapm creation_rules: - path_regex: secrets.yaml$ key_groups: - age: - *admin - - *vm