HF-7: Move out sops config
* Updated configuration.nix to match latest homefree * Added secrets config * Updated Readme
This commit is contained in:
parent
b216f4f19f
commit
90c1ecfe14
15 changed files with 318 additions and 31 deletions
10
.sops.yaml
Normal file
10
.sops.yaml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# see https://github.com/Mic92/dotfiles/blob/master/nixos/.sops.yaml
|
||||||
|
keys:
|
||||||
|
- &user_homefree 06321D7F20335A7E08595BA905D137EE114BA2C2
|
||||||
|
- &host_homefree 0BC4F8FF51F3167F06683FFB19008821C072983E
|
||||||
|
creation_rules:
|
||||||
|
- path_regex: secrets/[^/]+\.(yaml|json|env|ini)$
|
||||||
|
key_groups:
|
||||||
|
- pgp:
|
||||||
|
- *user_homefree
|
||||||
|
- *host_homefree
|
38
README.md
38
README.md
|
@ -1,8 +1,42 @@
|
||||||
HomeFree Sample Config
|
HomeFree Sample Config
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Clone this repo and modify configuration.nix as needed, then deploy with:
|
## Edit config
|
||||||
|
|
||||||
|
Clone this repo and modify configuration.nix as needed onto a freshly installed NixOS machine.
|
||||||
|
|
||||||
|
## Create secrets
|
||||||
|
|
||||||
|
- Generate appropriate GPG keys. You will need a private SSH key at ~/.ssh/id_rsa
|
||||||
|
|
||||||
```
|
```
|
||||||
./install.sh
|
./generate-gpg-keys.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Create secrets file in this folder. Use the following commands.
|
||||||
|
|
||||||
|
```
|
||||||
|
sops secrets/authentik.yaml
|
||||||
|
sops secrets/backup.yaml
|
||||||
|
sops secrets/ddclient.yaml
|
||||||
|
sops secrets/linkwarden.yaml
|
||||||
|
sops secrets/nextcloud.yaml
|
||||||
|
sops secrets/tailscale.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
And copy the contents from the appropriate file in the `secrets-unencrypted` folder, changing
|
||||||
|
the values as required.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
```
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## You can also deploy remotely to a machine running the Live CD
|
||||||
|
|
||||||
|
```
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
BUT, you'll have to check out the source onto the server and run the `./generate-gpg-keys.sh` script again after deployment.
|
||||||
|
|
3
build.sh
Executable file
3
build.sh
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
sudo nixos-rebuild switch --flake .#${HOSTNAME} -L
|
|
@ -1,7 +1,8 @@
|
||||||
{ lib, ... }:
|
{ config, lib, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./disk-config.nix
|
./disk-config.nix
|
||||||
|
./secrets.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
networking = {
|
networking = {
|
||||||
|
@ -24,6 +25,10 @@
|
||||||
authorizedKeys = [
|
authorizedKeys = [
|
||||||
"<replace me>"
|
"<replace me>"
|
||||||
];
|
];
|
||||||
|
domain = "example.com";
|
||||||
|
additionalDomains = [ "domain2.com" ];
|
||||||
|
timeZone = "America/Los_Angeles";
|
||||||
|
countryCode = "US";
|
||||||
};
|
};
|
||||||
|
|
||||||
network = {
|
network = {
|
||||||
|
@ -62,25 +67,17 @@
|
||||||
zones = [
|
zones = [
|
||||||
## Repace with your own domain
|
## Repace with your own domain
|
||||||
{
|
{
|
||||||
zone = "homefree.host";
|
zone = "example.com";
|
||||||
|
protocol = "hetzner";
|
||||||
|
username = "username";
|
||||||
|
passwordFile = config.sops.secrets."ddclient/ddclient-password".path;
|
||||||
|
}
|
||||||
|
## Repace with your own domain
|
||||||
|
{
|
||||||
|
zone = "domain2.com";
|
||||||
protocol = "hetzner";
|
protocol = "hetzner";
|
||||||
username = "erahhal";
|
username = "erahhal";
|
||||||
passwordFile = "/run/secrets/ddclient/ddclient-password";
|
passwordFile = config.sops.secrets."ddclient/ddclient-password".path;
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
wireguard = {
|
|
||||||
peers = [
|
|
||||||
{
|
|
||||||
name = "my-phone";
|
|
||||||
publicKey = "<replace me>=";
|
|
||||||
allowedIPs = [ "192.168.2.2/32"];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "bros-phone";
|
|
||||||
publicKey = "<replace me>";
|
|
||||||
allowedIPs = [ "192.168.2.3/32"];
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -90,15 +87,73 @@
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
authentik = {
|
||||||
|
enable = true;
|
||||||
|
secrets = {
|
||||||
|
environment = config.sops.secrets."authentik/authentik-env".path;
|
||||||
|
ldap-environment = config.sops.secrets."authentik/authentik-ldap-env".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
baikal = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
cryptpad = {
|
||||||
|
enable = true;
|
||||||
|
adminKeys = [
|
||||||
|
"<public signing key of user that can access the admin panel>"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
homeassistant = {
|
homeassistant = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
frigate = {
|
||||||
|
enable = true;
|
||||||
|
cameras = [
|
||||||
|
{
|
||||||
|
enable = true;
|
||||||
|
name = "gate";
|
||||||
|
path = "rtsp://10.0.0.15/11";
|
||||||
|
width = 1920;
|
||||||
|
height = 1080;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
gitea = {
|
gitea = {
|
||||||
enable = true;
|
enable = true;
|
||||||
public = true;
|
public = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
headscale = {
|
||||||
|
enable = true;
|
||||||
|
secrets = {
|
||||||
|
tailscale-key = config.sops.secrets."tailscale/key".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
headscale-ui = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
jellyfin = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
linkwarden = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
nextcloud = {
|
||||||
|
enable = true;
|
||||||
|
secrets = {
|
||||||
|
admin-password = config.sops.secrets."nextcloud/admin-password".path;
|
||||||
|
secret-file = config.sops.secrets."nextcloud/secret-file".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
radicale = {
|
radicale = {
|
||||||
enable = true;
|
enable = true;
|
||||||
};
|
};
|
||||||
|
@ -112,23 +167,41 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
proxied-hosts = [
|
service-config = [
|
||||||
{
|
{
|
||||||
label = "att";
|
label = "att";
|
||||||
|
reverse-proxy = {
|
||||||
|
enable = true;
|
||||||
subdomains = [ "att" ];
|
subdomains = [ "att" ];
|
||||||
https-domains = [ "homefree.host" "rahh.al" ];
|
https-domains = [ "homefree.host" "rahh.al" ];
|
||||||
host = "att.localdomain";
|
host = "att.localdomain";
|
||||||
port = 80;
|
port = 80;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
label = "yamaha-recevier-web-gui";
|
label = "yamaha-recevier-web-gui";
|
||||||
|
reverse-proxy = {
|
||||||
subdomains = [ "yamaha" ];
|
subdomains = [ "yamaha" ];
|
||||||
https-domains = [ "homefree-host" ];
|
https-domains = [ "homefree-host" ];
|
||||||
port = 443;
|
port = 443;
|
||||||
ssl = true;
|
ssl = true;
|
||||||
ssl-no-verify = true;
|
ssl-no-verify = true;
|
||||||
host = "yamaha.localdomain";
|
host = "yamaha.localdomain";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
backups = {
|
||||||
|
enable = true;
|
||||||
|
to-path = "/var/lib/backups";
|
||||||
|
extra-from-paths = [
|
||||||
|
"/mnt/nfs-volume/persona-files1"
|
||||||
|
"/mnt/nfs-volume/persona-files2"
|
||||||
|
"/home/username"
|
||||||
|
];
|
||||||
|
secrets = {
|
||||||
|
restic-password = config.sops.secrets."backup/restic-password".path;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
36
generate-gpg-keys.sh
Executable file
36
generate-gpg-keys.sh
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
#! /usr/bin/env nix-shell
|
||||||
|
#! nix-shell -i bash -p gnupg ssh-to-pgp
|
||||||
|
|
||||||
|
## Import user SSH key into GPG
|
||||||
|
|
||||||
|
cp ~/.ssh/id_rsa /tmp/id_rsa
|
||||||
|
ssh-keygen -p -N "" -f /tmp/id_rsa
|
||||||
|
{
|
||||||
|
IFS=$'\n' read -r -d '' CAPTURED_STDERR;
|
||||||
|
IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
|
||||||
|
} < <((printf '\0%s\0' "$(ssh-to-pgp -private-key -i /tmp/id_rsa | gpg --import --allow-non-selfsigned-uid --quiet)" 1>&2) 2>&1)
|
||||||
|
USER_GPG_FINGERPRINT=$(echo $CAPTURED_STDERR | awk '{print $1;}')
|
||||||
|
echo "FINGERPRINT: ${USER_GPG_FINGERPRINT}"
|
||||||
|
rm /tmp/id_rsa
|
||||||
|
# set ultimate trust level
|
||||||
|
echo "${USER_GPG_FINGERPRINT}:6:" | gpg --import-ownertrust
|
||||||
|
echo -e "adduid\n\n${USER}@localhost\n\nsave\nexit\n" | gpg --command-fd=0 --status-fd=1 --edit-key ${USER_GPG_FINGERPRINT}
|
||||||
|
|
||||||
|
sed -i -e "s/\&user .\+$/\&user $USER_GPG_FINGERPRINT/g" .sops.yaml
|
||||||
|
|
||||||
|
## Import host SSH key into GPG
|
||||||
|
|
||||||
|
# Get GPG fingerprint of server RSA key
|
||||||
|
# HOST_GPG_FINGERPRINT=$(sudo cat /etc/ssh/ssh_host_rsa_key | ssh-to-pgp -private-key | gpg --import --allow-non-selfsigned-uid --quiet 2> /dev/null | head -n 1)
|
||||||
|
{
|
||||||
|
IFS=$'\n' read -r -d '' CAPTURED_STDERR;
|
||||||
|
IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
|
||||||
|
} < <((printf '\0%s\0' "$(sudo cat /etc/ssh/ssh_host_rsa_key | ssh-to-pgp -private-key | gpg --import --allow-non-selfsigned-uid --quiet)" 1>&2) 2>&1)
|
||||||
|
HOST_GPG_FINGERPRINT=$(echo $CAPTURED_STDERR | awk '{print $1;}')
|
||||||
|
echo "FINGERPRINT: ${HOST_GPG_FINGERPRINT}"
|
||||||
|
# set ultimate trust level
|
||||||
|
echo "${HOST_GPG_FINGERPRINT}:6:" | gpg --import-ownertrust
|
||||||
|
echo -e "adduid\n\n${USER}@localhost\n\nsave\nexit\n" | gpg --command-fd=0 --status-fd=1 --edit-key ${HOST_GPG_FINGERPRINT}
|
||||||
|
|
||||||
|
sed -i -e "s/\&host_$HOST .\+$/\&host_$HOST $HOST_GPG_FINGERPRINT/g" .sops.yaml
|
||||||
|
|
15
secrets-unencrypted/authentik.yaml
Normal file
15
secrets-unencrypted/authentik.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
authentik:
|
||||||
|
postgres-password: <postgres password>
|
||||||
|
authentik-env: |-
|
||||||
|
AUTHENTIK_REDIS__HOST=localhost
|
||||||
|
AUTHENTIK_POSTGRESQL__HOST=localhost
|
||||||
|
AUTHENTIK_POSTGRESQL__USER=authentik
|
||||||
|
AUTHENTIK_POSTGRESQL__NAME=authentik
|
||||||
|
AUTHENTIK_POSTGRESQL__PASSWORD=<postgres password>
|
||||||
|
AUTHENTIK_SECRET_KEY=<authentik secret key>
|
||||||
|
AUTHENTIK_TOKEN=<authentik token>
|
||||||
|
authentik-ldap-env: |-
|
||||||
|
AUTHENTIK_HOST=http://localhost:9000
|
||||||
|
AUTHENTIK_TOKEN=<authenik ldap token>
|
||||||
|
AUTHENTIK_INSECURE=true
|
||||||
|
|
2
secrets-unencrypted/backup.yaml
Normal file
2
secrets-unencrypted/backup.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
backup:
|
||||||
|
restic-password: <change me>
|
2
secrets-unencrypted/ddclient.yaml
Normal file
2
secrets-unencrypted/ddclient.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ddclient:
|
||||||
|
ddclient-password: <change me>
|
4
secrets-unencrypted/linkwarden.yaml
Normal file
4
secrets-unencrypted/linkwarden.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
linkwarden:
|
||||||
|
env: |-
|
||||||
|
NEXTAUTH_SECRET=<changeme>
|
||||||
|
POSTGRESQL_PASSWORD=<postgres password>
|
8
secrets-unencrypted/nextcloud.yaml
Normal file
8
secrets-unencrypted/nextcloud.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
nextcloud:
|
||||||
|
admin-password: <change me>
|
||||||
|
secret-file: |-
|
||||||
|
{
|
||||||
|
"redis": {
|
||||||
|
"password": "secret"
|
||||||
|
}
|
||||||
|
}
|
2
secrets-unencrypted/tailscale.yaml
Normal file
2
secrets-unencrypted/tailscale.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
tailscale:
|
||||||
|
key: <change me>
|
76
secrets.nix
Normal file
76
secrets.nix
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
{ config, ... }:
|
||||||
|
{
|
||||||
|
## @TODO: What to do about owner field an restartUnits?
|
||||||
|
## This file should probably be generated by the homefree repo
|
||||||
|
## In fact everything in this repo should be generated by
|
||||||
|
## the config editor in homefree repo.
|
||||||
|
sops.secrets = {
|
||||||
|
"authentik/authentik-env" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/authentik.yaml;
|
||||||
|
owner = config.homefree.system.adminUsername;
|
||||||
|
path = "/run/secrets/authentik/authentik-env";
|
||||||
|
restartUnits = [ "authentik.service" ];
|
||||||
|
};
|
||||||
|
"authentik/authentik-ldap-env" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/authentik.yaml;
|
||||||
|
|
||||||
|
owner = config.homefree.system.adminUsername;
|
||||||
|
path = "/run/secrets/authentik/authentik-ldap-env";
|
||||||
|
restartUnits = [ "authentik-ldap.service" ];
|
||||||
|
};
|
||||||
|
"authentik/postgres-password" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/authentik.yaml;
|
||||||
|
};
|
||||||
|
"backup/restic-password" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/backup.yaml;
|
||||||
|
|
||||||
|
owner = config.homefree.system.adminUsername;
|
||||||
|
path = "/run/secrets/backup/restic-password";
|
||||||
|
restartUnits = [ "restic.service" ];
|
||||||
|
};
|
||||||
|
"ddclient/ddclient-password" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/ddclient.yaml;
|
||||||
|
|
||||||
|
owner = config.homefree.system.adminUsername;
|
||||||
|
path = "/run/secrets/ddclient/ddclient-password";
|
||||||
|
restartUnits = [ "ddclient.service" ];
|
||||||
|
};
|
||||||
|
"linkwarden/env" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/linkwarden.yaml;
|
||||||
|
|
||||||
|
owner = config.homefree.system.adminUsername;
|
||||||
|
path = "/run/secrets/linkwarden/env";
|
||||||
|
restartUnits = [ "linkwarden.service" ];
|
||||||
|
};
|
||||||
|
"nextcloud/admin-password" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/nextcloud.yaml;
|
||||||
|
|
||||||
|
owner = "nextcloud";
|
||||||
|
path = "/run/secrets/nextcloud/admin-password";
|
||||||
|
restartUnits = [ "nextcloud.service" ];
|
||||||
|
};
|
||||||
|
"nextcloud/secret-file" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/nextcloud.yaml;
|
||||||
|
|
||||||
|
owner = "nextcloud";
|
||||||
|
path = "/run/secrets/nextcloud/secret-file";
|
||||||
|
restartUnits = [ "nextcloud.service" ];
|
||||||
|
};
|
||||||
|
"tailscale/key" = {
|
||||||
|
format = "yaml";
|
||||||
|
sopsFile = ./secrets/tailscale.yaml;
|
||||||
|
|
||||||
|
owner = config.homefree.system.adminUsername;
|
||||||
|
path = "/run/secrets/tailscale/key";
|
||||||
|
restartUnits = [ "tailscale.service" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
0
secrets/.gitignore
vendored
Normal file
0
secrets/.gitignore
vendored
Normal file
22
secrets/README.md
Normal file
22
secrets/README.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
Secrets config
|
||||||
|
--------------
|
||||||
|
|
||||||
|
1. Generate appropriate GPG keys. You will need a private SSH key at ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
```
|
||||||
|
./generate-gpg-keys.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Create secrets file in this folder. Use the following commands:
|
||||||
|
|
||||||
|
```
|
||||||
|
sops authentik.yaml
|
||||||
|
sops backup.yaml
|
||||||
|
sops ddclient.yaml
|
||||||
|
sops linkwarden.yaml
|
||||||
|
sops nextcloud.yaml
|
||||||
|
sops tailscale.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
And copy the contents from the appropriate file in the `secrets-unencrypted` folder, changing
|
||||||
|
the values as required.
|
Loading…
Add table
Reference in a new issue