Compare commits

...

3 commits

Author SHA1 Message Date
Jet Pham
3d47608a05
feat: add website 2026-03-09 20:08:31 -07:00
Jet Pham
5744860ade
feat: move mymx dns to the mymx repo 2026-03-09 20:08:17 -07:00
Jet Pham
8e174ba500
feat: migrate to agenix for secret management 2026-03-09 19:57:15 -07:00
23 changed files with 239 additions and 131 deletions

1
.envrc
View file

@ -1 +1,2 @@
use flake use flake
export RULES="$PWD/agenix.nix"

View file

@ -16,42 +16,47 @@ services:
## Deployment ## Deployment
This repository uses **untracked secrets**, so you must build the system locally before deploying. Secrets are managed with [agenix](https://github.com/ryantm/agenix) — encrypted in git, decrypted on the server at runtime.
### 1. Setup Secrets ### 1. Setup Secrets
1. `cp secrets/secrets.nix.example secrets/secrets.nix`
2. Fill in the values (generate random keys, etc).
- `openssl rand -base64 32` is a good way to make a new key
- `tailscaleKey` must be a **Reusable** key from the Tailscale admin console.
### 2. Verify Configuration Locally Key mapping is in `agenix.nix`. The `agenix` CLI and `RULES` env var are provided by the devShell via direnv.
Because `secrets/secrets.nix` is untracked by git, standard `nix flake check` will fail.
To build the server configuration locally and ensure there are no syntax or evaluation errors before pushing to the server, run:
```bash ```bash
nix build path:.#nixosConfigurations.extremist-software.config.system.build.toplevel --impure --dry-run direnv allow
agenix -e secrets/forgejo-db.age
agenix -e secrets/stalwart-admin.age
agenix -e secrets/searx-env.age # SEARXNG_SECRET=<value>
agenix -e secrets/tailscale-key.age
agenix -e secrets/grafana-secret.age
agenix -e secrets/matrix-macaroon.age # macaroon_secret_key: "<value>"
agenix -e secrets/ntfy-admin-hash.age
agenix -e secrets/mymx-webhook.age
```
To edit an existing secret, run the same command again.
### 2. Verify Configuration
```bash
nix flake check
``` ```
### 3. Initial Install (Wipe & Install) ### 3. Initial Install (Wipe & Install)
Run this command to build and deploy. **Warning: Wipes the server disk.**
**Warning: Wipes the server disk.**
```bash ```bash
# Replace <TARGET_IP> with your server's IP
nix run github:nix-community/nixos-anywhere -- --store-paths \ nix run github:nix-community/nixos-anywhere -- --store-paths \
$(nix build path:.#nixosConfigurations.extremist-software.config.system.build.diskoScript --impure --print-out-paths --no-link) \ $(nix build path:.#nixosConfigurations.extremist-software.config.system.build.diskoScript --print-out-paths --no-link) \
$(nix build path:.#nixosConfigurations.extremist-software.config.system.build.toplevel --impure --print-out-paths --no-link) \ $(nix build path:.#nixosConfigurations.extremist-software.config.system.build.toplevel --print-out-paths --no-link) \
root@<TARGET_IP> | tee install.log root@<TARGET_IP> | tee install.log
``` ```
### 4. Update Existing Server (No Wipe) ### 4. Update Existing Server
Once the server is running NixOS, use the `nhs` script to push updates. This repository provides `nhs` and `nh` via `direnv` (loaded from `flake.nix` devShell), so just run `direnv allow` first.
`nhs` and `nh` are provided via direnv.
```bash ```bash
# Update via Tailscale (uses nhs convenience script)
nhs nhs
# Or manually via IP
nh os switch --hostname extremist-software --target-host root@<TARGET_IP> --impure path:.
``` ```
repo uses `impure` build to load `secrets/secrets.nix` directly. no encrypted secrets in git.

13
agenix.nix Normal file
View file

@ -0,0 +1,13 @@
let
server = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAING219cDKTDLaZefmqvOHfXvYloA/ErsCGE0pM022vlB";
jet = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu";
in {
"secrets/forgejo-db.age".publicKeys = [ server jet ];
"secrets/stalwart-admin.age".publicKeys = [ server jet ];
"secrets/searx-env.age".publicKeys = [ server jet ];
"secrets/tailscale-key.age".publicKeys = [ server jet ];
"secrets/grafana-secret.age".publicKeys = [ server jet ];
"secrets/matrix-macaroon.age".publicKeys = [ server jet ];
"secrets/ntfy-admin-hash.age".publicKeys = [ server jet ];
"secrets/mymx-webhook.age".publicKeys = [ server jet ];
}

View file

@ -12,13 +12,19 @@
./modules/ntfy.nix ./modules/ntfy.nix
./modules/uptime-kuma.nix ./modules/uptime-kuma.nix
# mymx module is imported via flake input in flake.nix # mymx module is imported via flake input in flake.nix
./secrets/secrets-scheme.nix
# Impure Secrets
./secrets/secrets.nix
]; ];
# ... (rest of imports block replaced by ./secrets/secrets.nix being added to imports) # Agenix secrets
age.secrets = {
forgejo-db.file = ./secrets/forgejo-db.age;
stalwart-admin = { file = ./secrets/stalwart-admin.age; owner = "stalwart-mail"; };
searx-env.file = ./secrets/searx-env.age;
tailscale-key.file = ./secrets/tailscale-key.age;
grafana-secret = { file = ./secrets/grafana-secret.age; owner = "grafana"; };
matrix-macaroon = { file = ./secrets/matrix-macaroon.age; owner = "matrix-synapse"; };
ntfy-admin-hash.file = ./secrets/ntfy-admin-hash.age;
mymx-webhook = { file = ./secrets/mymx-webhook.age; owner = "mymx"; };
};
# Bootloader # Bootloader
boot.loader.grub.enable = true; boot.loader.grub.enable = true;
@ -36,7 +42,7 @@
# Users # Users
users.users.root.openssh.authorizedKeys.keys = [ users.users.root.openssh.authorizedKeys.keys = [
config.mySecrets.sshPublicKey "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE40ISu3ydCqfdpb26JYD5cIN0Fu0id/FDS+xjB5zpqu"
]; ];
# SSH - Secure it # SSH - Secure it
@ -77,9 +83,17 @@
clean.extraArgs = "--keep 2"; clean.extraArgs = "--keep 2";
}; };
# Automatic upgrades
system.autoUpgrade = {
enable = true;
dates = "04:00";
allowReboot = false;
};
# System # System
system.stateVersion = "24.05"; system.stateVersion = "24.05";
nix.settings.experimental-features = [ "nix-command" "flakes" ]; nix.settings.experimental-features = [ "nix-command" "flakes" ];
services.postgresql.package = pkgs.postgresql_15;
nixpkgs.config.allowUnfree = true; # Allow unfree packages (Minecraft, etc.) nixpkgs.config.allowUnfree = true; # Allow unfree packages (Minecraft, etc.)
# Time # Time
@ -89,15 +103,14 @@
zramSwap.enable = true; zramSwap.enable = true;
zramSwap.memoryPercent = 50; zramSwap.memoryPercent = 50;
# Secrets handled via ./secrets.nix importing to config.mySecrets services.tailscale.authKeyFile = config.age.secrets.tailscale-key.path;
environment.etc."secrets/tailscale-auth".text = config.mySecrets.tailscaleKey;
environment.etc."secrets/mymx-webhook".text = config.mySecrets.mymxWebhookSecret;
services.tailscale.authKeyFile = "/etc/secrets/tailscale-auth";
# MyMX # MyMX
services.jetpham-website.enable = true;
services.mymx = { services.mymx = {
enable = true; enable = true;
webhookSecretFile = "/etc/secrets/mymx-webhook"; webhookSecretFile = config.age.secrets.mymx-webhook.path;
}; };
# Allow Tailscale traffic # Allow Tailscale traffic

82
flake.lock generated
View file

@ -1,5 +1,50 @@
{ {
"nodes": { "nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1770165109,
"narHash": "sha256-9VnK6Oqai65puVJ4WYtCTvlJeXxMzAp/69HhQuTdl/I=",
"owner": "ryantm",
"repo": "agenix",
"rev": "b027ee29d959fda4b60b57566d64c98a202e0feb",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1744478979,
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"disko": { "disko": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -20,6 +65,27 @@
"type": "github" "type": "github"
} }
}, },
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1745494811,
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"mymx": { "mymx": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -59,6 +125,7 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"agenix": "agenix",
"disko": "disko", "disko": "disko",
"mymx": "mymx", "mymx": "mymx",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
@ -84,6 +151,21 @@
"repo": "rust-overlay", "repo": "rust-overlay",
"type": "github" "type": "github"
} }
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View file

@ -10,7 +10,11 @@
mymx.url = "git+https://git.extremist.software/jet/mymx"; mymx.url = "git+https://git.extremist.software/jet/mymx";
mymx.inputs.nixpkgs.follows = "nixpkgs"; mymx.inputs.nixpkgs.follows = "nixpkgs";
website.url = "git+https://git.extremist.software/jet/website";
website.inputs.nixpkgs.follows = "nixpkgs";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
}; };
outputs = { self, nixpkgs, disko, ... }@inputs: { outputs = { self, nixpkgs, disko, ... }@inputs: {
@ -20,6 +24,8 @@
modules = [ modules = [
disko.nixosModules.disko disko.nixosModules.disko
inputs.mymx.nixosModules.default inputs.mymx.nixosModules.default
inputs.website.nixosModules.default
inputs.agenix.nixosModules.default
./disk-config.nix ./disk-config.nix
./configuration.nix ./configuration.nix
@ -29,11 +35,12 @@
devShells.x86_64-linux.default = let devShells.x86_64-linux.default = let
pkgs = nixpkgs.legacyPackages.x86_64-linux; pkgs = nixpkgs.legacyPackages.x86_64-linux;
deploy = pkgs.writeShellScriptBin "nhs" '' deploy = pkgs.writeShellScriptBin "nhs" ''
nh os switch --hostname extremist-software --target-host root@extremist-software --impure path:. "$@" nh os switch --hostname extremist-software --target-host root@extremist-software path:. "$@"
''; '';
in pkgs.mkShell { in pkgs.mkShell {
packages = [ packages = [
pkgs.nh pkgs.nh
inputs.agenix.packages.x86_64-linux.default
deploy deploy
]; ];
}; };

View file

@ -125,18 +125,6 @@
''; '';
}; };
"mymx.extremist.software" = {
extraConfig = ''
rate_limit {
zone mymx_per_ip {
key {remote.ip}
events 60
window 1m
}
}
reverse_proxy localhost:4002
'';
};
"matrix.extremist.software" = { "matrix.extremist.software" = {
extraConfig = '' extraConfig = ''
@ -170,5 +158,4 @@
# Ensure Caddy can read the certs too now that they are in the acme group # Ensure Caddy can read the certs too now that they are in the acme group
users.users.caddy.extraGroups = [ "acme" ]; users.users.caddy.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [ 80 443 ];
} }

View file

@ -14,12 +14,8 @@
}; };
# You can configure SMTP here using secrets if needed # You can configure SMTP here using secrets if needed
}; };
# Secret for DB password database.passwordFile = config.age.secrets.forgejo-db.path;
settings.database.PASSWORD = config.mySecrets.forgejoDb;
}; };
services.postgresql = { services.postgresql.enable = true;
enable = true;
package = pkgs.postgresql_15;
};
} }

View file

@ -43,7 +43,7 @@
authentication.fallback-admin = { authentication.fallback-admin = {
user = "admin"; user = "admin";
secret = config.mySecrets.stalwartAdmin; secret = "%{file:/run/agenix/stalwart-admin}%";
}; };
}; };
}; };
@ -51,10 +51,4 @@
# Allow Stalwart to read the ACME certificate procured for Caddy # Allow Stalwart to read the ACME certificate procured for Caddy
systemd.services.stalwart.serviceConfig.SupplementaryGroups = [ "acme" ]; systemd.services.stalwart.serviceConfig.SupplementaryGroups = [ "acme" ];
# Open Firewalls for Mail
networking.firewall.allowedTCPPorts = [
993 # IMAP (Secure)
4190 # Sieve
8080 # Admin UI (Reverse proxied, but good to double check loopback)
];
} }

View file

@ -3,6 +3,7 @@
{ {
services.matrix-synapse = { services.matrix-synapse = {
enable = true; enable = true;
extraConfigFiles = [ config.age.secrets.matrix-macaroon.path ];
settings = { settings = {
server_name = "extremist.software"; server_name = "extremist.software";
public_baseurl = "https://matrix.extremist.software"; public_baseurl = "https://matrix.extremist.software";
@ -24,8 +25,6 @@
]; ];
enable_registration = false; enable_registration = false;
registration_shared_secret = "extremist_software_admin_creation";
macaroon_secret_key = config.mySecrets.matrixMacaroon;
database = { database = {
name = "psycopg2"; name = "psycopg2";
allow_unsafe_locale = true; allow_unsafe_locale = true;

View file

@ -31,7 +31,7 @@
domain = "status.extremist.software"; domain = "status.extremist.software";
}; };
security = { security = {
secret_key = config.mySecrets.grafanaSecret; secret_key = "$__file{/run/agenix/grafana-secret}";
}; };
}; };
provision = { provision = {

View file

@ -1,4 +1,4 @@
{ config, pkgs, ... }: { config, pkgs, lib, ... }:
{ {
services.ntfy-sh = { services.ntfy-sh = {
@ -10,12 +10,22 @@
auth-file = "/var/lib/ntfy-sh/user.db"; auth-file = "/var/lib/ntfy-sh/user.db";
auth-default-access = "deny-all"; auth-default-access = "deny-all";
enable-login = true; enable-login = true;
auth-users = [
"jet:${config.mySecrets.ntfyAdminHash}:admin"
];
auth-access = [ auth-access = [
"*:up*:write-only" "*:up*:write-only"
]; ];
}; };
}; };
# Patch the generated config at runtime to inject the admin bcrypt hash
systemd.services.ntfy-sh = {
serviceConfig.RuntimeDirectory = "ntfy-sh";
serviceConfig.ExecStartPre = let
script = pkgs.writeShellScript "ntfy-patch-config" ''
cp /etc/ntfy/server.yml /run/ntfy-sh/server.yml
HASH=$(cat ${config.age.secrets.ntfy-admin-hash.path})
printf '\nauth-users:\n - "jet:%s:admin"\n' "$HASH" >> /run/ntfy-sh/server.yml
'';
in [ "+${script}" ];
serviceConfig.ExecStart = lib.mkForce "${pkgs.ntfy-sh}/bin/ntfy serve --config /run/ntfy-sh/server.yml";
};
} }

View file

@ -5,11 +5,12 @@
enable = true; enable = true;
package = pkgs.searxng; package = pkgs.searxng;
redisCreateLocally = true; redisCreateLocally = true;
environmentFile = config.age.secrets.searx-env.path;
settings = { settings = {
server = { server = {
port = 8082; port = 8082;
bind_address = "127.0.0.1"; bind_address = "127.0.0.1";
secret_key = config.mySecrets.searxKey; secret_key = "@SEARXNG_SECRET@";
}; };
search = { search = {
request_timeout = 1.5; request_timeout = 1.5;

7
secrets/forgejo-db.age Normal file
View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg mtSxHYyX33fx/dUTpNGgu4ah3X/I6zTB0amu7Ji+iWU
6EXDWMEoDuDZ36rYqUR52IQFASZb5s0bm3KRyAKIXUg
-> ssh-ed25519 Ziw7aw zqjgjZGh9C3H/gpuLx+dUC9EngSoHB/feiyCgqss+F4
MyCY88yFfDSqAr0PbYSg/FbHo+B6rxXBPkVxczgW93E
--- qGC9Dxmqtgm92IqNd3azWYEtkMEwwWRNsuXow6oZjlE
ìX)1±s™tr(fæÕPµ,Û78Öƒ™ ŠVøÍÖ”·1õ1&%ŒÃ(¶Fë-úˆD"(7ów=äéþîßxmÙžãväS

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg 6TMM/HxgvFAlsOOJuEhoKfnN5CcjEvck9BKUXTNQsjk
Y0G/GK6+t5jFK+cPqovD/oxs1ZLRAprstr27pZ6mb0c
-> ssh-ed25519 Ziw7aw TQWn+XR8FHTv2+ol4id6hcL3C+Jk92jsB2hHFacoD3o
fr+xO4DvOHLSPn05u6JZi++wBABw0z9WqghdwJ62pz0
--- PS3uOR8IZPAUoS8XA5WsBcCsLEfTxwS+vW6eHdZy3Fo
£È¯Ê”¼1È/Ûœ<C39B>%®öÆr¹Ë)+í°Ãý0ÚWg¯?hÌJÍYãåÄœ¢Û®öçiÝŒ%[ê=æyÔd·à˜w§€¦õ,xS

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg gbXdVVx0trOnWR5v3V4jjfP58B5jXWKwoi8Da2JKx1Y
s8rPw207y5TzjlLPXm+gG+eQqBqh6geeFvnn4iH3s84
-> ssh-ed25519 Ziw7aw 99vuNfyVaByhU5bwxJTuoxeYoQWryP36ddAd/fZOhBY
hdtoLgoFVslZpm9luo3Edns4hYMQESIReI7laFDjeOQ
--- Zgwav28km0/q1wX2FZDT5xpVQurkcjqu0lmOWr8ZH38
K)-¢áÊy•˜.uƒì€è³%Tµo(ñ:^ßE°p"ëé9>ºj´#ÔF­ë•ž8Wž-ñ S1jIò§4·Án
2

7
secrets/mymx-webhook.age Normal file
View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg EC9vi+nqoSqUHET3/4fWoiuW9vTZo5XOB1dc+Fe36U0
FYKWAiLaAbotst3AuOulpgqAg+JHUqD3uWWLk7hxrH8
-> ssh-ed25519 Ziw7aw naV+WKfldJhOnIzz13Q9zKSK+z+oRhiVfeEYuG+dtS0
/GLmF3ws0aUsSVTAv9zzzD+8Cp/IkMlHWFzv1CbgSiM
--- PdqmGwHvR/R0tqf46e1ZJl/QIzB1qadFtNyONpoQl30
wnÿ4Âò@ŠýÐÞD~Ír³×Ë*þj·®!„-*½ûv})0<30>±ú´÷ÞÏÉFÛ7)®}rá/>Häè/3åS$ }ÅÙµìû«@¯Ð

View file

@ -0,0 +1,8 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg Cccnzwl3XTJOW5+IuxDAsiI0L8Fy8JhJnpdERg9qgXU
vgvQdUbmwRna+gLjGsmsheGGeG2KIxsWoDw4XAVSjEA
-> ssh-ed25519 Ziw7aw vMnvy4HgMvhwALtUI14DmX6LbQiLXROINbJPlVfoW0g
FGxDYfiejy2a5W9eZKww1YgQ3mQFTj/mORwBwTsEW80
--- lThDR400zmmiBqnNmi2QKp2l3z3wCZ0jAxqIROLWn74
?¿3JÀ4zýrˆK
œk×Ï[ˆ€Àå“5D/Ò×DTX+lü<1F>©frjг„± ½v©Î€›ñ³,ø…¤•#ê“z*}*Q°Ç¤Jèœ´åÆ¡ŽX1<JÑ¿n<>

9
secrets/searx-env.age Normal file
View file

@ -0,0 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg s5orwA5GrqKWguh/hIhdJGyUP+Vx7iGqoQKuEO48DiY
K+CrOTAFATdTsax+GwQBjJkni4IYDnfPdsVop8eMkKs
-> ssh-ed25519 Ziw7aw 27Zr3vWFaQNfeTxJmNajNkigC5RUcwgz6Qs7183fUTM
Bmj69hGO8tIZUJG5tiXqZHy+Ft6T5J2iJAYIxyYxZj8
--- rC5PWCFkjuuPrSWRImrY7IzODjxevS30MFSXdV5qpG4
#N¥<4E>R!F”²3{
Š1bF?ùœÇ¯ßg!o}$…iR½ƒ5øÞ×
¶ûçjÈõýMÿgÕqµÝÈS,­_r:ªqf

View file

@ -1,45 +0,0 @@
{ lib, ... }:
with lib;
{
options.mySecrets = {
forgejoDb = mkOption {
type = types.str;
description = "Forgejo Database Password";
};
stalwartAdmin = mkOption {
type = types.str;
description = "Stalwart Mail Admin Password";
};
searxKey = mkOption {
type = types.str;
description = "Searx Secret Key";
};
tailscaleKey = mkOption {
type = types.str;
description = "Tailscale Auth Key";
};
sshPublicKey = mkOption {
type = types.str;
description = "SSH Public Key for Root User";
};
grafanaSecret = mkOption {
type = types.str;
description = "Grafana Secret Key for security";
};
matrixMacaroon = mkOption {
type = types.str;
description = "Macaroon Secret Key for Matrix Synapse";
};
ntfyAdminHash = mkOption {
type = types.str;
description = "Bcrypt hash for ntfy admin user";
};
mymxWebhookSecret = mkOption {
type = types.str;
description = "MyMX Webhook Secret for signature verification";
};
};
}

View file

@ -1,17 +0,0 @@
{ pkgs, config, lib, ... }:
{
# Copy this file to secrets.nix and fill in real values
mySecrets = {
forgejoDb = "changeme_forgejo_db";
stalwartAdmin = "changeme_stalwart_admin";
searxKey = "changeme_searx_secret";
minecraftRcon = "changeme_rcon";
tailscaleKey = "tskey-auth-PLACEHOLDER";
sshPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...";
grafanaSecret = "changeme_grafana_secret";
matrixMacaroon = "changeme_matrix_macaroon_secret_key";
ntfyAdminHash = "changeme_bcrypt_hash_from_ntfy_user_hash";
mymxWebhookSecret = "changeme_mymx_webhook_secret";
};
}

View file

@ -0,0 +1,9 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg E7BMWjT2cbnomhydZCaRs5EMKoDGyU9O+NAvKHjflzs
8yl7y2iXNrBuCyT05sOatAHiJhizUSFgFJt0NlMZ9pY
-> ssh-ed25519 Ziw7aw PTAzjpRIfFk86q3docaVsh4CbXjDiCNJR2Of8YAYSBQ
5WLY3czA6TKBJyTMwGVxSR7kuIVxBDMaKZ41VYgGhN8
--- DHfY8BOaO+vb2MYxX/3XbgAIlwilFEPLRGUlZGJh1g0
<04>{<7B>-L^ツ粮8ホハ;ネヌモヌ碓
・7Лy囹aユ]€<EFBE9A>,<2C> jEス\<5C><>\セ
:"yX<゙ 7Xネオ綏ユ浜M

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 uKftJg c78IHZJHcr9y//w/tqXHsuwqPjclpCPeGUzCQ1Huwkw
h/3PruYSzkFbrGPPLrYpqoo+btj2NAHS0BlJk//U8x0
-> ssh-ed25519 Ziw7aw O/aFm27iQeYXA04hqRNGcoUy0JmAAKDLsK1Bp/p/miY
EBqXc31Ymh3YgjagBvICwQvX6KKwkkMF3Tv7XqsAvPs
--- sIkeKQZHLKTLXEVZdwmP/FpjbUWyyIZYx2/nKswFWoQ
ö6¥àô§™v<>†Iú.`<60>\cZÒÕB³á;»‰x«mHR©€3ÕoÁ§· Ó£T«qÇeÐldÇ"'«ý£\I]T2ÑKõl ùú¾¯§¨â~ÜÂO±B0Æ