Compare commits

...

88 Commits

Author SHA1 Message Date
390bdaaf51 resilio: update to unstable module
All checks were successful
flake / flake (push) Successful in 2m19s
Currently this pins `rslsync`'s group ID using https://github.com/NixOS/nixpkgs/pull/350055
2024-11-09 21:03:56 +00:00
ba9d54ddab chore(deps): lock file maintenance
All checks were successful
flake / flake (push) Successful in 2m7s
2024-11-09 15:20:26 +00:00
843802bcb7 backups: include more git repos
All checks were successful
flake / flake (push) Successful in 1m45s
2024-11-08 12:23:54 +00:00
a07c493802 stinger: update firewall for homeassistant
All checks were successful
flake / flake (push) Successful in 1m47s
2024-11-06 20:12:59 +00:00
3a2d6f4e2e stinger: enable bluetooth
All checks were successful
flake / flake (push) Successful in 1m35s
2024-11-06 10:34:33 +00:00
a383e013c6 homeassistant: microserver.home -> stinger.pop
All checks were successful
flake / flake (push) Successful in 2m0s
2024-11-06 01:36:14 +00:00
ed3b9019f2 homeassistant: backup database
All checks were successful
flake / flake (push) Successful in 1m36s
2024-11-06 01:05:52 +00:00
a3fd10be31 stinger: init host
All checks were successful
flake / flake (push) Successful in 1m36s
2024-11-05 22:10:12 +00:00
79a3c62924 defaults: enable all firmware
All checks were successful
flake / flake (push) Successful in 1m37s
2024-11-05 22:10:01 +00:00
0761162e34 chore(deps): update determinatesystems/nix-installer-action action to v15
All checks were successful
flake / flake (push) Successful in 1m31s
2024-11-04 23:01:03 +00:00
2999a5f744 merlin: init host
All checks were successful
flake / flake (push) Successful in 1m29s
2024-11-04 22:35:55 +00:00
5146d6cd6f lavd: finish cleanup
All checks were successful
flake / flake (push) Successful in 1m27s
2024-11-03 18:36:01 +00:00
3ebba9d7a5 home: enable zoxide
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-31 23:00:45 +00:00
1b5f342aab home-manager: enable ssh-agent
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-31 22:32:57 +00:00
87d311dabe sched_ext: switch to unstable for packages
All checks were successful
flake / flake (push) Successful in 2m3s
2024-10-31 21:59:09 +00:00
0cf7aa1760 tang: remove tywin ip
All checks were successful
flake / flake (push) Successful in 1m24s
Missed this when cleaning up. We should probably get these static IPs from
authoritative DNS like Tailscale IPs, then they wouldn't have been missed. We
can then construct the static IP mappings from this, moving some stuff out of
router/default.nix.
2024-10-29 23:35:20 +00:00
363b8fe3c0 tywin.storage: delete
All checks were successful
flake / flake (push) Successful in 1m26s
2024-10-29 23:24:19 +00:00
ca57201ad5 tmux: increase history-limit
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-29 22:54:30 +00:00
32de6b05be tmux: add kernel rev and extended hostname to status-right
All checks were successful
flake / flake (push) Successful in 1m31s
2024-10-29 22:48:12 +00:00
0149d53da2 restic: backup to backblaze
All checks were successful
flake / flake (push) Successful in 1m33s
2024-10-27 21:24:20 +00:00
c7efa1fad4 restic: backup to wasabi
Some checks failed
flake / flake (push) Has been cancelled
2024-10-27 20:09:45 +00:00
dbc2931052 restic: split out common behaviour
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-27 15:57:07 +00:00
817cc3f356 phoenix: temporarily add a password to debug boot issues
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-27 15:37:52 +00:00
c33d5c2edd secrets: re-encrypt with boron user key
All checks were successful
flake / flake (push) Successful in 1m29s
2024-10-27 00:43:47 +01:00
187c15b5ab backups: update scripts for new host/path
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-26 23:47:34 +01:00
fc1fb7b528 sapling: set default merge style to :merge3
All checks were successful
flake / flake (push) Successful in 1m31s
2024-10-26 19:26:48 +01:00
caa3128310 home-manager: pass through nixos stateVersion if >24.05
All checks were successful
flake / flake (push) Successful in 1m27s
home-manager currently has a pinned stateVersion on all hosts, even though many
of the hosts were initialised after that point. Create a condition such that
any hosts initialised after 24.05 (the latest currently host) will use that
version in home-manager instead of pinning to 22.11.

Any future users can pass the stateVersion through without the `if`.

Test plan:
```
# system.stateVersion = "23.11";
$ nix eval '.#nixosConfigurations."boron.cx.ts.hillion.co.uk".config.home-manager.users.root.home.stateVersion'
"22.11"
```
```
# system.stateVersion = "24.05";
$ nix eval '.#nixosConfigurations."phoenix.st.ts.hillion.co.uk".config.home-manager.users.root.home.stateVersion'
"22.11"
```
```
# system.stateVersion = "24.11"; // no-commit change
$ nix eval '.#nixosConfigurations."phoenix.st.ts.hillion.co.uk".config.home-manager.users.root.home.stateVersion'
nix eval '.#nixosConfigurations."phoenix.st.ts.hillion.co.uk".config.home-manager.users.root.home.stateVersion'
error:
       ...
       (stack trace truncated; use '--show-trace' to show the full trace)

       error: A definition for option `home-manager.users.root.home.stateVersion' is not of type `one of "18.09", "19.03", "19.09", "20.03", "20.09", "21.03", "21.05", "21.11", "22.05", "22.11", "23.05", "23.11", "24.05"'. Definition values:
       - In `/nix/store/8dhsknmlnv571bg100j9v9yqq1nnh346-source/modules/home/default.nix': "24.11"
```
2024-10-26 19:13:08 +01:00
72e7aead94 sapling: set ui.username
All checks were successful
flake / flake (push) Successful in 1m29s
2024-10-26 18:49:14 +01:00
b5489abf98 ssh: allow on all ports for sodium/phoenix
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-26 18:15:31 +01:00
9970dc413d boron: persist ssh key
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-26 15:04:14 +01:00
b3fb80811c chore(deps): lock file maintenance
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-26 14:00:16 +00:00
4c7a99bfb7 home-manager: enable neovim
All checks were successful
flake / flake (push) Successful in 1m29s
2024-10-26 00:39:35 +01:00
edad7248a5 chore(deps): update actions/checkout action to v4.2.2
All checks were successful
flake / flake (push) Successful in 1m25s
2024-10-24 23:00:54 +00:00
ce6c9a25c5 flake: fix unstable path pointing at github instead of gitea
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-24 09:39:20 +01:00
3a0c8effbb flake: use generic branch from forked nixpkgs
All checks were successful
flake / flake (push) Successful in 1m29s
Rather than pulling a specific feature branch into `nixpkgs-unstable`, pull a branch for `nixos-unstable`. Then we can cherry pick and rebase multiple features in the `nixpkgs` fork and keep up more easily with upstream.

The preferred method here would be a list of PRs or URLs to patch into the flake input, but that doesn't seem to be an option.

This change adds in the resilio gid PR, but is otherwise unchanged.
2024-10-23 23:27:53 +01:00
172e6c7415 router: enable ssh on eth0 and add work mbp key
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-23 21:06:24 +01:00
9a18124847 phoenix: enable zswap
All checks were successful
flake / flake (push) Successful in 1m25s
2024-10-21 23:00:04 +01:00
efbf9575f2 phoenix: enable plex
All checks were successful
flake / flake (push) Successful in 1m25s
2024-10-21 22:27:12 +01:00
e03ce4e26c phoenix: enable resilio sync and backups
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-21 20:49:13 +01:00
b18ae44ccb resilio: place storagePath in directoryPath by default
All checks were successful
flake / flake (push) Successful in 1m25s
2024-10-21 08:54:20 +01:00
e80ef10eb7 resilio: calculate default deviceName automatically
Some checks failed
flake / flake (push) Has been cancelled
2024-10-21 08:54:20 +01:00
26beb4116a phoenix: serve restic
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-21 00:39:36 +01:00
1822d07cfe phoenix: enable downloads
All checks were successful
flake / flake (push) Successful in 1m26s
2024-10-21 00:20:42 +01:00
a6efbb1b68 phoenix: import practical-defiant-coffee zpool
All checks were successful
flake / flake (push) Successful in 1m24s
2024-10-20 20:07:59 +01:00
6fe4ca5b61 phoenix: mount disk btrfs partitions and add chia
All checks were successful
flake / flake (push) Successful in 1m23s
2024-10-20 20:07:59 +01:00
3e8dcd359e secrets: clean up tywin secrets
All checks were successful
flake / flake (push) Successful in 1m26s
2024-10-20 20:07:16 +01:00
86bca8ce1c tywin: prepare for zpool export
All checks were successful
flake / flake (push) Successful in 1m23s
2024-10-20 19:37:26 +01:00
ee3b420220 backups/git: move tywin->phoenix
All checks were successful
flake / flake (push) Successful in 1m24s
2024-10-20 17:40:20 +01:00
58ce44df6b phoenix: add chia
All checks were successful
flake / flake (push) Successful in 1m24s
2024-10-20 16:29:55 +01:00
f34592926e phoenix: init host
All checks were successful
flake / flake (push) Successful in 1m24s
2024-10-20 16:07:21 +01:00
7dd820685f backup-git: fix systemd timer
All checks were successful
flake / flake (push) Successful in 1m28s
2024-10-19 18:30:57 +01:00
4047b0d8b2 router: reserve ips for nanokvms
All checks were successful
flake / flake (push) Successful in 1m27s
2024-10-19 16:53:35 +01:00
d7a8562c7d restic: modularise server component
All checks were successful
flake / flake (push) Successful in 1m25s
2024-10-19 15:24:32 +01:00
ea163448df homeassistant: enable waze
All checks were successful
flake / flake (push) Successful in 1m23s
2024-10-19 00:39:33 +01:00
a8288ec678 scx_layered: get from forked nixpkgs
All checks were successful
flake / flake (push) Successful in 1m24s
2024-10-18 13:56:40 +01:00
50a8411ac8 nixos: add nixpkgs-unstable to flake registry
All checks were successful
flake / flake (push) Successful in 1m15s
2024-10-13 00:33:57 +01:00
6f5b9430c9 prometheus: add alert for resilio sync going down
All checks were successful
flake / flake (push) Successful in 1m17s
2024-10-12 21:39:00 +01:00
33cdcdca0a prometheus: enable systemd collector
All checks were successful
flake / flake (push) Successful in 1m15s
2024-10-12 15:27:13 +01:00
c42a4e5297 chore(deps): lock file maintenance
All checks were successful
flake / flake (push) Successful in 1m43s
2024-10-12 13:37:53 +00:00
2656c0dba9 scx_lavd: package and ship
All checks were successful
flake / flake (push) Successful in 1m18s
2024-10-12 00:54:02 +01:00
961acd80d7 scx_layered: package and ship
All checks were successful
flake / flake (push) Successful in 1m14s
2024-10-11 20:15:55 +01:00
eb07e4c4fd chore(deps): update actions/checkout action to v4.2.1
All checks were successful
flake / flake (push) Successful in 1m15s
2024-10-07 23:00:25 +00:00
4eaae0fa75 isponsorblocktv: deploy docker container
All checks were successful
flake / flake (push) Successful in 1m18s
2024-10-06 21:38:06 +01:00
72955e2377 homeassistant: announce locally and deploy to hallway tablet
All checks were successful
flake / flake (push) Successful in 1m17s
2024-10-06 20:43:48 +01:00
0a2330cb90 www: fix cloning script
All checks were successful
flake / flake (push) Successful in 1m15s
2024-10-06 16:35:59 +01:00
3d8a60da5b sched_ext: bump kernel to 6.12-rc1
All checks were successful
flake / flake (push) Successful in 1m13s
Removes the custom kernel features and requires any host running
sched_ext to pull a kernel at least 6.12. Looks at
pkgs.unstable.linuxPackages first, if that's too old it falls back to
pkgs.linuxPackages_latest, and if that's too old it goes for
pkgs.unstable.linuxPackages_testing.

The plan is to leave `boot.kernelPackages` alone if new enough, but
we'll keep the assertion. Some schedulers might require more specific
kernel constraints in the future.
2024-10-03 00:17:59 +01:00
c0e331bf80 boron: enable resilio sync
All checks were successful
flake / flake (push) Successful in 1m16s
2024-09-28 15:01:30 +01:00
9c419376c5 chore(deps): lock file maintenance
All checks were successful
flake / flake (push) Successful in 1m19s
2024-09-28 12:31:15 +00:00
4332fee3ce chore(deps): update actions/checkout action to v4.2.0
All checks were successful
flake / flake (push) Successful in 1m15s
2024-09-26 23:00:18 +00:00
ceb8591705 step-ca: pin uid and gid
All checks were successful
flake / flake (push) Successful in 1m14s
2024-09-23 20:30:35 +01:00
415a061842 prometheus: move id pinning to correct module
All checks were successful
flake / flake (push) Successful in 1m15s
2024-09-23 20:26:34 +01:00
31a9828430 prometheus: add service and enable reporting globally (#330)
All checks were successful
flake / flake (push) Successful in 1m15s
## Test plan:

- https://prometheus.ts.hillion.co.uk/graph?g0.expr=1%20-%20(node_filesystem_avail_bytes%7Bmountpoint%20%3D%20%22%2F%22%2C%20device%3D%22tmpfs%22%7D%20%2F%20node_filesystem_size_bytes%7Bmountpoint%20%3D%20%22%2F%22%2C%20device%3D%22tmpfs%22%7D)&g0.tab=0&g0.display_mode=lines&g0.show_exemplars=0&g0.range_input=1h - reports percentage used on all tmpfs roots. This is exactly what I wanted, in the future I might add alerts for it as high tmpfs usage is a sign of something being wrong and is likely to lead to OOMing.

Aside: NixOS is awesome. I just deployed full monitoring to every host I have and all future hosts in minutes.
Reviewed-on: #330
Co-authored-by: Jake Hillion <jake@hillion.co.uk>
Co-committed-by: Jake Hillion <jake@hillion.co.uk>
2024-09-23 20:24:31 +01:00
7afa21e537 chia: update to 2.4.3
All checks were successful
flake / flake (push) Successful in 1m15s
2024-09-22 21:09:31 +01:00
739e1f6ab3 home: move tailscale exit node from microserver to router (#328)
All checks were successful
flake / flake (push) Successful in 1m15s
## Test plan:

- Connected MacBook to iPhone hotspot (off network).
- With Tailscale connected can ping/ssh to microserver.home on both LANs (main and IoT).
- With exit node enabled traceroute shows router's tailscale IP as a hop.
- With exit node enabled ipinfo.io shows my home IP.
- With exit node disabled ipinfo.io shows an EE IP.

iPhone exit node is still playing up, it shows no Internet connection. This behaviour was identical with the Pi setup that this replaces, maybe an iOS 18 bug for Tailscale? Treating this as not a regression.
Co-authored-by: Jake Hillion <jake@hillion.co.uk>
Co-committed-by: Jake Hillion <jake@hillion.co.uk>
2024-09-22 21:04:53 +01:00
8933d38d36 sched_ext: ship pre-release 6.12 kernel
All checks were successful
flake / flake (push) Successful in 1m14s
2024-09-22 16:18:04 +01:00
0ad31dddae gendry: decrypt encrypted disk with clevis/tang
All checks were successful
flake / flake (push) Successful in 1m15s
2024-09-22 11:06:03 +01:00
d5c2f8d543 router: setup cameras vlan
All checks were successful
flake / flake (push) Successful in 1m15s
2024-09-17 09:20:27 +01:00
1189a41df9 chore(deps): lock file maintenance
All checks were successful
flake / flake (push) Successful in 1m43s
2024-09-15 16:01:08 +00:00
39730d2ec3 macbook: add shell utilities
All checks were successful
flake / flake (push) Successful in 1m16s
2024-09-14 02:39:26 +01:00
ac6f285400 resilio: require mounts be available
All checks were successful
flake / flake (push) Successful in 1m15s
Without this resilio fails on boot on tywin.storage where the paths are
on a ZFS array which gets mounted reliably later than the resilio
service attempts to start.
2024-09-14 02:30:20 +01:00
e4b8fd7438 chore(deps): update determinatesystems/nix-installer-action action to v14
All checks were successful
flake / flake (push) Successful in 1m27s
2024-09-10 00:00:51 +00:00
24be3394bc chore(deps): update determinatesystems/magic-nix-cache-action action to v8
All checks were successful
flake / flake (push) Successful in 1m13s
2024-09-09 23:00:50 +00:00
ba053c539c boron: enable podman
All checks were successful
flake / flake (push) Successful in 1m13s
2024-09-06 19:04:25 +01:00
3aeeb69c2b nix-darwin: add macbook
All checks were successful
flake / flake (push) Successful in 1m13s
2024-09-05 00:50:02 +01:00
85246af424 caddy: update to unstable
All checks were successful
flake / flake (push) Successful in 1m13s
The default config for automatic ACME no longer works in Caddy <2.8.0.
This is due to changes with ZeroSSL's auth. Update to unstable Caddy
which is new enough to renew certs again.

Context: https://github.com/caddyserver/caddy/releases/tag/v2.8.0

Add `pkgs.unstable` as an overlay as recommended on the NixOS wiki. This
is needed here as Caddy must be runnable on all architectures.
2024-09-05 00:04:08 +01:00
ba7a39b66e chore(deps): pin dependencies
All checks were successful
flake / flake (push) Successful in 1m16s
2024-09-02 23:00:12 +00:00
df31ebebf8 boron: bump tmpfs to 100% of RAM
All checks were successful
flake / flake (push) Successful in 1m18s
2024-08-31 22:04:38 +01:00
2f3a33ad8e chore(deps): lock file maintenance
All checks were successful
flake / flake (push) Successful in 1m15s
2024-08-30 19:01:46 +00:00
126 changed files with 2771 additions and 941 deletions

View File

@ -11,9 +11,9 @@ jobs:
flake:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: DeterminateSystems/nix-installer-action@v13
- uses: DeterminateSystems/magic-nix-cache-action@v7
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: DeterminateSystems/nix-installer-action@b92f66560d6f97d6576405a7bae901ab57e72b6a # v15
- uses: DeterminateSystems/magic-nix-cache-action@87b14cf437d03d37989d87f0fa5ce4f5dc1a330b # v8
- name: lint
run: |
nix fmt

View File

@ -0,0 +1,27 @@
{ config, pkgs, ... }:
{
config = {
system.stateVersion = 4;
networking.hostName = "jakehillion-mba-m2-15";
nix = {
useDaemon = true;
};
programs.zsh.enable = true;
security.pam.enableSudoTouchIdAuth = true;
environment.systemPackages = with pkgs; [
fd
htop
mosh
neovim
nix
ripgrep
sapling
];
};
}

View File

@ -2,7 +2,9 @@
"nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"darwin": [
"darwin"
],
"home-manager": [
"home-manager"
],
@ -28,35 +30,53 @@
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1700795494,
"narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=",
"lastModified": 1731153869,
"narHash": "sha256-3Ftf9oqOypcEyyrWJ0baVkRpvQqroK/SVBFLvU3nPuc=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d",
"rev": "5c74ab862c8070cbf6400128a1b56abb213656da",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1731060864,
"narHash": "sha256-aYE7oAYZ+gPU1mPNhM0JwLAQNgjf0/JK1BF1ln2KBgk=",
"owner": "nix-community",
"repo": "disko",
"rev": "5e40e02978e3bd63c2a6a9fa6fa8ba0e310e747f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
@ -72,11 +92,11 @@
]
},
"locked": {
"lastModified": 1720042825,
"narHash": "sha256-A0vrUB6x82/jvf17qPCpxaM+ulJnD8YZwH9Ci0BsAzE=",
"lastModified": 1726989464,
"narHash": "sha256-Vl+WVTJwutXkimwGprnEtXc/s/s8sMuXzqXaspIGlwM=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "e1391fb22e18a36f57e6999c7a9f966dc80ac073",
"rev": "2f23fa308a7c067e52dfcc30a0758f47043ec176",
"type": "github"
},
"original": {
@ -93,11 +113,11 @@
]
},
"locked": {
"lastModified": 1723399884,
"narHash": "sha256-97wn0ihhGqfMb8WcUgzzkM/TuAxce2Gd20A8oiruju4=",
"lastModified": 1730837930,
"narHash": "sha256-0kZL4m+bKBJUBQse0HanewWO0g8hDdCvBhudzxgehqc=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "086f619dd991a4d355c07837448244029fc2d9ab",
"rev": "2f607e07f3ac7e53541120536708e824acccfaa8",
"type": "github"
},
"original": {
@ -108,11 +128,11 @@
},
"impermanence": {
"locked": {
"lastModified": 1719091691,
"narHash": "sha256-AxaLX5cBEcGtE02PeGsfscSb/fWMnyS7zMWBXQWDKbE=",
"lastModified": 1730403150,
"narHash": "sha256-W1FH5aJ/GpRCOA7DXT/sJHFpa5r8sq2qAUncWwRZ3Gg=",
"owner": "nix-community",
"repo": "impermanence",
"rev": "23c1f06316b67cb5dabdfe2973da3785cfe9c34a",
"rev": "0d09341beeaa2367bac5d718df1404bf2ce45e6f",
"type": "github"
},
"original": {
@ -124,11 +144,11 @@
},
"nixos-hardware": {
"locked": {
"lastModified": 1723310128,
"narHash": "sha256-IiH8jG6PpR4h9TxSGMYh+2/gQiJW9MwehFvheSb5rPc=",
"lastModified": 1730919458,
"narHash": "sha256-yMO0T0QJlmT/x4HEyvrCyigGrdYfIXX3e5gWqB64wLg=",
"owner": "nixos",
"repo": "nixos-hardware",
"rev": "c54cf53e022b0b3c1d3b8207aa0f9b194c24f0cf",
"rev": "e1cc1f6483393634aee94514186d21a4871e78d7",
"type": "github"
},
"original": {
@ -139,11 +159,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1723688146,
"narHash": "sha256-sqLwJcHYeWLOeP/XoLwAtYjr01TISlkOfz+NG82pbdg=",
"lastModified": 1730963269,
"narHash": "sha256-rz30HrFYCHiWEBCKHMffHbMdWJ35hEkcRVU0h7ms3x0=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c3d4ac725177c030b1e289015989da2ad9d56af0",
"rev": "83fb6c028368e465cd19bb127b86f971a5e41ebc",
"type": "github"
},
"original": {
@ -155,23 +175,22 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1723637854,
"narHash": "sha256-med8+5DSWa2UnOqtdICndjDAEjxr5D7zaIiK4pn0Q7c=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c3aa7b8938b17aebd2deecf7be0636000d62a2b9",
"type": "github"
"lastModified": 1730867498,
"narHash": "sha256-Ce3a1w7Qf+UEPjVJcXxeSiWyPMngqf1M2EIsmqiluQw=",
"rev": "9240e11a83307a6e8cf2254340782cba4aa782fd",
"type": "tarball",
"url": "https://gitea.hillion.co.uk/api/v1/repos/JakeHillion/nixpkgs/archive/9240e11a83307a6e8cf2254340782cba4aa782fd.tar.gz"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://gitea.hillion.co.uk/JakeHillion/nixpkgs/archive/nixos-unstable.tar.gz"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"darwin": "darwin",
"disko": "disko",
"flake-utils": "flake-utils",
"home-manager": "home-manager",
"home-manager-unstable": "home-manager-unstable",

View File

@ -1,14 +1,18 @@
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-unstable.url = "https://gitea.hillion.co.uk/JakeHillion/nixpkgs/archive/nixos-unstable.tar.gz";
nixos-hardware.url = "github:nixos/nixos-hardware";
flake-utils.url = "github:numtide/flake-utils";
darwin.url = "github:lnl7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixpkgs";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
agenix.inputs.darwin.follows = "darwin";
agenix.inputs.home-manager.follows = "home-manager";
home-manager.url = "github:nix-community/home-manager/release-24.05";
@ -17,19 +21,40 @@
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
impermanence.url = "github:nix-community/impermanence/master";
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
};
description = "Hillion Nix flake";
outputs = { self, nixpkgs, nixpkgs-unstable, nixos-hardware, flake-utils, agenix, home-manager, home-manager-unstable, impermanence, ... }@inputs: {
nixosConfigurations =
outputs =
{ self
, agenix
, darwin
, disko
, flake-utils
, home-manager
, home-manager-unstable
, impermanence
, nixos-hardware
, nixpkgs
, nixpkgs-unstable
, ...
}@inputs:
let
fqdns = builtins.attrNames (builtins.readDir ./hosts);
getSystemOverlays = system: nixpkgsConfig: [
(final: prev: {
unstable = nixpkgs-unstable.legacyPackages.${prev.system};
"storj" = final.callPackage ./pkgs/storj.nix { };
})
];
in
{
nixosConfigurations =
let
fqdns = builtins.attrNames (builtins.readDir ./hosts);
mkHost = fqdn:
let
system = builtins.readFile ./hosts/${fqdn}/system;
@ -45,6 +70,7 @@
agenix.nixosModules.default
impermanence.nixosModules.impermanence
disko.nixosModules.disko
home-manager-pick.nixosModules.default
{
@ -61,6 +87,22 @@
};
in
nixpkgs.lib.genAttrs fqdns mkHost;
darwinConfigurations = {
jakehillion-mba-m2-15 = darwin.lib.darwinSystem {
system = "aarch64-darwin";
specialArgs = inputs;
modules = [
./darwin/jakehillion-mba-m2-15/configuration.nix
({ config, ... }: {
nixpkgs.overlays = getSystemOverlays "aarch64-darwin" config.nixpkgs.config;
})
];
};
};
} // flake-utils.lib.eachDefaultSystem (system: {
formatter = nixpkgs.legacyPackages.${system}.nixpkgs-fmt;
});

View File

@ -34,26 +34,8 @@
### Explicitly use the latest kernel at time of writing because the LTS
### kernels available in NixOS do not seem to support this server's very
### modern hardware.
boot.kernelPackages = pkgs.linuxPackages_6_10;
### Apply patch to enable sched_ext which isn't yet available upstream.
boot.kernelPatches = [{
name = "sched_ext";
patch = pkgs.fetchpatch {
url = "https://github.com/sched-ext/scx-kernel-releases/releases/download/v6.10.3-scx1/linux-v6.10.3-scx1.patch.zst";
hash = "sha256-c4UlXsVOHGe0gvL69K9qTMWqCR8as25qwhfNVxCXUTs=";
decode = "${pkgs.zstd}/bin/unzstd";
excludes = [ "Makefile" ];
};
extraConfig = ''
BPF y
BPF_EVENTS y
BPF_JIT y
BPF_SYSCALL y
DEBUG_INFO_BTF y
FTRACE y
SCHED_CLASS_EXT y
'';
}];
### custom.sched_ext.enable implies >=6.12, if this is removed the kernel may need to be pinned again. >=6.10 seems good.
custom.sched_ext.enable = true;
## Enable btrfs compression
fileSystems."/data".options = [ "compress=zstd" ];
@ -63,6 +45,11 @@
custom.impermanence = {
enable = true;
cache.enable = true;
userExtraFiles.jake = [
".ssh/id_ecdsa"
".ssh/id_rsa"
];
};
boot.initrd.postDeviceCommands = lib.mkAfter ''
btrfs subvolume delete /cache/system
@ -101,6 +88,42 @@
fileSystems = [ "/data" ];
};
## Resilio
custom.resilio = {
enable = true;
folders =
let
folderNames = [
"dad"
"joseph"
"projects"
"resources"
"sync"
];
mkFolder = name: {
name = name;
secret = {
name = "resilio/plain/${name}";
file = ../../secrets/resilio/plain/${name}.age;
};
};
in
builtins.map (mkFolder) folderNames;
};
services.resilio.directoryRoot = "/data/sync";
## General usability
### Make podman available for dev tools such as act
virtualisation = {
containers.enable = true;
podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
};
};
users.users.jake.extraGroups = [ "podman" ];
## Networking
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = true;

View File

@ -18,7 +18,7 @@
{
device = "tmpfs";
fsType = "tmpfs";
options = [ "mode=0755" ];
options = [ "mode=0755" "size=100%" ];
};
fileSystems."/boot" =

View File

@ -0,0 +1,7 @@
# gendry.jakehillion-terminals.ts.hillion.co.uk
Additional installation step for Clevis/Tang:
$ echo -n $DISK_ENCRYPTION_PASSWORD | clevis encrypt sss "$(cat /etc/nixos/hosts/gendry.jakehillion-terminals.ts.hillion.co.uk/clevis_config.json)" >/mnt/data/disk_encryption.jwe
$ sudo chown root:root /mnt/data/disk_encryption.jwe
$ sudo chmod 0400 /mnt/data/disk_encryption.jwe

View File

@ -15,8 +15,24 @@
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelParams = [
"ip=dhcp"
];
boot.initrd = {
availableKernelModules = [ "r8169" ];
network.enable = true;
clevis = {
enable = true;
useTang = true;
devices."root".secretFile = "/data/disk_encryption.jwe";
};
};
custom.defaults = true;
## Custom scheduler
custom.sched_ext.enable = true;
## Impermanence
custom.impermanence = {
enable = true;
@ -43,9 +59,7 @@
## Resilio
custom.resilio.enable = true;
services.resilio.deviceName = "gendry.jakehillion-terminals";
services.resilio.directoryRoot = "/data/sync";
services.resilio.storagePath = "/data/sync/.sync";
custom.resilio.folders =
let

View File

@ -0,0 +1,75 @@
{ config, pkgs, lib, ... }:
{
imports = [
./disko.nix
./hardware-configuration.nix
];
config = {
system.stateVersion = "24.05";
networking.hostName = "merlin";
networking.domain = "rig.ts.hillion.co.uk";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelParams = [
"ip=dhcp"
# zswap
"zswap.enabled=1"
"zswap.compressor=zstd"
"zswap.max_pool_percent=20"
];
boot.initrd = {
availableKernelModules = [ "igc" ];
network.enable = true;
clevis = {
enable = true;
useTang = true;
devices = {
"disk0-crypt".secretFile = "/data/disk_encryption.jwe";
};
};
};
boot.kernelPackages = pkgs.linuxPackages_latest;
custom.defaults = true;
custom.locations.autoServe = true;
custom.impermanence.enable = true;
custom.users.jake.password = true;
security.sudo.wheelNeedsPassword = lib.mkForce true;
# Networking
networking = {
interfaces.enp171s0.name = "eth0";
interfaces.enp172s0.name = "eth1";
};
networking.nameservers = lib.mkForce [ ]; # Trust the DHCP nameservers
networking.firewall = {
trustedInterfaces = [ "tailscale0" ];
allowedTCPPorts = lib.mkForce [
22 # SSH
];
allowedUDPPorts = lib.mkForce [ ];
interfaces = {
eth0 = {
allowedTCPPorts = lib.mkForce [ ];
allowedUDPPorts = lib.mkForce [ ];
};
};
};
## Tailscale
age.secrets."tailscale/merlin.rig.ts.hillion.co.uk".file = ../../secrets/tailscale/merlin.rig.ts.hillion.co.uk.age;
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale/merlin.rig.ts.hillion.co.uk".path;
};
};
}

View File

@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
disk0 = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
disk0-crypt = {
size = "100%";
content = {
type = "luks";
name = "disk0-crypt";
settings = {
allowDiscards = true;
};
content = {
type = "btrfs";
subvolumes = {
"/data" = {
mountpoint = "/data";
mountOptions = [ "compress=zstd" "ssd" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "ssd" ];
};
};
};
};
};
swap = {
size = "64G";
content = {
type = "swap";
randomEncryption = true;
discardPolicy = "both";
};
};
};
};
};
};
nodev = {
"/" = {
fsType = "tmpfs";
mountOptions = [
"mode=755"
"size=100%"
];
};
};
};
}

View File

@ -0,0 +1,28 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usbhid" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp171s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp172s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlp173s0f0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -23,12 +23,6 @@
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale/microserver.home.ts.hillion.co.uk".path;
useRoutingFeatures = "server";
extraUpFlags = [
"--advertise-routes"
"10.64.50.0/24,10.239.19.0/24"
"--advertise-exit-node"
];
};
## Enable IoT VLAN
@ -43,11 +37,6 @@
bluetooth.enable = true;
};
## Enable IP forwarding for Tailscale
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = true;
};
## Run a persistent iperf3 server
services.iperf3.enable = true;
services.iperf3.openFirewall = true;
@ -56,12 +45,9 @@
networking.firewall.interfaces = {
"eth0" = {
allowedUDPPorts = [
5353 # HomeKit
];
allowedTCPPorts = [
1400 # HA Sonos
7654 # Tang
21063 # HomeKit
];
};
};

View File

@ -0,0 +1,7 @@
# phoenix.st.ts.hillion.co.uk
Additional installation step for Clevis/Tang:
$ echo -n $DISK_ENCRYPTION_PASSWORD | clevis encrypt sss "$(cat /etc/nixos/hosts/phoenix.st.ts.hillion.co.uk/clevis_config.json)" >/mnt/data/disk_encryption.jwe
$ sudo chown root:root /mnt/data/disk_encryption.jwe
$ sudo chmod 0400 /mnt/data/disk_encryption.jwe

View File

@ -0,0 +1,14 @@
{
"t": 1,
"pins": {
"tang": [
{
"url": "http://10.64.50.21:7654"
},
{
"url": "http://10.64.50.25:7654"
}
]
}
}

View File

@ -0,0 +1,161 @@
{ config, pkgs, lib, ... }:
let
zpool_name = "practical-defiant-coffee";
in
{
imports = [
./disko.nix
./hardware-configuration.nix
];
config = {
system.stateVersion = "24.05";
networking.hostName = "phoenix";
networking.domain = "st.ts.hillion.co.uk";
networking.hostId = "4d7241e9";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelParams = [
"ip=dhcp"
"zfs.zfs_arc_max=34359738368"
# zswap
"zswap.enabled=1"
"zswap.compressor=zstd"
"zswap.max_pool_percent=20"
];
boot.initrd = {
availableKernelModules = [ "igc" ];
network.enable = true;
clevis = {
enable = true;
useTang = true;
devices = {
"disk0-crypt".secretFile = "/data/disk_encryption.jwe";
"disk1-crypt".secretFile = "/data/disk_encryption.jwe";
};
};
};
custom.defaults = true;
custom.locations.autoServe = true;
custom.impermanence.enable = true;
custom.users.jake.password = true; # TODO: remove me once booting has stabilised
## Filesystems
boot.supportedFilesystems = [ "zfs" ];
boot.zfs = {
forceImportRoot = false;
extraPools = [ zpool_name ];
};
services.btrfs.autoScrub = {
enable = true;
interval = "Tue, 02:00";
# All filesystems includes the BTRFS parts of all the hard drives. This
# would take forever and is redundant as they get fully read regularly.
fileSystems = [ "/data" ];
};
services.zfs.autoScrub = {
enable = true;
interval = "Wed, 02:00";
};
## Resilio
custom.resilio = {
enable = true;
backups.enable = true;
folders =
let
folderNames = [
"dad"
"joseph"
"projects"
"resources"
"sync"
];
mkFolder = name: {
name = name;
secret = {
name = "resilio/plain/${name}";
file = ../../secrets/resilio/plain/${name}.age;
};
};
in
builtins.map (mkFolder) folderNames;
};
services.resilio.directoryRoot = "/${zpool_name}/sync";
## Chia
age.secrets."chia/farmer.key" = {
file = ../../secrets/chia/farmer.key.age;
owner = "chia";
group = "chia";
};
custom.chia = {
enable = true;
keyFile = config.age.secrets."chia/farmer.key".path;
plotDirectories = builtins.genList (i: "/mnt/d${toString i}/plots/contract-k32") 8;
};
## Restic
custom.services.restic.path = "/${zpool_name}/backups/restic";
## Backups
### Git
custom.backups.git = {
enable = true;
extraRepos = [ "https://gitea.hillion.co.uk/JakeHillion/nixos.git" ];
};
## Downloads
custom.services.downloads = {
metadataPath = "/${zpool_name}/downloads/metadata";
downloadCachePath = "/${zpool_name}/downloads/torrents";
filmsPath = "/${zpool_name}/media/films";
tvPath = "/${zpool_name}/media/tv";
};
## Plex
users.users.plex.extraGroups = [ "mediaaccess" ];
services.plex.enable = true;
## Networking
networking = {
interfaces.enp4s0.name = "eth0";
interfaces.enp5s0.name = "eth1";
interfaces.enp6s0.name = "eth2";
interfaces.enp8s0.name = "eth3";
};
networking.nameservers = lib.mkForce [ ]; # Trust the DHCP nameservers
networking.firewall = {
trustedInterfaces = [ "tailscale0" ];
allowedTCPPorts = lib.mkForce [
22 # SSH
];
allowedUDPPorts = lib.mkForce [ ];
interfaces = {
eth0 = {
allowedTCPPorts = lib.mkForce [
32400 # Plex
];
allowedUDPPorts = lib.mkForce [ ];
};
};
};
## Tailscale
age.secrets."tailscale/phoenix.st.ts.hillion.co.uk".file = ../../secrets/tailscale/phoenix.st.ts.hillion.co.uk.age;
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale/phoenix.st.ts.hillion.co.uk".path;
};
};
}

View File

@ -0,0 +1,103 @@
{
disko.devices = {
disk = {
disk0 = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
disk0-crypt = {
size = "100%";
content = {
type = "luks";
name = "disk0-crypt";
settings = {
allowDiscards = true;
};
};
};
swap = {
size = "64G";
content = {
type = "swap";
randomEncryption = true;
discardPolicy = "both";
};
};
};
};
};
disk1 = {
type = "disk";
device = "/dev/nvme1n1";
content = {
type = "gpt";
partitions = {
disk1-crypt = {
size = "100%";
content = {
type = "luks";
name = "disk1-crypt";
settings = {
allowDiscards = true;
};
content = {
type = "btrfs";
extraArgs = [
"-d raid1"
"/dev/mapper/disk0-crypt"
];
subvolumes = {
"/data" = {
mountpoint = "/data";
mountOptions = [ "compress=zstd" "ssd" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "ssd" ];
};
};
};
};
};
swap = {
size = "64G";
content = {
type = "swap";
randomEncryption = true;
discardPolicy = "both";
};
};
};
};
};
};
nodev = {
"/" = {
fsType = "tmpfs";
mountOptions = [
"mode=755"
"size=100%"
];
};
};
};
}

View File

@ -9,28 +9,11 @@
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.availableKernelModules = [ "nvme" "ahci" "xhci_pci" "thunderbolt" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{
device = "/dev/disk/by-uuid/cb48d4ed-d268-490c-9977-2b5d31ce2c1b";
fsType = "btrfs";
};
boot.initrd.luks.devices."root" = {
device = "/dev/disk/by-uuid/32837730-5e15-4917-9939-cbb58bb0aabf";
allowDiscards = true;
};
fileSystems."/boot" =
{
device = "/dev/disk/by-uuid/BC57-0AF6";
fsType = "vfat";
};
fileSystems."/mnt/d0" =
{
device = "/dev/disk/by-uuid/9136434d-d883-4118-bd01-903f720e5ce1";
@ -79,14 +62,16 @@
fsType = "btrfs";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp7s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp5s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp6s0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp8s0.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1 @@
x86_64-linux

View File

@ -32,6 +32,14 @@
nat.enable = lib.mkForce false;
useDHCP = false;
vlans = {
cameras = {
id = 3;
interface = "eth2";
};
};
interfaces = {
enp1s0 = {
name = "eth0";
@ -56,6 +64,14 @@
}
];
};
cameras /* cameras@eth2 */ = {
ipv4.addresses = [
{
address = "10.133.145.1";
prefixLength = 24;
}
];
};
enp4s0 = { name = "eth3"; };
enp5s0 = { name = "eth4"; };
enp6s0 = { name = "eth5"; };
@ -82,8 +98,10 @@
ip protocol icmp counter accept comment "accept all ICMP types"
iifname "eth0" ct state { established, related } counter accept
iifname "eth0" drop
iifname "eth0" tcp dport 22 counter accept comment "SSH"
iifname { "eth0", "cameras" } ct state { established, related } counter accept
iifname { "eth0", "cameras" } drop
}
chain forward {
@ -92,6 +110,7 @@
iifname {
"eth1",
"eth2",
"tailscale0",
} oifname {
"eth0",
} counter accept comment "Allow trusted LAN to WAN"
@ -101,12 +120,13 @@
} oifname {
"eth1",
"eth2",
} ct state established,related counter accept comment "Allow established back to LANs"
"tailscale0",
} ct state { established,related } counter accept comment "Allow established back to LANs"
ip daddr 10.64.50.20 tcp dport 32400 counter accept comment "Plex"
ip daddr 10.64.50.20 tcp dport 8444 counter accept comment "Chia"
iifname "tailscale0" oifname { "eth1", "eth2" } counter accept comment "Allow LAN access from Tailscale"
iifname { "eth1", "eth2" } oifname "tailscale0" ct state { established,related } counter accept comment "Allow established back to Tailscale"
ip daddr 10.64.50.27 tcp dport 32400 counter accept comment "Plex"
ip daddr 10.64.50.21 tcp dport 7654 counter accept comment "Tang"
}
}
@ -115,16 +135,17 @@
chain prerouting {
type nat hook prerouting priority filter; policy accept;
iifname eth0 tcp dport 32400 counter dnat to 10.64.50.20
iifname eth0 tcp dport 8444 counter dnat to 10.64.50.20
iifname eth0 tcp dport 32400 counter dnat to 10.64.50.27
iifname eth0 tcp dport 7654 counter dnat to 10.64.50.21
}
chain postrouting {
type nat hook postrouting priority filter; policy accept;
oifname "eth0" masquerade
iifname tailscale0 oifname eth1 snat to 10.64.50.1
iifname tailscale0 oifname eth2 snat to 10.239.19.1
}
}
'';
@ -138,7 +159,7 @@
settings = {
interfaces-config = {
interfaces = [ "eth1" "eth2" ];
interfaces = [ "eth1" "eth2" "cameras" ];
};
lease-database = {
type = "memfile";
@ -195,18 +216,22 @@
data = "10.64.50.1, 1.1.1.1, 8.8.8.8";
}
];
reservations = lib.lists.imap0
(i: el: {
reservations = lib.lists.remove null (lib.lists.imap0
(i: el: if el == null then null else {
ip-address = "10.64.50.${toString (20 + i)}";
inherit (el) hw-address hostname;
}) [
{ hostname = "tywin"; hw-address = "c8:7f:54:6d:e1:03"; }
null
{ hostname = "microserver"; hw-address = "e4:5f:01:b4:58:95"; }
{ hostname = "theon"; hw-address = "00:1e:06:49:06:1e"; }
{ hostname = "server-switch"; hw-address = "84:d8:1b:9d:0d:85"; }
{ hostname = "apc-ap7921"; hw-address = "00:c0:b7:6b:f4:34"; }
{ hostname = "sodium"; hw-address = "d8:3a:dd:c3:d6:2b"; }
];
{ hostname = "gendry"; hw-address = "18:c0:4d:35:60:1e"; }
{ hostname = "phoenix"; hw-address = "a8:b8:e0:04:17:a5"; }
{ hostname = "merlin"; hw-address = "b0:41:6f:13:20:14"; }
{ hostname = "stinger"; hw-address = "7c:83:34:be:30:dd"; }
]);
}
{
subnet = "10.239.19.0/24";
@ -230,17 +255,58 @@
];
reservations = [
{
# bedroom-everything-presence-one
hw-address = "40:22:d8:e0:1d:50";
ip-address = "10.239.19.2";
hostname = "bedroom-everything-presence-one";
}
{
# living-room-everything-presence-one
hw-address = "40:22:d8:e0:0f:78";
ip-address = "10.239.19.3";
hostname = "living-room-everything-presence-one";
}
{
hw-address = "a0:7d:9c:b0:f0:14";
ip-address = "10.239.19.4";
hostname = "hallway-wall-tablet";
}
{
hw-address = "d8:3a:dd:c3:d6:2b";
ip-address = "10.239.19.5";
hostname = "sodium";
}
{
hw-address = "48:da:35:6f:f2:4b";
ip-address = "10.239.19.6";
hostname = "hammer";
}
{
hw-address = "48:da:35:6f:83:b8";
ip-address = "10.239.19.7";
hostname = "charlie";
}
];
}
{
subnet = "10.133.145.0/24";
interface = "cameras";
pools = [{
pool = "10.133.145.64 - 10.133.145.254";
}];
option-data = [
{
name = "routers";
data = "10.133.145.1";
}
{
name = "broadcast-address";
data = "10.133.145.255";
}
{
name = "domain-name-servers";
data = "1.1.1.1, 8.8.8.8";
}
];
reservations = [
];
}
];
@ -284,6 +350,13 @@
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale/router.home.ts.hillion.co.uk".path;
useRoutingFeatures = "server";
extraSetFlags = [
"--advertise-routes"
"10.64.50.0/24,10.239.19.0/24,10.133.145.0/24"
"--advertise-exit-node"
"--netfilter-mode=off"
];
};
## Enable btrfs compression
@ -307,9 +380,34 @@
};
services.caddy = {
enable = true;
virtualHosts."http://graphs.router.home.ts.hillion.co.uk" = {
virtualHosts = {
"graphs.router.home.ts.hillion.co.uk" = {
listenAddresses = [ config.custom.dns.tailscale.ipv4 config.custom.dns.tailscale.ipv6 ];
extraConfig = "reverse_proxy unix///run/netdata/netdata.sock";
extraConfig = ''
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
reverse_proxy unix///run/netdata/netdata.sock
'';
};
"hammer.kvm.ts.hillion.co.uk" = {
listenAddresses = [ config.custom.dns.tailscale.ipv4 config.custom.dns.tailscale.ipv6 ];
extraConfig = ''
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
reverse_proxy http://10.239.19.6
'';
};
"charlie.kvm.ts.hillion.co.uk" = {
listenAddresses = [ config.custom.dns.tailscale.ipv4 config.custom.dns.tailscale.ipv6 ];
extraConfig = ''
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
reverse_proxy http://10.239.19.7
'';
};
};
};
users.users.caddy.extraGroups = [ "netdata" ];

View File

@ -1,4 +1,4 @@
{ config, pkgs, nixpkgs-unstable, lib, nixos-hardware, ... }:
{ config, pkgs, lib, nixos-hardware, ... }:
{
imports = [
@ -48,14 +48,17 @@
## Custom Services
custom.locations.autoServe = true;
custom.www.home.enable = true;
custom.www.iot.enable = true;
custom.services.isponsorblocktv.enable = true;
# Networking
networking = {
useDHCP = false;
interfaces = {
end0 = {
name = "eth0";
useDHCP = true;
interfaces.end0.name = "eth0";
vlans = {
iot = {
id = 2;
interface = "eth0";
};
};
};
@ -64,14 +67,27 @@
networking.firewall = {
trustedInterfaces = [ "tailscale0" ];
allowedTCPPorts = lib.mkForce [
22 # SSH
];
allowedUDPPorts = lib.mkForce [ ];
interfaces = {
eth0 = {
allowedTCPPorts = lib.mkForce [
80 # HTTP 1-2
443 # HTTPS 1-2
7654 # Tang
];
allowedUDPPorts = lib.mkForce [
443 # HTTP 3
];
};
iot = {
allowedTCPPorts = lib.mkForce [
80 # HTTP 1-2
443 # HTTPS 1-2
];
allowedUDPPorts = lib.mkForce [
443 # HTTP 3
];
};
};

View File

@ -0,0 +1,84 @@
{ config, pkgs, lib, ... }:
{
imports = [
./disko.nix
./hardware-configuration.nix
];
config = {
system.stateVersion = "24.05";
networking.hostName = "stinger";
networking.domain = "pop.ts.hillion.co.uk";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelParams = [
"ip=dhcp"
# zswap
"zswap.enabled=1"
"zswap.compressor=zstd"
"zswap.max_pool_percent=20"
];
boot.initrd = {
availableKernelModules = [ "r8169" ];
network.enable = true;
clevis = {
enable = true;
useTang = true;
devices = {
"disk0-crypt".secretFile = "/data/disk_encryption.jwe";
};
};
};
custom.defaults = true;
custom.locations.autoServe = true;
custom.impermanence.enable = true;
hardware = {
bluetooth.enable = true;
};
# Networking
networking = {
interfaces.enp1s0.name = "eth0";
vlans = {
iot = {
id = 2;
interface = "eth0";
};
};
};
networking.nameservers = lib.mkForce [ ]; # Trust the DHCP nameservers
networking.firewall = {
trustedInterfaces = [ "tailscale0" ];
allowedTCPPorts = lib.mkForce [
22 # SSH
];
allowedUDPPorts = lib.mkForce [ ];
interfaces = {
eth0 = {
allowedTCPPorts = lib.mkForce [
1400 # HA Sonos
21063 # HomeKit
];
allowedUDPPorts = lib.mkForce [
5353 # HomeKit
];
};
};
};
## Tailscale
age.secrets."tailscale/stinger.pop.ts.hillion.co.uk".file = ../../secrets/tailscale/stinger.pop.ts.hillion.co.uk.age;
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale/stinger.pop.ts.hillion.co.uk".path;
};
};
}

View File

@ -0,0 +1,70 @@
{
disko.devices = {
disk = {
disk0 = {
type = "disk";
device = "/dev/nvme0n1";
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
disk0-crypt = {
size = "100%";
content = {
type = "luks";
name = "disk0-crypt";
settings = {
allowDiscards = true;
};
content = {
type = "btrfs";
subvolumes = {
"/data" = {
mountpoint = "/data";
mountOptions = [ "compress=zstd" "ssd" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [ "compress=zstd" "ssd" ];
};
};
};
};
};
swap = {
size = "64G";
content = {
type = "swap";
randomEncryption = true;
discardPolicy = "both";
};
};
};
};
};
};
nodev = {
"/" = {
fsType = "tmpfs";
mountOptions = [
"mode=755"
"size=100%"
];
};
};
};
}

View File

@ -0,0 +1,28 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp0s20f0u2.useDHCP = lib.mkDefault true;
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -0,0 +1 @@
x86_64-linux

View File

@ -1,7 +0,0 @@
# tywin.storage.ts.hillion.co.uk
Additional installation step for Clevis/Tang:
$ echo -n $DISK_ENCRYPTION_PASSWORD | clevis encrypt sss "$(cat /etc/nixos/hosts/tywin.storage.ts.hillion.co.uk/clevis_config.json)" >/mnt/disk_encryption.jwe
$ sudo chown root:root /mnt/disk_encryption.jwe
$ sudo chmod 0400 /mnt/disk_encryption.jwe

View File

@ -1,245 +0,0 @@
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
];
config = {
system.stateVersion = "22.11";
networking.hostName = "tywin";
networking.domain = "storage.ts.hillion.co.uk";
networking.hostId = "2a9b6df5";
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.kernelParams = [
"ip=dhcp"
"zfs.zfs_arc_max=25769803776"
];
boot.initrd = {
availableKernelModules = [ "r8169" ];
network.enable = true;
clevis = {
enable = true;
useTang = true;
devices."root".secretFile = "/disk_encryption.jwe";
};
};
custom.locations.autoServe = true;
custom.defaults = true;
# zram swap: used in the hope it will give the ZFS ARC more room to back off
zramSwap = {
enable = true;
memoryPercent = 200;
algorithm = "zstd";
};
## Tailscale
age.secrets."tailscale/tywin.storage.ts.hillion.co.uk".file = ../../secrets/tailscale/tywin.storage.ts.hillion.co.uk.age;
services.tailscale = {
enable = true;
authKeyFile = config.age.secrets."tailscale/tywin.storage.ts.hillion.co.uk".path;
};
## Filesystems
fileSystems."/".options = [ "compress=zstd" ];
boot.supportedFilesystems = [ "zfs" ];
boot.zfs = {
forceImportRoot = false;
extraPools = [ "data" ];
};
services.btrfs.autoScrub = {
enable = true;
interval = "Tue, 02:00";
# All filesystems includes the BTRFS parts of all the hard drives. This
# would take forever and is redundant as they get fully read regularly.
fileSystems = [ "/" ];
};
services.zfs.autoScrub = {
enable = true;
interval = "Wed, 02:00";
};
## Backups
### Git
age.secrets."git/git_backups_ecdsa".file = ../../secrets/git/git_backups_ecdsa.age;
age.secrets."git/git_backups_remotes".file = ../../secrets/git/git_backups_remotes.age;
custom.backups.git = {
enable = true;
sshKey = config.age.secrets."git/git_backups_ecdsa".path;
reposFile = config.age.secrets."git/git_backups_remotes".path;
repos = [ "https://gitea.hillion.co.uk/JakeHillion/nixos.git" ];
};
## Resilio
custom.resilio.enable = true;
services.resilio.deviceName = "tywin.storage";
services.resilio.directoryRoot = "/data/users/jake/sync";
services.resilio.storagePath = "/data/users/jake/sync/.sync";
custom.resilio.folders =
let
folderNames = [
"dad"
"joseph"
"projects"
"resources"
"sync"
];
mkFolder = name: {
name = name;
secret = {
name = "resilio/plain/${name}";
file = ../../secrets/resilio/plain/${name}.age;
};
};
in
builtins.map (mkFolder) folderNames;
age.secrets."resilio/restic/128G.key" = {
file = ../../secrets/restic/128G.age;
owner = "rslsync";
group = "rslsync";
};
services.restic.backups."sync" = {
repository = "rest:http://restic.tywin.storage.ts.hillion.co.uk/128G";
user = "rslsync";
passwordFile = config.age.secrets."resilio/restic/128G.key".path;
timerConfig = {
Persistent = true;
OnUnitInactiveSec = "15m";
RandomizedDelaySec = "5m";
};
paths = [ "/data/users/jake/sync" ];
exclude = [
"/data/users/jake/sync/.sync"
"/data/users/jake/sync/*/.sync"
"/data/users/jake/sync/resources/media/films"
"/data/users/jake/sync/resources/media/iso"
"/data/users/jake/sync/resources/media/tv"
"/data/users/jake/sync/dad/media"
];
};
## Restic
age.secrets."restic/128G.key" = {
file = ../../secrets/restic/128G.age;
owner = "restic";
group = "restic";
};
age.secrets."restic/1.6T.key" = {
file = ../../secrets/restic/1.6T.age;
owner = "restic";
group = "restic";
};
services.restic.server = {
enable = true;
appendOnly = true;
extraFlags = [ "--no-auth" ];
dataDir = "/data/backups/restic";
listenAddress = "127.0.0.1:8000"; # TODO: can this be a Unix socket?
};
services.caddy = {
enable = true;
virtualHosts."http://restic.tywin.storage.ts.hillion.co.uk".extraConfig = ''
bind ${config.custom.dns.tailscale.ipv4} ${config.custom.dns.tailscale.ipv6}
reverse_proxy http://localhost:8000
'';
};
### HACK: Allow Caddy to restart if it fails. This happens because Tailscale
### is too late at starting. Upstream nixos caddy does restart on failure
### but it's prevented on exit code 1. Set the exit code to 0 (non-failure)
### to override this.
systemd.services.caddy = {
requires = [ "tailscaled.service" ];
after = [ "tailscaled.service" ];
serviceConfig = {
RestartPreventExitStatus = lib.mkForce 0;
};
};
services.restic.backups."prune-128G" = {
repository = "/data/backups/restic/128G";
user = "restic";
passwordFile = config.age.secrets."restic/128G.key".path;
timerConfig = {
Persistent = true;
OnCalendar = "02:30";
RandomizedDelaySec = "1h";
};
pruneOpts = [
"--keep-last 48"
"--keep-within-hourly 7d"
"--keep-within-daily 1m"
"--keep-within-weekly 6m"
"--keep-within-monthly 24m"
];
};
services.restic.backups."prune-1.6T" = {
repository = "/data/backups/restic/1.6T";
user = "restic";
passwordFile = config.age.secrets."restic/1.6T.key".path;
timerConfig = {
Persistent = true;
OnCalendar = "Wed, 02:30";
RandomizedDelaySec = "4h";
};
pruneOpts = [
"--keep-within-daily 14d"
"--keep-within-weekly 2m"
"--keep-within-monthly 18m"
];
};
## Chia
age.secrets."chia/farmer.key" = {
file = ../../secrets/chia/farmer.key.age;
owner = "chia";
group = "chia";
};
custom.chia = {
enable = true;
openFirewall = true;
keyFile = config.age.secrets."chia/farmer.key".path;
plotDirectories = builtins.genList (i: "/mnt/d${toString i}/plots/contract-k32") 8;
};
## Downloads
custom.services.downloads = {
metadataPath = "/data/downloads/metadata";
downloadCachePath = "/data/downloads/torrents";
filmsPath = "/data/media/films";
tvPath = "/data/media/tv";
};
## Plex
users.users.plex.extraGroups = [ "mediaaccess" ];
services.plex = {
enable = true;
openFirewall = true;
};
## Networking
networking.nameservers = lib.mkForce [ ]; # Trust the DHCP nameservers
networking.firewall.interfaces."tailscale0".allowedTCPPorts = [
80 # Caddy (restic.tywin.storage.ts.)
];
};
}

View File

@ -2,7 +2,7 @@
{
imports = [
./git.nix
./git/default.nix
./homeassistant.nix
./matrix.nix
];

View File

@ -7,25 +7,17 @@ in
options.custom.backups.git = {
enable = lib.mkEnableOption "git";
repos = lib.mkOption {
extraRepos = lib.mkOption {
description = "A list of remotes to clone.";
type = with lib.types; listOf str;
default = [ ];
};
reposFile = lib.mkOption {
description = "A file containing the remotes to clone, one per line.";
type = with lib.types; nullOr str;
default = null;
};
sshKey = lib.mkOption {
description = "SSH private key to use when cloning repositories over SSH.";
type = with lib.types; nullOr str;
default = null;
};
};
config = lib.mkIf cfg.enable {
age.secrets."git-backups/restic/128G".file = ../../secrets/restic/128G.age;
age.secrets."git/git_backups_ecdsa".file = ../../../secrets/git/git_backups_ecdsa.age;
age.secrets."git/git_backups_remotes".file = ../../../secrets/git/git_backups_remotes.age;
age.secrets."git-backups/restic/128G".file = ../../../secrets/restic/128G.age;
systemd.services.backup-git = {
description = "Git repo backup service.";
@ -37,9 +29,10 @@ in
WorkingDirectory = "%C/backup-git";
LoadCredential = [
"id_ecdsa:${config.age.secrets."git/git_backups_ecdsa".path}"
"repos_file:${config.age.secrets."git/git_backups_remotes".path}"
"restic_password:${config.age.secrets."git-backups/restic/128G".path}"
] ++ (if cfg.sshKey == null then [ ] else [ "id_ecdsa:${cfg.sshKey}" ])
++ (if cfg.reposFile == null then [ ] else [ "repos_file:${cfg.reposFile}" ]);
];
};
environment = {
@ -48,11 +41,12 @@ in
};
script = ''
set -x
shopt -s nullglob
# Read and deduplicate repos
${if cfg.reposFile == null then "" else "readarray -t raw_repos < $CREDENTIALS_DIRECTORY/repos_file"}
declare -A repos=(${builtins.concatStringsSep " " (builtins.map (x : "[${x}]=1") cfg.repos)})
readarray -t raw_repos < $CREDENTIALS_DIRECTORY/repos_file
declare -A repos=(${builtins.concatStringsSep " " (builtins.map (x : "[${x}]=1") cfg.extraRepos)})
for repo in ''${raw_repos[@]}; do repos[$repo]=1; done
# Clean up existing repos
@ -79,7 +73,7 @@ in
# Backup to Restic
${pkgs.restic}/bin/restic \
-r rest:http://restic.tywin.storage.ts.hillion.co.uk/128G \
-r rest:https://restic.ts.hillion.co.uk/128G \
--cache-dir .restic --exclude .restic \
backup .
@ -93,9 +87,9 @@ in
wantedBy = [ "timers.target" ];
timerConfig = {
Persistent = true;
OnBootSec = "10m";
OnUnitInactiveSec = "15m";
RandomizedDelaySec = "5m";
Unit = "backup-git.service";
};
};
};

View File

@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIc3WVROMCifYtqHRWf5gZAOQFdpbcSYOC0JckKzUVM5sGdXtw3VXNiVqY3npdMizS4e1V8Hh77UecD3q9CLkMA= backups-git@nixos

View File

@ -14,20 +14,45 @@ in
owner = "hass";
group = "hass";
};
age.secrets."backups/homeassistant/restic/1.6T" = {
file = ../../secrets/restic/1.6T.age;
owner = "postgres";
group = "postgres";
};
services = {
restic.backups."homeassistant" = {
postgresqlBackup = {
enable = true;
compression = "none"; # for better diffing
databases = [ "homeassistant" ];
};
restic.backups = {
"homeassistant-config" = {
user = "hass";
timerConfig = {
OnCalendar = "03:00";
RandomizedDelaySec = "60m";
};
repository = "rest:http://restic.tywin.storage.ts.hillion.co.uk/128G";
repository = "rest:https://restic.ts.hillion.co.uk/128G";
passwordFile = config.age.secrets."backups/homeassistant/restic/128G".path;
paths = [
config.services.home-assistant.configDir
];
};
"homeassistant-database" = {
user = "postgres";
timerConfig = {
OnCalendar = "03:00";
RandomizedDelaySec = "60m";
};
repository = "rest:https://restic.ts.hillion.co.uk/1.6T";
passwordFile = config.age.secrets."backups/homeassistant/restic/1.6T".path;
paths = [
"${config.services.postgresqlBackup.location}/homeassistant.sql"
];
};
};
};
};
}

View File

@ -24,7 +24,7 @@ in
OnCalendar = "03:00";
RandomizedDelaySec = "60m";
};
repository = "rest:http://restic.tywin.storage.ts.hillion.co.uk/128G";
repository = "rest:https://restic.ts.hillion.co.uk/128G";
passwordFile = config.age.secrets."backups/matrix/restic/128G".path;
paths = [
"${config.services.postgresqlBackup.location}/matrix-synapse.sql"

View File

@ -9,6 +9,9 @@ in
};
config = lib.mkIf cfg.enable {
users.users.step-ca.uid = config.ids.uids.step-ca;
users.groups.step-ca.gid = config.ids.gids.step-ca;
services.step-ca = {
enable = true;

View File

@ -22,8 +22,8 @@ in
default = null;
};
plotDirectories = lib.mkOption {
type = with lib.types; nullOr (listOf str);
default = null;
type = with lib.types; listOf str;
default = [ ];
};
openFirewall = lib.mkOption {
type = lib.types.bool;
@ -46,7 +46,7 @@ in
};
virtualisation.oci-containers.containers.chia = {
image = "ghcr.io/chia-network/chia:2.4.1";
image = "ghcr.io/chia-network/chia:2.4.3";
ports = [ "8444" ];
extraOptions = [
"--uidmap=0:${toString config.users.users.chia.uid}:1"
@ -62,6 +62,11 @@ in
};
};
systemd.tmpfiles.rules = [
"d ${cfg.path} 0700 chia chia - -"
"d ${cfg.path}/.chia 0700 chia chia - -"
];
networking.firewall = lib.mkIf cfg.openFirewall {
allowedTCPPorts = [ 8444 ];
};

View File

@ -13,14 +13,15 @@
./ids.nix
./impermanence.nix
./locations.nix
./prometheus/default.nix
./resilio.nix
./sched_ext.nix
./services/default.nix
./shell/default.nix
./ssh/default.nix
./storj.nix
./users.nix
./www/global.nix
./www/www-repo.nix
./www/default.nix
];
options.custom = {

View File

@ -1,9 +1,10 @@
{ pkgs, lib, config, agenix, ... }:
{ pkgs, nixpkgs-unstable, lib, config, agenix, ... }:
{
options.custom.defaults = lib.mkEnableOption "defaults";
config = lib.mkIf config.custom.defaults {
hardware.enableAllFirmware = true;
nix = {
settings.experimental-features = [ "nix-command" "flakes" ];
settings = {
@ -38,7 +39,6 @@
git
htop
nix
sapling
vim
];
variables.EDITOR = "vim";
@ -53,11 +53,17 @@
};
networking.firewall.enable = true;
nix.registry.nixpkgs-unstable.to = {
type = "path";
path = nixpkgs-unstable;
};
# Delegation
custom.ca.consumer.enable = true;
custom.dns.enable = true;
custom.home.defaults = true;
custom.hostinfo.enable = true;
custom.prometheus.client.enable = true;
custom.shell.enable = true;
custom.ssh.enable = true;
};

View File

@ -50,10 +50,16 @@ in
pop = {
li = "100.106.87.35";
sodium = "100.87.188.4";
stinger = "100.117.89.126";
};
rig = {
merlin = "100.69.181.56";
};
st = {
phoenix = "100.92.37.106";
};
storage = {
theon = "100.104.142.22";
tywin = "100.115.31.91";
};
};
};
@ -77,10 +83,16 @@ in
pop = {
li = "fd7a:115c:a1e0::e701:5723";
sodium = "fd7a:115c:a1e0::3701:bc04";
stinger = "fd7a:115c:a1e0::8401:597e";
};
rig = {
merlin = "fd7a:115c:a1e0::8d01:b538";
};
st = {
phoenix = "fd7a:115c:a1e0::6901:256a";
};
storage = {
theon = "fd7a:115c:a1e0::4aa8:8e16";
tywin = "fd7a:115c:a1e0:ab12:4843:cd96:6273:1f5b";
};
};
};

View File

@ -3,30 +3,47 @@
{
imports = [
./git.nix
./neovim.nix
./tmux/default.nix
];
options.custom.home.defaults = lib.mkEnableOption "home";
config = lib.mkIf config.custom.home.defaults {
home-manager = {
home-manager =
let
stateVersion = if (builtins.compareVersions config.system.stateVersion "24.05") > 0 then config.system.stateVersion else "22.11";
in
{
users.root.home = {
stateVersion = "22.11";
inherit stateVersion;
## Set an empty ZSH config and defer to the global one
file.".zshrc".text = "";
};
users."${config.custom.user}".home = {
stateVersion = "22.11";
users."${config.custom.user}" = {
home = {
inherit stateVersion;
};
## Set an empty ZSH config and defer to the global one
file.".zshrc".text = "";
services = {
ssh-agent.enable = true;
};
programs = {
zoxide = {
enable = true;
options = [ "--cmd cd" ];
};
zsh.enable = true;
};
};
};
# Delegation
custom.home.git.enable = true;
custom.home.neovim.enable = true;
custom.home.tmux.enable = true;
};
}

View File

@ -9,13 +9,25 @@ in
};
config = lib.mkIf cfg.enable {
home-manager.users.jake.programs.git = lib.mkIf (config.custom.user == "jake") {
home-manager.users.jake.programs = {
sapling = lib.mkIf (config.custom.user == "jake") {
enable = true;
userName = "Jake Hillion";
userEmail = "jake@hillion.co.uk";
extraConfig = {
user = {
email = "jake@hillion.co.uk";
name = "Jake Hillion";
ui = {
"merge:interactive" = ":merge3";
};
};
};
git = lib.mkIf (config.custom.user == "jake") {
enable = true;
userName = "Jake Hillion";
userEmail = "jake@hillion.co.uk";
extraConfig = {
pull = {
rebase = true;
};
@ -28,4 +40,5 @@ in
};
};
};
};
}

82
modules/home/neovim.nix Normal file
View File

@ -0,0 +1,82 @@
{ pkgs, lib, config, ... }:
let
cfg = config.custom.home.neovim;
in
{
options.custom.home.neovim = {
enable = lib.mkEnableOption "neovim";
};
config = lib.mkIf config.custom.home.neovim.enable {
home-manager.users."${config.custom.user}".programs.neovim = {
enable = true;
viAlias = true;
vimAlias = true;
plugins = with pkgs.vimPlugins; [
a-vim
dracula-nvim
telescope-nvim
];
extraLuaConfig = ''
-- Logical options
vim.opt.splitright = true
vim.opt.splitbelow = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.expandtab = true
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
-- Appearance
vim.cmd[[colorscheme dracula-soft]]
vim.opt.number = true
vim.opt.relativenumber = true
-- Telescope
require('telescope').setup({
pickers = {
find_files = {
find_command = {
"${pkgs.fd}/bin/fd",
"--type=f",
"--strip-cwd-prefix",
"--no-require-git",
"--hidden",
"--exclude=.sl",
},
},
},
defaults = {
vimgrep_arguments = {
"${pkgs.ripgrep}/bin/rg",
"--color=never",
"--no-heading",
"--with-filename",
"--line-number",
"--column",
"--smart-case",
"--no-require-git",
"--hidden",
"--glob=!.sl",
},
},
})
-- Key bindings
vim.g.mapleader = ","
--- Key bindings: Telescope
local telescope_builtin = require('telescope.builtin')
vim.keymap.set('n', '<leader>ff', telescope_builtin.find_files, {})
vim.keymap.set('n', '<leader>fg', telescope_builtin.live_grep, {})
vim.keymap.set('n', '<leader>fb', telescope_builtin.buffers, {})
vim.keymap.set('n', '<leader>fh', telescope_builtin.help_tags, {})
'';
};
};
}

View File

@ -1,9 +1,16 @@
setw -g mouse on
# Large history
set -g history-limit 500000
# Bindings
bind C-Y set-window-option synchronize-panes
bind -n C-k clear-history
# Status pane
set -g status-right-length 100
set -g status-right "#(uname -r) • #(hostname -f | sed 's/\.ts\.hillion\.co\.uk//g') • %d-%b-%y %H:%M"
# New panes in the same directory
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"

View File

@ -7,6 +7,9 @@
unifi = 183;
chia = 185;
gitea = 186;
node-exporter = 188;
step-ca = 198;
isponsorblocktv = 199;
## Consistent People
jake = 1000;
@ -17,6 +20,9 @@
unifi = 183;
chia = 185;
gitea = 186;
node-exporter = 188;
step-ca = 198;
isponsorblocktv = 199;
## Consistent Groups
mediaaccess = 1200;

View File

@ -46,6 +46,22 @@ in
gitea.stateDir = "${cfg.base}/system/var/lib/gitea";
};
custom.chia = lib.mkIf config.custom.chia.enable {
path = lib.mkOverride 999 "/data/chia";
};
services.resilio = lib.mkIf config.services.resilio.enable {
directoryRoot = lib.mkOverride 999 "${cfg.base}/sync";
};
services.plex = lib.mkIf config.services.plex.enable {
dataDir = lib.mkOverride 999 "/data/plex";
};
services.home-assistant = lib.mkIf config.services.home-assistant.enable {
configDir = lib.mkOverride 999 "/data/home-assistant";
};
environment.persistence = lib.mkMerge [
{
"${cfg.base}/system" = {
@ -60,6 +76,9 @@ in
(lib.lists.optional config.custom.services.unifi.enable "/var/lib/unifi") ++
(lib.lists.optional (config.virtualisation.oci-containers.containers != { }) "/var/lib/containers") ++
(lib.lists.optional config.services.tang.enable "/var/lib/private/tang") ++
(lib.lists.optional config.services.caddy.enable "/var/lib/caddy") ++
(lib.lists.optional config.services.prometheus.enable "/var/lib/${config.services.prometheus.stateDir}") ++
(lib.lists.optional config.custom.services.isponsorblocktv.enable "${config.custom.services.isponsorblocktv.dataDir}") ++
(lib.lists.optional config.services.step-ca.enable "/var/lib/step-ca/db");
};
}
@ -74,7 +93,11 @@ in
home-manager.users =
let
mkUser = (x: {
mkUser = (x:
let
homeCfg = config.home-manager.users."${x}";
in
{
name = x;
value = {
home = {
@ -84,9 +107,12 @@ in
files = cfg.userExtraFiles.${x} or [ ];
directories = cfg.userExtraDirs.${x} or [ ];
};
file.".zshrc".text = lib.mkForce ''
HISTFILE=/data/users/${x}/.zsh_history
'';
sessionVariables = lib.attrsets.optionalAttrs homeCfg.programs.zoxide.enable { _ZO_DATA_DIR = "/data/users/${x}/.local/share/zoxide"; };
};
programs = {
zsh.history.path = lib.mkOverride 999 "/data/users/${x}/.zsh_history";
};
};
});

View File

@ -20,11 +20,13 @@ in
custom.locations.locations = {
services = {
authoritative_dns = [ "boron.cx.ts.hillion.co.uk" ];
downloads = "tywin.storage.ts.hillion.co.uk";
downloads = "phoenix.st.ts.hillion.co.uk";
gitea = "boron.cx.ts.hillion.co.uk";
homeassistant = "microserver.home.ts.hillion.co.uk";
homeassistant = "stinger.pop.ts.hillion.co.uk";
mastodon = "";
matrix = "boron.cx.ts.hillion.co.uk";
prometheus = "boron.cx.ts.hillion.co.uk";
restic = "phoenix.st.ts.hillion.co.uk";
tang = [
"li.pop.ts.hillion.co.uk"
"microserver.home.ts.hillion.co.uk"

View File

@ -0,0 +1,24 @@
{ pkgs, lib, config, ... }:
let
cfg = config.custom.prometheus.client;
in
{
options.custom.prometheus.client = {
enable = lib.mkEnableOption "prometheus-client";
};
config = lib.mkIf cfg.enable {
users.users.node-exporter.uid = config.ids.uids.node-exporter;
users.groups.node-exporter.gid = config.ids.gids.node-exporter;
services.prometheus.exporters.node = {
enable = true;
port = 9000;
enabledCollectors = [
"systemd"
];
};
};
}

View File

@ -0,0 +1,8 @@
{ ... }:
{
imports = [
./client.nix
./service.nix
];
}

View File

@ -0,0 +1,67 @@
{ pkgs, lib, config, ... }:
let
cfg = config.custom.services.prometheus;
in
{
options.custom.services.prometheus = {
enable = lib.mkEnableOption "prometheus-client";
};
config = lib.mkIf cfg.enable {
services.prometheus = {
enable = true;
globalConfig = {
scrape_interval = "15s";
};
retentionTime = "1y";
scrapeConfigs = [{
job_name = "node";
static_configs = [{
targets = builtins.map (x: "${x}:9000") (builtins.attrNames (builtins.readDir ../../hosts));
}];
}];
rules = [
''
groups:
- name: service alerting
rules:
- alert: ResilioSyncDown
expr: node_systemd_unit_state{ name = 'resilio.service', state != 'active' } > 0
for: 10m
annotations:
summary: "Resilio Sync systemd service is down"
description: "The Resilio Sync systemd service is not active on instance {{ $labels.instance }}."
''
];
};
services.caddy = {
enable = true;
virtualHosts."prometheus.ts.hillion.co.uk" = {
listenAddresses = [ config.custom.dns.tailscale.ipv4 config.custom.dns.tailscale.ipv6 ];
extraConfig = ''
reverse_proxy http://localhost:9090
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
'';
};
};
### HACK: Allow Caddy to restart if it fails. This happens because Tailscale
### is too late at starting. Upstream nixos caddy does restart on failure
### but it's prevented on exit code 1. Set the exit code to 0 (non-failure)
### to override this.
systemd.services.caddy = {
requires = [ "tailscaled.service" ];
after = [ "tailscaled.service" ];
serviceConfig = {
RestartPreventExitStatus = lib.mkForce 0;
};
};
};
}

View File

@ -4,6 +4,9 @@ let
cfg = config.custom.resilio;
in
{
imports = [ "${nixpkgs-unstable}/nixos/modules/services/networking/resilio.nix" ];
disabledModules = [ "services/networking/resilio.nix" ];
options.custom.resilio = {
enable = lib.mkEnableOption "resilio";
@ -16,9 +19,14 @@ in
type = with lib.types; uniq (listOf attrs);
default = [ ];
};
backups = {
enable = lib.mkEnableOption "resilio.backups";
};
};
config = lib.mkIf cfg.enable {
config = lib.mkIf cfg.enable (lib.mkMerge [
{
users.users =
let
mkUser =
@ -46,6 +54,10 @@ in
services.resilio = {
enable = true;
deviceName = lib.mkOverride 999 (lib.strings.concatStringsSep "." (lib.lists.take 2 (lib.strings.splitString "." config.networking.fqdnOrHostName)));
storagePath = lib.mkOverride 999 "${config.services.resilio.directoryRoot}/.sync";
sharedFolders =
let
mkFolder = name: secret: {
@ -61,5 +73,39 @@ in
in
builtins.map (folder: mkFolder folder.name folder.secret) cfg.folders;
};
};
systemd.services.resilio.unitConfig.RequiresMountsFor = builtins.map (folder: "${config.services.resilio.directoryRoot}/${folder.name}") cfg.folders;
}
(lib.mkIf cfg.backups.enable {
age.secrets."resilio/restic/128G.key" = {
file = ../secrets/restic/128G.age;
owner = "rslsync";
group = "rslsync";
};
services.restic.backups."resilio" = {
repository = "rest:https://restic.ts.hillion.co.uk/128G";
user = "rslsync";
passwordFile = config.age.secrets."resilio/restic/128G.key".path;
timerConfig = {
OnBootSec = "10m";
OnUnitInactiveSec = "15m";
RandomizedDelaySec = "5m";
};
paths = [ config.services.resilio.directoryRoot ];
exclude = [
"${config.services.resilio.directoryRoot}/.sync"
"${config.services.resilio.directoryRoot}/*/.sync"
"${config.services.resilio.directoryRoot}/resources/media/films"
"${config.services.resilio.directoryRoot}/resources/media/iso"
"${config.services.resilio.directoryRoot}/resources/media/tv"
"${config.services.resilio.directoryRoot}/dad/media"
];
};
})
]);
}

22
modules/sched_ext.nix Normal file
View File

@ -0,0 +1,22 @@
{ config, pkgs, lib, ... }:
let
cfg = config.custom.sched_ext;
in
{
options.custom.sched_ext = {
enable = lib.mkEnableOption "sched_ext";
};
config = lib.mkIf cfg.enable {
assertions = [{
assertion = config.boot.kernelPackages.kernelAtLeast "6.12";
message = "sched_ext requires a kernel >=6.12";
}];
boot.kernelPackages = if pkgs.linuxPackages.kernelAtLeast "6.12" then pkgs.linuxPackages else (if pkgs.linuxPackages_latest.kernelAtLeast "6.12" then pkgs.linuxPackages_latest else pkgs.unstable.linuxPackages_testing);
environment.systemPackages = with pkgs; [ unstable.scx.layered unstable.scx.lavd ];
};
}

View File

@ -33,14 +33,20 @@ in
86400 NS ns1.hillion.co.uk.
ca 21600 CNAME sodium.pop.ts.hillion.co.uk.
deluge.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk.
restic 21600 CNAME ${config.custom.locations.locations.services.restic}.
prometheus 21600 CNAME ${config.custom.locations.locations.services.prometheus}.
deluge.downloads 21600 CNAME ${config.custom.locations.locations.services.downloads}.
prowlarr.downloads 21600 CNAME ${config.custom.locations.locations.services.downloads}.
radarr.downloads 21600 CNAME ${config.custom.locations.locations.services.downloads}.
sonarr.downloads 21600 CNAME ${config.custom.locations.locations.services.downloads}.
graphs.router.home 21600 CNAME router.home.ts.hillion.co.uk.
prowlarr.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk.
radarr.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk.
restic.tywin.storage 21600 CNAME tywin.storage.ts.hillion.co.uk.
sonarr.downloads 21600 CNAME tywin.storage.ts.hillion.co.uk.
zigbee2mqtt.home 21600 CNAME router.home.ts.hillion.co.uk.
charlie.kvm 21600 CNAME router.home.ts.hillion.co.uk.
hammer.kvm 21600 CNAME router.home.ts.hillion.co.uk.
'' + (makeRecords "A" config.custom.dns.authoritative.ipv4.uk.co.hillion.ts) + "\n\n" + (makeRecords "AAAA" config.custom.dns.authoritative.ipv6.uk.co.hillion.ts);
};
};

View File

@ -6,8 +6,10 @@
./downloads.nix
./gitea/default.nix
./homeassistant.nix
./isponsorblocktv.nix
./mastodon/default.nix
./matrix.nix
./restic.nix
./tang.nix
./unifi.nix
./version_tracker.nix

View File

@ -24,6 +24,12 @@ in
};
config = lib.mkIf cfg.enable {
age.secrets."wireguard/downloads".file = ../../secrets/wireguard/downloads.age;
age.secrets."deluge/auth" = {
file = ../../secrets/deluge/auth.age;
owner = "deluge";
};
services.caddy = {
enable = true;
@ -45,12 +51,6 @@ in
## Wireguard
age.secrets."wireguard/downloads".file = ../../secrets/wireguard/downloads.age;
age.secrets."deluge/auth" = {
file = ../../secrets/deluge/auth.age;
owner = "deluge";
};
networking.wireguard.interfaces."downloads" = {
privateKeyFile = config.age.secrets."wireguard/downloads".path;
ips = [ "10.2.0.2/32" ];

View File

@ -1,4 +1,4 @@
{ config, pkgs, lib, nixpkgs-unstable, ... }:
{ config, pkgs, lib, ... }:
let
cfg = config.custom.services.gitea;
@ -55,7 +55,7 @@ in
services.gitea = {
enable = true;
package = nixpkgs-unstable.legacyPackages.x86_64-linux.gitea;
package = pkgs.unstable.gitea;
mailerPasswordFile = config.age.secrets."gitea/mailer_password".path;
appName = "Hillion Gitea";

View File

@ -44,6 +44,7 @@ in
"bluetooth"
"default_config"
"esphome"
"fully_kiosk"
"google_assistant"
"homekit"
"met"
@ -54,6 +55,7 @@ in
"sonos"
"sun"
"switchbot"
"waze_travel_time"
];
customComponents = with pkgs.home-assistant-custom-components; [
adaptive_lighting
@ -62,6 +64,20 @@ in
config = {
default_config = { };
homeassistant = {
auth_providers = [
{ type = "homeassistant"; }
{
type = "trusted_networks";
trusted_networks = [ "10.239.19.4/32" ];
trusted_users = {
"10.239.19.4" = "fb4979873ecb480d9e3bb336250fa344";
};
allow_bypass_login = true;
}
];
};
recorder = {
db_url = "postgresql://@/homeassistant";
};
@ -71,6 +87,8 @@ in
trusted_proxies = with config.custom.dns.authoritative; [
ipv4.uk.co.hillion.ts.cx.boron
ipv6.uk.co.hillion.ts.cx.boron
ipv4.uk.co.hillion.ts.pop.sodium
ipv6.uk.co.hillion.ts.pop.sodium
];
};

View File

@ -0,0 +1,62 @@
{ config, pkgs, lib, ... }:
let
cfg = config.custom.services.isponsorblocktv;
ver = "v2.2.1";
ctl = pkgs.writeScriptBin "isponsorblocktv-config" ''
#! ${pkgs.runtimeShell}
set -e
sudo systemctl stop podman-isponsorblocktv
sudo ${pkgs.podman}/bin/podman run \
--rm -it \
--uidmap=0:${toString config.users.users.isponsorblocktv.uid}:1 \
--gidmap=0:${toString config.users.groups.isponsorblocktv.gid}:1 \
-v ${cfg.dataDir}:/app/data \
ghcr.io/dmunozv04/isponsorblocktv:${ver} \
--setup-cli
sudo systemctl start podman-isponsorblocktv
'';
in
{
options.custom.services.isponsorblocktv = {
enable = lib.mkEnableOption "isponsorblocktv";
dataDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/isponsorblocktv";
};
};
config = lib.mkIf cfg.enable {
environment.systemPackages = [ ctl ];
users.groups.isponsorblocktv = {
gid = config.ids.gids.isponsorblocktv;
};
users.users.isponsorblocktv = {
home = cfg.dataDir;
createHome = true;
isSystemUser = true;
group = "isponsorblocktv";
uid = config.ids.uids.isponsorblocktv;
};
virtualisation.oci-containers.containers.isponsorblocktv = {
image = "ghcr.io/dmunozv04/isponsorblocktv:${ver}";
extraOptions = [
"--uidmap=0:${toString config.users.users.isponsorblocktv.uid}:1"
"--gidmap=0:${toString config.users.groups.isponsorblocktv.gid}:1"
];
volumes = [ "${cfg.dataDir}:/app/data" ];
};
systemd.tmpfiles.rules = [
"d ${cfg.dataDir} 0700 isponsorblocktv isponsorblocktv - -"
];
};
}

306
modules/services/restic.nix Normal file
View File

@ -0,0 +1,306 @@
{ config, pkgs, lib, ... }:
let
cfg = config.custom.services.restic;
in
{
options.custom.services.restic = {
enable = lib.mkEnableOption "restic http server";
path = lib.mkOption {
type = lib.types.path;
default = "/var/lib/restic";
};
repos = lib.mkOption {
readOnly = true;
type = with lib.types; attrsOf (submodule {
options = {
path = lib.mkOption {
default = null;
type = nullOr str;
};
passwordFile = lib.mkOption {
default = null;
type = nullOr str;
};
environmentFile = lib.mkOption {
default = null;
type = nullOr str;
};
forgetConfig = lib.mkOption {
default = null;
type = nullOr (submodule {
options = {
timerConfig = lib.mkOption {
type = attrs;
};
opts = lib.mkOption {
type = listOf str;
};
};
});
};
clones = lib.mkOption {
default = [ ];
type = listOf (submodule {
options = {
timerConfig = lib.mkOption {
type = attrs;
};
repo = lib.mkOption {
type = str;
};
};
});
};
};
});
default = {
"128G" = {
path = "${cfg.path}/128G";
passwordFile = config.age.secrets."restic/128G.key".path;
forgetConfig = {
timerConfig = {
OnCalendar = "02:30";
RandomizedDelaySec = "1h";
};
opts = [
"--keep-last 48"
"--keep-within-hourly 7d"
"--keep-within-daily 1m"
"--keep-within-weekly 6m"
"--keep-within-monthly 24m"
];
};
clones = [
{
repo = "128G-wasabi";
timerConfig = {
OnBootSec = "30m";
OnUnitInactiveSec = "60m";
RandomizedDelaySec = "20m";
};
}
{
repo = "128G-backblaze";
timerConfig = {
OnBootSec = "30m";
OnUnitInactiveSec = "60m";
RandomizedDelaySec = "20m";
};
}
];
};
"1.6T" = {
path = "${cfg.path}/1.6T";
passwordFile = config.age.secrets."restic/1.6T.key".path;
forgetConfig = {
timerConfig = {
OnCalendar = "Wed, 02:30";
RandomizedDelaySec = "4h";
};
opts = [
"--keep-within-daily 14d"
"--keep-within-weekly 2m"
"--keep-within-monthly 18m"
];
};
clones = [
{
repo = "1.6T-wasabi";
timerConfig = {
OnBootSec = "30m";
OnUnitInactiveSec = "60m";
RandomizedDelaySec = "20m";
};
}
{
repo = "1.6T-backblaze";
timerConfig = {
OnBootSec = "30m";
OnUnitInactiveSec = "60m";
RandomizedDelaySec = "20m";
};
}
];
};
"128G-wasabi" = {
environmentFile = config.age.secrets."restic/128G-wasabi.env".path;
};
"1.6T-wasabi" = {
environmentFile = config.age.secrets."restic/1.6T-wasabi.env".path;
};
"128G-backblaze" = {
environmentFile = config.age.secrets."restic/128G-backblaze.env".path;
};
"1.6T-backblaze" = {
environmentFile = config.age.secrets."restic/1.6T-backblaze.env".path;
};
};
};
};
config = lib.mkIf cfg.enable {
age.secrets = {
"restic/128G.key" = {
file = ../../secrets/restic/128G.age;
owner = "restic";
group = "restic";
};
"restic/128G-wasabi.env".file = ../../secrets/restic/128G-wasabi.env.age;
"restic/128G-backblaze.env".file = ../../secrets/restic/128G-backblaze.env.age;
"restic/1.6T.key" = {
file = ../../secrets/restic/1.6T.age;
owner = "restic";
group = "restic";
};
"restic/1.6T-wasabi.env".file = ../../secrets/restic/1.6T-wasabi.env.age;
"restic/1.6T-backblaze.env".file = ../../secrets/restic/1.6T-backblaze.env.age;
};
services.restic.server = {
enable = true;
appendOnly = true;
extraFlags = [ "--no-auth" ];
dataDir = cfg.path;
listenAddress = "127.0.0.1:8000"; # TODO: can this be a Unix socket?
};
services.caddy = {
enable = true;
virtualHosts."restic.ts.hillion.co.uk".extraConfig = ''
bind ${config.custom.dns.tailscale.ipv4} ${config.custom.dns.tailscale.ipv6}
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
reverse_proxy http://localhost:8000
'';
};
systemd =
let
mkRepoInfo = repo_cfg: (if (repo_cfg.passwordFile != null) then {
serviceConfig.LoadCredential = [
"password_file:${repo_cfg.passwordFile}"
];
environment = {
RESTIC_REPOSITORY = repo_cfg.path;
RESTIC_PASSWORD_FILE = "%d/password_file";
};
} else {
serviceConfig.EnvironmentFile = repo_cfg.environmentFile;
});
mkForgetService = name: repo_cfg:
if (repo_cfg.forgetConfig != null) then
({
description = "Restic forget service for ${name}";
serviceConfig = {
User = "restic";
Group = "restic";
};
script = ''
set -xe
${pkgs.restic}/bin/restic forget ${lib.strings.concatStringsSep " " repo_cfg.forgetConfig.opts} \
--prune \
--retry-lock 30m
'';
} // (mkRepoInfo repo_cfg)) else { };
mkForgetTimer = repo_cfg:
if (repo_cfg.forgetConfig != null) then {
wantedBy = [ "timers.target" ];
timerConfig = repo_cfg.forgetConfig.timerConfig;
} else { };
mkCloneService = from_repo: clone_cfg: to_repo: {
name = "restic-clone-${from_repo.name}-${to_repo.name}";
value = lib.mkMerge [
{
description = "Restic copy from ${from_repo.name} to ${to_repo.name}";
serviceConfig = {
User = "restic";
Group = "restic";
LoadCredential = [
"from_password_file:${from_repo.cfg.passwordFile}"
];
};
environment = {
RESTIC_FROM_PASSWORD_FILE = "%d/from_password_file";
};
script = ''
set -xe
${pkgs.restic}/bin/restic copy \
--from-repo ${from_repo.cfg.path} \
--retry-lock 30m
'';
}
(mkRepoInfo to_repo.cfg)
];
};
mkCloneTimer = from_repo: clone_cfg: to_repo: {
name = "restic-clone-${from_repo.name}-${to_repo.name}";
value = {
wantedBy = [ "timers.target" ];
timerConfig = clone_cfg.timerConfig;
};
};
mapClones = fn: builtins.listToAttrs (lib.lists.flatten (lib.mapAttrsToList
(
from_repo_name: from_repo_cfg: (builtins.map
(
clone_cfg: (fn
{ name = from_repo_name; cfg = from_repo_cfg; }
clone_cfg
{ name = clone_cfg.repo; cfg = cfg.repos."${clone_cfg.repo}"; }
)
)
from_repo_cfg.clones)
)
cfg.repos));
in
{
services = {
caddy = {
### HACK: Allow Caddy to restart if it fails. This happens because Tailscale
### is too late at starting. Upstream nixos caddy does restart on failure
### but it's prevented on exit code 1. Set the exit code to 0 (non-failure)
### to override this.
requires = [ "tailscaled.service" ];
after = [ "tailscaled.service" ];
serviceConfig = {
RestartPreventExitStatus = lib.mkForce 0;
};
};
}
// lib.mapAttrs' (name: value: lib.attrsets.nameValuePair ("restic-forget-" + name) (mkForgetService name value)) cfg.repos
// mapClones mkCloneService;
timers = lib.mapAttrs' (name: value: lib.attrsets.nameValuePair ("restic-forget-" + name) (mkForgetTimer value)) cfg.repos
// mapClones mkCloneTimer;
};
};
}

View File

@ -13,7 +13,10 @@ in
enable = true;
ipAddressAllow = [
"138.201.252.214/32"
"10.64.50.20/32"
"10.64.50.26/32"
"10.64.50.27/32"
"10.64.50.28/32"
"10.64.50.29/32"
];
};
};

View File

@ -75,7 +75,7 @@ in
};
services.restic.backups."zigbee2mqtt" = lib.mkIf cfg.backup {
repository = "rest:http://restic.tywin.storage.ts.hillion.co.uk/1.6T";
repository = "rest:https://restic.ts.hillion.co.uk/1.6T";
user = "zigbee2mqtt";
passwordFile = config.age.secrets."resilio/zigbee2mqtt/1.6T.key".path;

View File

@ -14,6 +14,8 @@ in
"jake".openssh.authorizedKeys.keys = [
"sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBBwJH4udKNvi9TjOBgkxpBBy7hzWqmP0lT5zE9neusCpQLIiDhr6KXYMPXWXdZDc18wH1OLi2+639dXOvp8V/wgAAAAEc3NoOg== jake@beryllium-keys"
"sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBPPJtW19jOaUsjmxc0+QibaLJ3J3yxPXSXZXwKT0Ean6VeaH5G8zG+zjt1Y6sg2d52lHgrRfeVl1xrG/UGX8qWoAAAAEc3NoOg== jakehillion@jakehillion-mbp"
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOt74U+rL+BMtAEjfu/Optg1D7Ly7U+TupRxd5u9kfN7oJnW4dJA25WRSr4dgQNq7MiMveoduBY/ky2s0c9gvIA= jake@jake-gentoo"
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBC0uKIvvvkzrOcS7AcamsQRFId+bqPwUC9IiUIsiH5oWX1ReiITOuEo+TL9YMII5RyyfJFeu2ZP9moNuZYlE7Bs= jake@jake-mbp"
@ -48,7 +50,6 @@ in
"router.home.ts.hillion.co.uk".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAlCj/i2xprN6h0Ik2tthOJQy6Qwq3Ony73+yfbHYTFu";
"sodium.pop.ts.hillion.co.uk".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDQmG7v/XrinPmkTU2eIoISuU3+hoV4h60Bmbwd+xDjr";
"theon.storage.ts.hillion.co.uk".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN59psLVu3/sQORA4x3p8H3ei8MCQlcwX5T+k3kBeBMf";
"tywin.storage.ts.hillion.co.uk".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGATsjWO0qZNFp2BhfgDuWi+e/ScMkFxp79N2OZoed1k";
};
programs.ssh.knownHostsFiles = [ ./github_known_hosts ];
};

10
modules/www/default.nix Normal file
View File

@ -0,0 +1,10 @@
{ config, lib, ... }:
{
imports = [
./global.nix
./home.nix
./iot.nix
./www-repo.nix
];
}

View File

@ -33,6 +33,11 @@ in
services.caddy = {
enable = true;
package = pkgs.unstable.caddy;
globalConfig = ''
email acme@hillion.co.uk
'';
virtualHosts = {
"hillion.co.uk".extraConfig = ''

27
modules/www/home.nix Normal file
View File

@ -0,0 +1,27 @@
{ pkgs, lib, config, ... }:
let
cfg = config.custom.www.home;
locations = config.custom.locations.locations;
in
{
options.custom.www.home = {
enable = lib.mkEnableOption "home";
};
config = lib.mkIf cfg.enable {
services.caddy = {
enable = true;
virtualHosts = {
"homeassistant.home.hillion.co.uk".extraConfig = ''
bind 10.64.50.25
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
reverse_proxy http://${locations.services.homeassistant}:8123
'';
};
};
};
}

32
modules/www/iot.nix Normal file
View File

@ -0,0 +1,32 @@
{ pkgs, lib, config, ... }:
let
cfg = config.custom.www.iot;
locations = config.custom.locations.locations;
in
{
options.custom.www.iot = {
enable = lib.mkEnableOption "iot";
};
config = lib.mkIf cfg.enable {
services.caddy = {
enable = true;
package = pkgs.unstable.caddy;
virtualHosts = {
"homeassistant.iot.hillion.co.uk".extraConfig = ''
bind 10.239.19.5
tls {
ca https://ca.ts.hillion.co.uk:8443/acme/acme/directory
}
@blocked not remote_ip 10.239.19.4
respond @blocked "<h1>Access Denied</h1>" 403
reverse_proxy http://${locations.services.homeassistant}:8123
'';
};
};
};
}

View File

@ -57,7 +57,7 @@ in
${pkgs.git}/bin/git clone ${cfg.remote} ${cfg.location}
else
cd ${cfg.location}
${pkgs.git} remote set-url origin ${cfg.remote}
${pkgs.git}/bin/git remote set-url origin ${cfg.remote}
${pkgs.git}/bin/git fetch
${pkgs.git}/bin/git reset --hard origin/${cfg.branch}
fi

View File

@ -0,0 +1,15 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p restic rsync
set -e
HOST="restic.ts.hillion.co.uk"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
rsync -ar --no-perms --delete-after --rsync-path='sudo -u restic rsync' --progress $HOST:/practical-defiant-coffee/backups/restic/128G/ restic/128G
echo 'checking 128G'
restic -r restic/128G check --read-data-subset=25%
touch last_synced

View File

@ -2,12 +2,12 @@
#!nix-shell -i bash -p restic rsync
set -e
HOST="tywin.storage.ts.hillion.co.uk"
HOST="restic.ts.hillion.co.uk"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$DIR"
rsync -ar --no-perms --delete-after --rsync-path='sudo -u restic rsync' --progress $HOST:/data/backups/restic/ restic
rsync -ar --no-perms --delete-after --rsync-path='sudo -u restic rsync' --progress $HOST:/practical-defiant-coffee/backups/restic/ restic
echo 'checking 128G'
restic -r restic/128G check --read-data
@ -15,4 +15,3 @@ echo 'checking 1.6T'
restic -r restic/1.6T check --read-data
touch last_synced

Binary file not shown.

Binary file not shown.

View File

@ -1,23 +1,31 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
AiswwF+XOeVnSZ7QbCIG+4D+o5JxVYlw6d4R1GDj3orsEGPy8a83QtjiUiNDUwFO
/3GD3I6Hv5/H16s5kLVjxachAKKequNMtZ3R9y8pJaCa3i2Ypf0itlryoPT5MywA
vlgLzPHmc/eYdyOGWJ+Lfe5ZYq8cGSyWn7E2g5KzWxj3+Pn4onNwTCQBClPtebrw
E3mvTywpIvWQ5QyrJHIkFQERoKO1kprL9G5ikvgvGqC87SLPsOhvCX/5a83znKPo
8HMEUDIUbcyjaTusdXpXdRtFEtjDoXR2lDsbJB73LG7u9mBFwJNDPeI5ulWL/7kl
whb9xs87Z6JaEJFZOB1jwfsIUGQKVSoHAWNWfM6WT9tNkYfh+mulQOuE99rEwGVn
+/Mo5nYMfmb0hUeQEEVAdfko4w4NvWvUIq0keZ4M9IjfggOdDPM7wG41xKcqXJkz
d92e4Qj7fl8ldMcha7EJkXKTuP48zBeEmnWwMRY0UAbnHsIb0ko03Wi5fO8tKiHj
sl/asjk074jextEkhlzGQrDtJm2rK9GXuZVvtuIy+wKRWNs0sS7NqArlZj5jlUbB
sPYf5JeWBC3pEcdN73T+O4CIssOT5k7D7k8P2h8zw5Se2iMAjB50sFnCOe6Iiyfq
RHL/686aDDCJVqQ2tk0N25oT4h1Xk7dJZSNFaFh47zs
-> ssh-rsa GxPFJQ
F1+/Im3cdSzHDBn2W5LAV+ezO23nrjzaeVLQ0pFNYMt6v8XTA/WHHTPsImg/Nebi
noLNcxgjPu3fSnubXJuhsL5kQ6qHWvjQlQ0cRVSnMvV4UvrrPyp0066q1iMBL3PA
rh4hQ7sF4sHz3pm9jtxfdnWamGxqsowE793AjtNEvSU/i9/ZkFrKRj0LLAhHeIHJ
dWdYpnlZIrRjXFo6y+jdYpK0gyGQopy4SwoRwvDmQ/5paBRhpiXYUPtwRckiz/KE
iHA0WJhDO9a5OHLN9WPnKVRIutH/YHviy4twyPDjhHCDeJBQE02Lykd6wvJg9cWT
BkCeYhVdGp7VpWZEbLCtnw
in/cSQ8GJaS5GpEdJFXBC8no9M3BRcB+F98R1Xm+MSlyS153MVuNcGUAfEQ9RbOd
8nKFnJ0ZjvgWnE342cJPnOZJ9yrMi7pcRy8RXslMIIBXLnt5Tv32kJJSdWYfOyHc
aT3ZYQN3j+rqokLb2Axe95pWCXKj/wUyoBCYgC5evb8/ek6XRVA647bnET5DsD0J
HCTXanw3Nm6l6Uy/AJ87FM3tBaIzA/EIktZiS1ujY7yKOU5R0VPvmwZEFC8Y4dSE
k3FbG6aUcz9JP+BSA2bO3p3z89fyun7MFgPZt0xW7EVN+YQaamqdQOFtXZZAdDzq
jDVgoCbFm/g8bJzvFAFq+w
-> ssh-rsa K9mW1w
Pm7esUbyDOoLdzxxrRkOXYxodhfKdK+X41nAT2AOR0bBcNHqGt8BSvL+HOK1vbOW
AquzA7+S91aNF7noV3JPIDrWZxDquqBp4z89YYyWNjpH9EIOYa2Sbp5xNFdgyAJw
C0uS3B/XKJcQi2np39szNzuR2h7uTKkKW5wMan+YUK1ODxmTJVibo0c0JUybMjXA
VS31BrkDb0LKRgvp/kNfn9aEaI7d78oca+6X0BDHk2zYRPwL1Q/MGw4tkx3pqI+x
i6frCSHlo715tHaYvxRQyimWthmUft/1etMasFINhLidx4ufdawLR6sbR09sCrMj
5NMeB1wc1XrGxwMumNDWyg
-> ssh-ed25519 nWv9MA CxCjLfbIfEn1voAr3jX+dRGnHmdAyylNuPn/2QfuphM
PS2cpu13uyPlo9PJIT+dybq4P2juNpiZY61sJq7DepQ
-> )ei-grease ,jk Bw
IucfaHwBWhzdMcTDXxOUyTy1kCUnSlsfAwVw8YKimsxHyvJS+wkyPXUzepHMZYId
SvebFA
--- q53LwYLjQ6p0yHStpDma4DYMpfFTpv7+MAzaHjM7Kaw
¹§—?0šîÕº9S>íƒÊìhàÛ(Æ Qå>8;þÓz°Øø¿L‰úPYhJÞsÛ@¥dÕÒœC׌<C397>9Ú¿{r|­±t¶¡aNv3'o•
ôÖ±¹d= í¦àZ<C3A0>`T62(€÷$ÓH°ŸZ:œQhµú<C2B5>
sSMw9YdkrWxDctoj4jEEd7d3Pzaar13X/AlYmaUjl4JFG5en372xl1TUvqX8GN0k
ZwtLyUdSZCubpu+2Hd17hMK06KYz0jyV8qobsepgifgEvsFCeGq356pd6wDWaoog
hARFKOgHgHV6ElHlwkeWjIeFkz5BunTUn3NTZGlbDFnhKnEw1dexy98ZRmrZ7vlO
6+55q81hL1eRsBuenq8/hF+5zsnJK6pNnfL34NlPU8uQ5EmHZoDxpsk0AhJAOijK
Jh18WlnsHdLganJpa7vx8fn/rPUJq+M5ieNCu+BFvta08UA7vmlW/OYkaFIn4weS
OfzizypwKK4Y1HV+PMdtKg
-> ssh-ed25519 RR/L5A iVk2PxSSxsqJ6TKq2kXOATgdBf3WXVikjuXTonkXnwQ
cbeSnGk8CAwz20mJUa2tkaJMNCbcU2tvzH+aRdJ1aPE
--- CaEXrA9MPkvFWguILIVe2FhmFbgeHMNTHXgvDBf3Hbk
Baüm'm™£ÏAOðOU!ýzÊ(ÿü#Ô°¾ÿ_?!g÷q" ù§žŽZƒ<5A>è|æ·šî÷aOó|HªüÐûSq&ÆÆn+w<>$áZ^ù Gg|à(HR,<06>àm1VÁÈÄû<C384>3]ÁE~püÃ/¥e÷²

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,19 +1,31 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
uM89I2iF5jhpx3ndhtroIDxXWMSZew8mSLLBiSisYM+CfjtGKOVCDvmOFNSgPz1g
96D93T9esUo+KSwWyhhEqUwEHyrdnHVPkTAQ73ie/ZoSvdCPmdSA0RgKbyYHSTp1
Z1hS/SN0xLSshz8aur/dd6FC01Ju0dqjDgCMN6edNhJfMhZXc2xidcj7Ir2T77B9
kFnLqAADHL8yyHfQzU7EIzWp857mcn4sbtPV5CuMfSvOzAdQWMxtFQndJUTnokTz
e3Gg57gkNOa50jYbr0fxN7fUBWu7J/MyOErwbRq5TzF/ZfbHkrH5iXvMBaNjSQy1
RVQozDXJ+j5oc14TQDbi59kOi4ZJmXJTk+eCFMTalYrHqdtTqV9c7KsOdiceeajp
wec3Iowgben4uqEgBluJtn5lRoDSdmKWbYSYxL3E/wX+0df8P9aZpTTEGGfhH+RY
yxhalaRYmLHD8kJ8yBlPdcKx9y6hkkE5Me+IB9Soh4pqtTbk3k/7pHLRYD2sq1T2
gxipaSumoj5trfPnp75qOTubnJ+a3l5FPiv3JOe0nOxY8zFuv7IcOsvcVipo1z+X
miuOVgbZeZrKb7//zVb0Dn1IJSZITY0SsWbNh8MVB7N5xN9iGWAmE9adrnbCKFIZ
PWteIw7/tlZHdUEr0QJwim1Br639Ah41mMspltsKA2c
-> ssh-rsa GxPFJQ
bIDYJMyhT4Tt0oTNWGwahKnw7ewWky+O8J7ExiDqIRNskA99SJ45u4n03mc6uQl0
56gTQ53HEQIH7u4DfITmKTf5iSn6O7QDW0c15dJ7P1hz3JaPu4p/Lyuzy9B1RcUY
XjNhmRyIAJdUWla/+k+o/dLRp46CtK3nIoxLd8all7vPys8i2gBQIr4HmmkZ4Nd1
CFQCXbb58asmAcYta1nTTY5yvFq6IHDbWPZDGOYCWceFoPCjlkvVH4VJjTQ7uyLX
bopz3gKxUogk0RTuF0o8tfqeZzJhcXOB0tvMfpPmMnQh08u8t4j8kVlnv+Ru5ZsE
H95rbwVArprojzFBy1fcHQ
sGxzilQ4r6X/D1MXKuXVI4p8v6KGnqN+4WUqda8OknlK79PTQY58fL/Mtmep+syZ
D11IuciWOSbaH21ZH3fuUNuNz0CRq+JWgkLnI0HwcnXH/Ni2MvXTiX9ihHzLawDE
ApkC+UbpUcZ5qsOQp2Kh0hbtLj+vegsQeIiMej4g13Z0QS6P7ElX5lYkdv/TBjXS
b1AwwmSuhl/IPzfnvMqnwpa/QeyweC7aSPuuy4WQQwjJa7pAPvuyZl7Bi2KfSa/c
p3SJsGNMJxeNUrD0FC/k/Jn0qm1B0Hf7qHi1/0ax58j1uNQCfqv6/YG0uC+SGHjY
LcFKAvBPn3HvH672Ed6ytQ
-> ssh-rsa K9mW1w
s/y+2ROtxC5AY/1KxqAYuFUJgV4QtrnhOwi+fF+61TKet/8ni1oEjvAiUwg40b9h
eNPGr/ohywXgAj77j8y/J3uWA6uXt1zhpoadZFw63Gdy236AAK6mqU+pf6tEFGYf
ZiD25Z+rhorfYsMS6CkWEVIrM8dgMAGri1pdhXTuoC7LYn9f7GRmcyujbwRUOT9Q
DXmdb6V1j5Q5I6f6TYljGdhp6I8KrAnHMBEcZBECfgTnHE3Hot51p/aoS1KeNcsb
Y9gjpQgNIcccx3CANNJ8y8iZpPzd6Qp5eFk0/IrqqMlGfYrVJ6hX37mV1pqPp4Z+
KTuVZ47PIByw6yabdJdmsg
-> ssh-ed25519 iWiFbA SMZ9gRd/HVCXD7q7W+D5ooyS+k3Nr/hoU2bbwmv/3mI
AZEH5d3rS9B27j52SYNt7wy2IanpmrYJor5OjZAzaVI
--- xWHau8xcErvYJZNB/HkjjfzWWvLrOqdI4ccGSmg/xjo
Ý׍vÄď˝J/XçM<C3A7>Mkě@Î9ämÎ"vĹ «äĆŻî—ÉŤç¨ H÷ń-×<>cŽuĹ…€Z†3nv\°ĘMĽ5đXşQ6
FmNlXwGIN5E/7btwU2TBzyEJq99RNWLE8+P1VSqXI3ZRvbq4sGMW8wpEYSlkYrLk
A9wsYA3x0U7oEt6pnJzuZkyVrc08k/7Jr8Oboscti7wPjbNyMCsPNHJU0CvpuVfh
lRVyy8Ir793jNkqvtWpJS203YyPyV9WwYzH8Q6QlKVs8VLi8KLv4truVbM4MfBQd
BiGYakuK+ckkoS3GBaSm8NNDV1+Ocf3M9RFJnqke7dQIS5tRyY2HCYzqZXbzDtSl
9CRaHnu/H46O3R9Fqq3314Uj94HoUe0SuayXBD7WCzkn9ZevsHZPhk9BHulHaRBT
ExOUcA6hCIDopz+xqErcRQ
-> ssh-ed25519 iWiFbA lsC4GR0vzRjpq20voTzHrzRuoU/aamdM3sIIHYpUQWc
KA5kjHA1lxdKM6Y2yK0rvtlUaB8EI8q5jMZPs/VywCg
--- q/m5+KxRTtf5vgXnAXd8HLGCCE9BfsDs/uJuGSGbw/Y
€@âºv<Y&4•[ýæð![U•<55>oÂ8³Œ`.Mt¤ÝSg¹.S5Tñg²˜»¼cp:g$¥f{eânñAdt¦Þò‰R@lŒ?

View File

@ -1,19 +1,31 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
HWrOsyGtCBR++xduIQUiaVMo8UplDwkbb6WnO6zOLdDD+ZRjje0X+jKbvpSD/k8m
d9p/0AnneewAPmP3xToEk9hRjhGwUcrYURH3ed7/1a+ef7wIGfeNfJfAe5muAUWE
OLNxu9s6OIRUK5f6EtHKto5IEhr/GoGWCCCxDJheXQ5e4DLzhrH3FxfWDXz7PqiH
trXWMploZArJ2f1RGr0wOJIhtHLcv5PxXpHz4ASx1m6pL+q3OdmIV7J+JQaDKVWE
LDa4tQnwcvFodB+g9U8a/KetsCyCdlQnpDqjVAYelMDz+IaMqz8htO/nTL8uS9bg
2AHdB7c1NiPzbI1M4G563jQ7q7n5eQB+nFSTiyXYfvz3tz47GlDvO3DiVtoRnfiY
Yp+K02/emsa6wcBVEPcLlWqACp3+DwL48BVll5XfPadXeR2jsv4JFuDfBSzhr7P8
Xb+PfXbcK3fbXykMrVlfuMfNgnnyFoyTSXqVByolU9lu+FHewgVkyFOhpOse/5eo
azm2Bg7DICsXiSXhlJj1iQmacjxdav771qqs71W68Vu3BgImKrRdgKJ1/DY/yZs+
UhyGN316EcMen+DhV1ZSD7FfO6A/HFB/GwoOgth+HAFCmL8XrDwWeSYHIqHmK9LI
z8rfksUGQPV1p1SL3UGBZZYO86ufXY9h0vdrKTUxGh0
-> ssh-rsa GxPFJQ
EpPN7UHHRuytMr2vXy9CHzjVkH1iCt9LiTLhFsqXbL03Rk+X82q233Lm12f0sQvz
Hqjukkh9bU90TLKcEOFpKrU5FQwKUjzEy85A+4UoovWdJ8VwACOzoJf29Ys1bX3i
Xp4gUT7ne5+4afNwKXVFDS1YCPjIoQPu2cGw6iTNIYwVY5fNxz5y5ZHLkI9lOqJD
mT7jCgLLdkK8vJiDcu4Ofr21GaziQh93YXK69i3gyAt6pqSRyQdAfhMGkykOWdrO
FXMtpzT82UCvfbFbbRCRuSFga0uq5zx2cwvBD4Xagw8Dfg9RQO0rX9NAbbgcoyfG
qnk+0bYAk3pWfdXW9Z/psQ
AaJUbzqcQ1JuhUECy6HAlijuUFCldS7YuLYnm6iv31IFK3W5X4k38CO5lHQGnzvy
GJKEhqETzgNk05MKu5kVWqPC/DwwO99JCmy6v3G88cTi1ekAox7OIwmeqnyT0NQX
Un8eiBECIT3WXfHUZ263n0b96s8YW/MDVlBi+EKjhj701qsjpl2b1aFiPUfETGZd
eyE0pi68mI3Mnp/WX6hR9DODAysJE0nubU/d50A+HtOSCNrrjguDuoEMhNgAPEjP
UzTMQ/+lrKJfIYRf+zvXnFbeUvQZu4Aswo+ghgwnNRYoYiEvbQyK+dhqQunHO6tI
e+A5GMBycd4IRz0AvCeEaA
-> ssh-rsa K9mW1w
NaR245c+88dGflT9cG73bQOBxQsVi5x8JkMTrqjabzwzHpRiBUdtP+Ou1w+klOI4
cv1RLngEZH9jsSiEdvpvRkzE2ILOR/abgABXZi/4vl7iXiC8T23QSOPXnMxrAgpH
RV9B3GcSClb70+Lf3pJtPBVHVENhFVFvj5JgxQ2Zi6eMpcMuL18r/Szn4erk8zXQ
330oEau80X6WoPtRaSqSxVRrMGecGHdIE9chLosCf1x8CgIcYBTtviky+fDQMkKZ
iwueW1luuBj1AuP33jUqjeyyMaJ6SqSmaxGqGHGXA/ayxF8HnHU9AJlhPH+tEEbs
84Xu2vwg9ikUz7B1tTBYeA
-> ssh-ed25519 iWiFbA CuUeGNUBc5K+AkXBRvp7SUTJNoMDW0bWRnYs3ZhFSGM
UwwyxNA2L9q6yYK+BqYcqOq6F5CF+iCUpuceWsEj7ck
--- 3XKIweSg0UFqbadbOP0APwaLyquaEdoanlvndvxcQkk
ßüu _śnTx#H-7<>‰yó—Îç<>¨—B„ô»uµŐÉîj<C3AE>ZHĐ'&÷_đś#ľĽ3ŕHÍ˝0f  šBęą×Ö™ýčÂLĽîz
e/qVub+2c0GRMuVkaGwyQ1I7GodKg0njuLCLhgWcGfqvov2aqbBy5QuTEIwPm/CM
Wp+LcPU+m0wyw/oAtiANeb1TNXRwX/k2oSbbbhN6912Sf/7QRJukgSWaT/l/TDYz
H9RW4EJ3ir2aGS+/rZRchhrbTgMdluH132Pkg9hy0Wybj+PnqUFf2RXk3bC6CfMB
uM1S6LdFPE09ublSk80U6M8Ihu8j2MSIQ+LSfHJJY3aoRZSr1DWz991+0WyC9fOQ
U885VoYh8tmw7rs0aw8gHLZ23Rx/Kf8S/ZQIM9ZVQnQrCEsGCmPXOZLbPM0hawXh
gQUICXoa4AXslSdBn+FG4g
-> ssh-ed25519 iWiFbA 0xrDzh2/OoYkwZck8r6VYNBsITWDuDBe+8AYYxvCiTM
jSlH57h8pxoeyTbUQQUoTTK0KwTvvg2LUggAJ8xUL9s
--- QGRYDjRpaQ369Yej6tuziZ/TJOjjDc7FGX9LRNuHYLU
~”Ubp§ÜƒÖ³Š"0·2çw´“KdŠ†K.÷Ïmк Þ¾4š¥NbÊôºÅŒGßçnb+AD-cDÙùÛ¡Ž?8fbãö“GÚ© <0C> ß‰<C39F>&

Binary file not shown.

View File

@ -1,18 +1,29 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
BZKLDxLAZZ/1TfFlNANKnS0NEzsrS45xVuppc21R8wx9OwzTGZIPJcEigYjbWCE1
XCvkvpw6oTk0RNXx6VdAdZ0dfvfOcU3PfR30/IeiEZyKioyO3gSPp1L2z4Qacz88
MZDsdFMKhivexSRcNl89Xa1LEDf30XYaLKMxhcgZ1b5Z8TEG5trIs2NKek0eHY5k
jBgfvAoKqILVeot8cRANoIhC7aVI6lvVxNVhKzshv/ZAADUN7AZgYyvD09i2qFRX
AP1Y8ld5Csi9pp1KQHn1qzu2ofGjkERUHDipfV7oL3C9s1/sJP2u1oBthqYhPi2R
YUv7k9c8jILWzYw0ryO5bvQJkUWW+SS4WuQAZA127+aq4XECAUiNS4R/aNKwzDK9
8N1k5vkzJLXdcmP8jL3D+03O7igV//CbxzbyLzJXP2dAQI85VW4oxsFiPBHLYqoo
Nq79K6iZll7FUvyPxiFEzll7N6wzM2nPIrDSJeeDxbfZiZzAW0FN7bWl4qS/olp6
sA62SyRPtLd1WugaULIeCa1hopJGUJM4kQpnXPu8uUIOpnHUbc+iGXMWqxTqmyZD
bH7oNIAtTQKXzZiO7M30rt85x1eiADZqWirH26yYufxg6KndUKe+SAsBZUAkoziO
0Lotv232mcwbyWrc3/+sk0rtEP8GYRlCFhP72EQW9dA
-> ssh-rsa GxPFJQ
kYf/CWnC4WoFnELMnW4b3k1df6r1sZn7JeLPqIvQ7haKwA0SUrbMGiyWui9ewn6s
VSZb7T7zCPFAgs546wiq9O3JzeQPtWdTFCA5F/U48ftbZsAL1YjINqm3ySUbg0O0
eh8wZnO4ludFG0bi0/7B6eDmDpfqn/TKLjDJkWiintYg1PMLMR0iDaF8D5oy0zCi
Yiz+sAWyYBVvUSD9PEdCPFu/q8ySj9upBxaObf/Z5pDC94I2Ex7NZm8lGoXyMmnk
vrhVuHc8eRcqqN+ID48JakdPopA/X7IvFIIJVh40yw4Qldzr7H+b7M98Wg0/UEiC
mZldTPzpKznZntXXx6O89Q
EBc6e5bYK8E+adyWM+l4nKIHbun1S2nTh8sLJiZYd9EYdKG/2S/+Pe7vREB5I3Ab
5femntN0JeCTwzjjlbBZKyULAN85sSm0pGibT/RUneOBzmENp1hQSbvGTNK0a/l1
ELRxmlDvziU5DO0WK574lXdTdXTkk8SGCpvNBtwnTov3TqlcO36BoCE5Apw62b1g
7l5/P9hMnIQovAHorh96kqj/unSCTc4Y0ZsNX9IqUqWLLxYNJovUEORFUnPTSvWh
Lbxp7wVXRxccY2bnr2BzmCObzujH7o4K1x/7zxVjxXc4TqGsPT/pzemZ6vzY0LPA
FCCV6Mk41j0O6ez0OyerHw
-> ssh-rsa K9mW1w
M89fPs6WcToz9Jr2YXrRGM26lHU/8Xk72OExtArEsqKpHcRw27EeOQpcXkQ1baro
0MFQTKRsMc2PV0S85BPlUIBrvIiTTHNr/eusKTpAlDwnwllGk26xdaqPO3SYXzMX
/zo65i6837vQZr1aRPg1LFzRMWfrj7tLGQPuuE9F68Q/BYaCBbEo8t1vVVVNibjt
1rGuaMnjJd7scHkJ+wEJURQQuwrIY4oH8obmrzjQrFbBiWPH/lIUH1OUv5SDbYul
/Oq0QEHws/o68EQxOKWrPWRu9P1A3xYu3I19YYZgrKr1G9c0+ZEtZsvfeqCE9w79
OOz3GtRRHRCLBDDzv8nfrA
--- e0EGzCgM5FbTE91OLwUaICK+yruDi8EAIBMGxFJXWLE
ªœ£®AòÂÙî{3·…óÚûí€ñ=Õ89ð9<C3B0>es<65>Gïj
!”Áü;ætr0¼î&Øgd;ü‚¢&Ã¥Í1£^§ 'ø6û<36>Wh^qœ
FHEQuY/JPZLSrSuHj8HTc+jNrxidPpM6qKAkZTl/0vYgWExdJtGi/IukNibjF47q
176i56gjkJZPts8FRgBFXUimBGUBiMCvEOV/Xc/ZK/Foz7JQuTpiNmxhPyVSrGhW
GgyXqLycs2KxWbIz7fPLghGXXEeq86z0yTKiQOx5IkkwZOdvUDmzpHrqnCNi4uG5
LfgzbAcZxhZEKEfOsqq46Gzww96uLmcLypnppUFfelioceMcMnzyXbwXYMDODoL4
c7rXqWqHA9Bu7P8uiPFeiGXuISQGsRUJVbK2GsT7lr6+WfSdTxJcOG/63nKWStbg
VkHYEs6vACX4gHb9BHvpLA
--- nPAuzxbz5u9828pB+pGjc8p63zEYMSyHjHdZZepEs1g
¢(dsÜç´WæâÆó3þo&<26>$÷îùIuÜßBF `PìíØHº¬}d4(H<>@&`kô«'öh«Õzqªâ2Š´[?0Ìt„<74>¾æU½ÊÈ

View File

@ -1,19 +1,31 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
YmBjkjwn3FjgeFaxQ9G5h3ex2ZGe1TStge4BZsHOPizJnaU0aGmN/e2hjgRRWBgc
Js+SrukIFZjrQ/z9qgEQhhktBkpn/y34a9jSeqYA7IUjBEb3puWFqREbkEtC91Wa
DGlJFnGQiFCZ5Z6cIj+CkylQme2UeFD8Mbzrnhslh3w3Y3M6oA0zbBmwsJZ3WtQv
1QUjkPoVEd7t5RDcvm7au+ezUFUm06TsVz77vYkm9P82/fq+u684kwsPTJY0AL6x
RXtAjN8y324nrwij/x1EHl1J9h4hYL8QT8S/9hnVQ5YuANAO3W39wRPedOyESIXt
MXssIp7mMdDzaWBBKsfGkV0SinN9LQ1m9lTEFthmhX76lrLUvlVCKIHMfZWUWf3i
fXf3AREcLCVcEqeWJw4Js8Phet7MsnWReDV/jrTFSISP7BJj5oSLtuLCRwa/imGk
rcZaCG14oo4Tnf4VJDV5UdjJQMo67/rROezv6wDKUW/NkNOKtN+fcErCLjiu2tGV
M9oe/G4sE6gCthy00BpeAJTiK8XDObnGAokBddS/SbhHyh3kZ6Zu49HWMBVW5dOV
RWmvKy++8nDft6oRVITOdxHoyurRUqSzN0p9K7HS6GDP78ThlDT9nigR1HAB1BMD
Ouh1N8tXdP4Ap5osPaOzcN5UWkdnFOPJ8+Fma8gQLZ4
-> ssh-rsa GxPFJQ
oP+PAtaEFPKwY/p94ofdBlLtCJDzaOkE7jblE4COKCp6NcfjUot7a7G2rSzG3Z9A
cF3HcuKsMrG2Tth4ElBB0nwfaXUJZOBO3nrZaU0RGBBkxqooDVV2LzA+NG0HpIZ6
8Rd/Ch621gaBDYbSNFKLx5pAotqsARt13BMVY9nuifNGmWAamZ5UsJwZ/OhxKC5i
bkFZGeHZm4tilpsBEnh99PxofQmFy52AQhpx2UZETaD7yXvyEQjN9yBVKGhwA8Xs
xIRZLVgCbMv5lroYChpj/SiuoNhuaLo+05+3r5JnL/ODEl2dYZHkr2fAo31QUPnr
kmir2Nwoq4MlNELjQvSfdQ
E9g838j5piMvfHhBSdMC5wDSkncDCP1GP2a5hVEL34Krn4+mWE9yRoYGTdcz5AK/
heVfg8h+NteAUYLcBw8B3TSxKKt1BBiQj3gGwX/mrMmOmOZD508JEQAVb6Bmvi5u
3DgxN9gci7iUF6BpaHcHi3U4Sl6bJK2oH6QmRFd/oM3c0f+0vDsTM1f0Yyt+Gab4
/DiGdSmvvTO9tq4sEd5Y1Y96HSBmRoCQU9VWv48/yx2HCiDioZH7vdgOdOkBWDX9
Ba1Qa0pev2PJFiCujCLLvb+6YWzlBlUKc6Awv7tEicExFUXbfiKVGxZmI50xY0Wl
KXRzoyUmAodsdp/HkwaoEA
-> ssh-rsa K9mW1w
GVNgJY5cse7GnU0UpgfBT2a8Ev0KeFC+Tfvj8Jd7Wgu7pYv/DlwIumJN2NcmU76S
zW1Z6we+Fs4DO83v+4Bug4d+m7oUbKxbUfgIDE4MDEkc4B/XUKv0Ex1VaO4lGh6h
0lRF4PO22OjyO4TT4tkLZgTAStq/vS20GhluEdVPp2ovSsn7KYLwmx81iBnfNDbm
0uEKAE2dj01BHSiRZ1rVj9OnTacrRpzp6mbVJxZqkUMJ+A/tMp1B7eTjWiGhUUGs
+de52Ba/ww1jM0BmbdemWS5SA1Kch1ttgnSFKIh24tYyRxX4AVsuYqPkIuH8+W4O
Jh0387AJaR+3+Tvweo88Tw
-> ssh-ed25519 iWiFbA xx3oYrX6/Z1srbxmAztZV5AJgYZn20UMvRnn4qrSoAU
98oe26dqhSE3eET7hwdV/jJTVu2ldBiZ6ysabwK97Co
--- qrw4HhyaHrpDmws4EoABLFF3HU30AaZFCt4qHKo6gUM
OnÄCfIÚìQÿlµç@‡?:5¸<09>Ö m*63ÿgtjÁÃïÖA8 ^;TÓx%;O»·»×ß׶YG¢€,mïÞÜ â¥ ®Éîs8Pƒ òR«\nòXA÷·w;—ÚXRMÛù2´òFÏ
GLZFcv1WXomvnn05f2db9MIAmDQXbD1dCpcNJNFK3Ax/efvgZxHNrppHZXDYwWn3
EkNDZVd9iMb+YZ8Zqa58TtTOhiNH8yTsZeq6jF3bM8Lc2ZoS+v/DqOA/pNALcS3b
LlIkIH4cZ/4cvrVc32+uRFhByLR5vgKuf+F/p41zzFUeA50rCFUR9/gzCByrxSRT
zW6z+PbgNARqbburCp8Jh7yJo74Phki8pizgDrfvWH7hoSYxtf/hbo2DobRntsnn
irlmXjXrXy3P41VoE+4PjbJpDBygAYy6uy0MwkSVXMc+y6i+txeMOw74amvOrF+f
gCaexeMDPmyGm3N2j7qDFg
-> ssh-ed25519 iWiFbA +U3hUeNDk/1M0AGubIlLJeJRiVG6yrLFeSxi5Q7rPBk
BVVyNpQ+BJOhl3/6gy96NXGGGA4nNHoUePDkIVj0xGU
--- 5udXYFRKZut6o3QTDjezohRg3uwaLSBo0IxC88yercs
`"íq·(9~úš‹:€S"ò±ê´1%ÉæNüÅ@â‹=†p„j?|Í_ñùeÈÊâdP)8`ÕEÀã¨FµAàæhÚÚJ<$ðò¢ÃtÌgüáP/z¶mÿHàu7Æja³|Ôsn÷Ð c ªz<àå5·¼>

View File

@ -1,20 +1,32 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
D5yNwwuWnJ0EUY0GvE7/ZMVDOGJaqv212LZhLLoUEd50l6fgXhk9bhycbLCJcchN
Sw9qr+uryVvuWjemKH5YTSx9iTpFegXcB4ekCGopUV5UwMbXFh0mdSHu8ZWm8dXi
7FldNgEe57JTink8macAON+jcZya3sP5QDa3/MITLv0FZHvkUTCDGIZY9u0utkc1
TZlOivvY7vx2CP2y+2Jh3NTOqbncVzDpOnhE1l0Wc+Lcwz8yWWatigwcC2O53lk4
kDdBNGOPppx8AjHbDxPe22hN7XW4axCAgek8IobTfo9ROto+Mwb5DZXM2afTQGjj
rX49hTjksoi0vXXssX/fhp8PPHnHLU8MwURaqJKBwGBFjiIms67rPKc99hFHsJP9
BLF/ajs9yOZDDl1zwspP0koIBYTtrhxXF8mJ3azDFvVcFWBJcNdWd4PldW/71yEE
iA5Q1qDqhixRLkTcihYikekNZ410hmigPnotkxsRdHxKRjnNi1t7kLrWmA21VyCy
93FasIUZOCKpm7KjzJkFhfijTJCxaBu6e1qBfCJdCC0xUT+eTNWSOpF69ymOZ8n3
uDFqEUi2U0nw7BbVMjv4ny8Qi3dMNKASw3PcuHLxxeuHgqxrqkGcvpJZffCEefZt
C9bicJ7OcESTDyFp+t4Nu/+PJyTiOClVCDMi1IXBTy0
-> ssh-rsa GxPFJQ
XtQerUqo59DoCzMSSbYWK1fZR5uPzA20NJcpZ8YOCD2cPJvGiSN4ePnPLSSnyUAV
ei45c6sdRRRZEKcq/uabTWPqk1xymKv4CrLn4FjS9VviKNYW0p+oo0J9ummwE6sa
/REKRIQRrsP1HwSO0gaq6CQEyGr9NouybuDDS5AIGpvaRV9+F1Htc/Um5JmsGaeC
aUBSJdZGnUajg/NN+QBlhhndT1PevFNKaviOJB4ghZUv8V89KZUhZMLuWQHVSr6D
fPQLXCI7mDjv82rydG5NWzE3OiMycLlt3AXWE97G4dhrtQGMPb3KDeGaY2mXBQ5G
Qq+myMZJqx9LbQWPyBgLgQ
JoNUBVV9WIA0Zx/+EjA47T5uRLEC9/wHsRR6aN51Ldd0Q5BzcM+bGCKM3yVLiUlC
ATiMcs3Z1PnpD5pgWlAbWRlvFO/HEPxofhXO6KK61KvhyIfwVfRxDf46WUERL9XM
28+YziZtobuhyYzf4knQumjkp3K7qOC64BqU2rXSwwHVqI/JdgMCf1H5w0bJi0rH
62RGy+D9vEnqwNPvnvwTMkOCvmFVcqCCJdpbOjZ9i3imsREO81aGdGz0daTm9FDU
iWrdpRcAnLFbxOkGn6tb5daTKut6hzpiV55yzN4LK8eo+gbVLUsrmCe8oz8EnSni
Cw0pDV2Y1YuNrbg0xWPiJw
-> ssh-rsa K9mW1w
QjWGmW/CSl1+xidbzQ7rBjPI9gphRAqC9j4dTsQmK48WlnlG9fAX1w7s8zJI287c
VwtOndfP/yYe8zj14IB0bn/efJ4s9DXS1toSVHhHMXGRYNx4LZJtGrHPEe7bmBDR
g3m6i3dFB48o4niZwLFmsTWD8KpYFPRmGnD9AX7cXtA1KzjD61ebb7dsjQ0J7/04
QLUmPUJ4BMgvMhv5zHfjq/LjasrOVY5QkKi95xYVREacy9hp/5COs9d0d40+qLFh
QJ2CuiOba5+aYnVWtbq63F9YJsAwknPOI2nV64l1BflQGJjec+wS4LPi4+l6pT+0
wPStv+iVu5vYdVNuq7KtnQ
-> ssh-ed25519 iWiFbA Qrs30RtQXXEglsSKQbmeLhZvQB9yR0EbKeba8IV1/wo
o89IKeFH91zdqfRJrIge0Sod6k+66BbN3DcUfnqSgqg
--- zhvOvBCbfuhWDejcJcXxtdypACwgPb1KrqpsNYWiKNc
å<}š‡: ¸Ã2bzªüÙÄq¬SYîÌõr掄Ý}¯â<C2AF> u—»ÌòbŸ\;
VuOJ56O13sQx72WUoSSPcjiFx5soxvzhr7RsmLibpoPKq859nXPObhsSqLm89zrp
1kI0AHcOKzuOV8DPI0e67b5NSaORUQMLCcbWhCI5Bgs486BEcwMMtPWDDq5X6z3/
V8mgHoh8iOIH65vxsU7TC9SG7CzYEQWOkuayrfYBi1eoiC8Zo7eiWoyskFa2MjLx
/QM0j4f6iLGIGi60dOgbaseZKLgKX+jYKWQCB8poRyLpCyWrf1o/ldBrJvDpT3s6
J+8tg/y4wJnZ8Pvdnmbeq+L6oz4+w7mC1phsvzQQg6sfSL1ZS80NKexgLnqR07Bq
O2lOHX6pciENCRDVY7YKPw
-> ssh-ed25519 iWiFbA rsOEDax/kHkNdNdNe+dMwJUKoWGcEchbqRTBz4OlUlY
McVrDhF2MuCtbBd7ibOWmJmXRzwDLIthhEv0FLlFi0Y
--- kCiH49m3rceEryHxukITIRQ4cmCUC0kHya+GYoBAeuk
’¡¦™÷>Á¼€Pßb?bñÊ,_
°!1#±Ü=ð¼â䈔® R׳ ]AcHíÛdTú8Ϥ‘

View File

@ -1,20 +1,29 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
Ei3MrdJ+zXDqzalTe/f+V6CsyNiJiETySPZ0R96Q2F5XUt86ucDwHPlstYoY2zQA
O6LF+TIlfBh7JC56Okf7tWx4TnmDphNFMAXJMZIYwGLBNnToumdLqFMgl+Rfxwp7
hPBAphcTTJp3DsxYxuSRVhtJGjEk6T5vtKDwi509M34OB+xkwLIJTXMQaUbfM1ZF
fwJroRCzAGIPKwwFUQJj5Jv/jJkZHYlgPIcRcmbswq1kGFl1dDfWUbM70oskKfE+
94q/tHsY0PTIrElHcdn0K/A/UZXCE9l+J2qgMKtAjAsMXQwwnJd8eOSaKzTTc7oe
kWgTYeyC6vYLTYIPfbUgH9SseQbWLTSKJX7RWCqDmK6KAxwxVqcDArrLTUxIiQLT
0Br9L5ih38A7XeOLrPZwHMNCePHt1+j8g1iaTKRVKdPuexEUIdSRYS36dHSxTeQW
nHe+2Ntm6xY4ue+Orc3IAY0kQuKHkeJRAsSK9sGoyp2ir8mfddSUpiFyR777Isw9
e0jzeX1Cba3NZI+aX6qY4cHNTRaeffLVg9rJLhfzVFIs85hbbklRS+lhkmxPQn4h
KTws7939opgpc30wD0qLRQLjt3wcYY2JtemN9U38CTTbIqKn13RDlfW+Jhg2YhhO
wVHCR6qFdXOZvIJJkUqf2s+YEPs51UO1l351+ycRCq4
-> ssh-rsa GxPFJQ
JQwr1aW+PpoDYZu2ByiZtjNoGe+D90flIc6+gXF+EgpMFwOUIW+g4+1tJ2GYhIPP
BhUDY3GJUmaTXKin0E88CwQnvImtpHRIGl4Kv2QAjK53BBMgBMcOR44c7bCo48k5
lTmv3N5LfLiIm5mIATK1Q72fVhAmg7T/U8IkS3eu2u2mGm5iatFj9cPxHGiN5w24
y/t5Lu6XewjpbilXaIP+Ya6YDpOaQ0zgYO8kRNTvUoPRz/H4SVFCcJeu+6CJcl+/
KxSIS9MvUouGXBsMDPBLNj8G8NgIAncXTwR7swW44b5twM8vJqF4BEr2OZ05CSbJ
XJjm8xbXftRp6AnFMbGheQ
Dbn424RrEBvjFgqtfcU3RP5TAKWn8LlWXC+N+0mbgrWTnt2/COyE2g1TOxgwBINe
sqnzUjWKgSCfRJezVmv8FNPXujwn8piFvUxKY5piFyJTrMgDauUVU/DClQ6eYOjn
rvcOqV7ZXXQ+Iq4X/412BLilFlGwKRB+wNXRAW7GPwRTO4hqNFtxIWVpENeOufeT
IRLWyaW/fON7pNsNIAERnUmaGoFqp+wXPjjUI+t5fMdP01cS6bhDglenYrY7As1s
PszJXwKzHXcvG3FNJEW1oqT4K8Qx+piR4kLfgH1aTx5gx65+yWcomPagW7rfwm4H
Av33BNdLQwNO9aqr5GgCbg
-> ssh-rsa K9mW1w
I5AkWeryU6t6HbtpzFWLwTaWjDNJoVwNJ0ifV9i23QdSn8FO7Op4bk7IqSdI//lF
5DjMeTbxdMR9LOtZXNcAMKX4I3Sy0o8uagh9BdBN1+0ugRVaoGXSvJC7dG7RY2cM
RsV43MTOPSdcR6ANWsNqGlM31H06kWwtPz4R8Wyt4/l+L6gWPjiO6zhg0au6D32H
6d6YqnrE2iM7iTvQeLx5WtPDp+GLAwVsfgGTfOw6jZm5XpuABV9kQwtZ46S4Caoz
rp30b7/ZtPS/IhWj5O+yZZKvhZngr3gYBKUViMA1nJ7+8Rnde5/k2uz38/c6oUWh
MstT1bHNnHt/G9Nvcd9w2w
-> Kn5-grease Rkg" f={5zY_0 ;uV)i~
J/j9JgII2KOWVRO1iN9j1HER+gwnWOg7TWgm/ITeXIF7hsl7K8V+vOgX8fq3WElZ
7c/seypQca/viPS9yu2Z206IMPXnIs4IXWdz0v63QP/YBAKZfngqwA
--- WBm5COr2VejaZiQ12H1fUeUxm1SJraLyu8Q6p7yUaJE
nÌšFÇø,ÆÔoÔíRžfÍ«v¯º<C2AF>”êð3)ßëZ óæ óʵ,†Ê¬*ãBqü7
ZkNpjNG/4AF36tk3Gjz25pDx/4ZkCRR0M/3/vJSY6gKQ3tPMhFn4lkAmLnRfgjD/
FHxLgBFG61fXjn1d3m+il9GYp5xSvLtdGzVUUMcNbD8oEK/tuJZDDNH2kzQ46gpW
K65BGD7e2DesCfWGqKPj6Agv6wTJEodqhIC+8YIbTjTmZ3bDA8CVb/o65tgqCOHH
vjo830aP1jUqfJQxjRQofeSyCZ4PG+TMmJdf43KTWcpROlsVbFW9Kw9nSB6jkmeU
keyaNsguaZZ1opINoEUaB08C5seTuLSeA+wJ7ANNRPN4vHt02Yskj/jH4RLKEO9F
w2Vjh3e9GXuNk7PxCnqBpA
--- L/oD4RIcbz+/TSmAGTRgZco7U0gsld31AjHIZ4BJST8
þÑÎù¦p/«C0ý…f¬ Ÿ5zá¬yë`7&aÄæ*Q(rAƒÉ:â\HJRIML©ÈQ$º

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,17 +1,29 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
csu+QTBNTinSApQjZl8BIvUGJPYbVKOTznFgZ4n6nsnWy4XThpbnpWOPvlxWMuh0
VOOEQVVxyOXlVU8yZ9rc0q1G3BuHi4qq2AvVcsqVLfu33T0GI2u7X+FukW+xKrQs
tQx5CQgk16+JlYouJ4DgNYFFDZzJHW1nmhurkg7K+qnX/dD1oXZx2+s5WnH/sdSZ
kLjzSr6GFcBK6mR9mHfy3MNApJfyXZS3WHiSANU3PEDsJ1ivreo+v3yM8XUvR+14
XnNWP/+AYIQGK8Hdrm5LVkTUZu/SOJVb95aEzA2nKr8Vvg/frZNaczLTjzS47ITi
MyaWJhNYZ0iSTGM+bMTcMx2iSPrABTMPlX0jhXvAlZxIgSSdjVrse5HOZRMKmFMl
L5MHIvDj20s60SL0oMmztn5xjJ+UpgF7FqkKF4z7V+7ed4Y6Eehr5s9GfYoxdfRQ
gvMh1xFM3vdc0boa/a5hfyAFMK4zNFzm5RS/4aIT+fcnsPxSNh5oDtUyVRTMAX9X
jFAsDEPIKsoTn7TV680ZZSX+jyqjQh8Ww5I2lv0NgSflXPpeY9HQMHgq5HWYf0Ai
smu67TEoH9yg6+cIwk7wGBBDoJjmWqPhzNyfsxDKZvWIiv17IbYnamSZ5xZ2t43p
KD/dq/foV0sMyHzYhHLQ36YONpoPmjoVbSVVknsoey0
-> ssh-rsa GxPFJQ
fPHTs93vsxxGTUCLEehvpweFFVp7W0nHfriL4NSEWcHch2I/2LFW3cr66ZvKJzQs
XSTl9XUBX9v4DEg1GJnS8PARhPN3X0qplfHuvgC0kgMS+TxR/xV+72Tu/JrJPtDz
mb0DDRtSupc6wVgJfrJ7b65kfaWhNEWiqtsDmsgyn92bhvDewHLkyH6TtRJ42CdZ
cF3N8qYbHmMKP5JjYTCD5f4tW9qq3On8/yJn2G1bVfX/dWnX8GuqbSgtrWGzFJow
l0Bcvf1+Q4+vuiDBefNIs6f7o3deQKZKS1oHbNsvQCKqcHuOErY1R37FspkttC78
Q6guxYYL9BHXwCH0+O1uCA
Rog/fRONvH1r/gwDGcA1gyCnLHxCwrtISWAJKjlyxNE5AVeMWBYdVYH7QPrFlyDd
DMEw0OqLH59A5xw8jEfZ6b/kxalKfVdF+Nj08lht3a5NxDWHJNrXamrlcDXs7GK1
hJUIeLzOubswSgzKRLz4GBq01u3u06CjinUkI2/oh/6C2SZbsoZOQtTIm++Pvtlw
iNxtH4wYE5F5SHPXX4UAf/504CtYsRhQOodkypYnVqFL7z3kwAAZz9s1kqu4axW0
U4R9IbZrC14j/0ptWqouY2NEPCkMD9WZvQs3GVfuERQmSF0NcLwGd7dd/AibnBST
k3vzdIiR1jhJfbIMNs8Hag
-> ssh-rsa K9mW1w
w8BiFa6mp0kyijfnJNO+hHPQIboF0GUK4zWRJzqzF9+g4d3aE1WrO/CitvDoLmO4
xLqSfP++Nd776lqSaOrOIFrSgsPXp9FI5jL4TFRf+ntpKGBR+a7TADAzhkjbd8Cj
opY1vzEBxWkeFValAemVAHbHQslfE/0jy4L+AlXNpnqlCud1J2S2ur2b1h+V6xha
voJmNoJKm4dbIeUonyNdVAqOfcU+35P+0eFQiQN2nKKH67DdWzUvBdrosv+s46mV
Ow0chEtDTxRYBstegSbiZoOABnCXbFMAjoyodVBe/GMi+XUcfr6UukKUlaC1BWjY
pp0jieCMmitPsiGGC7Vr5Q
--- uUM7rSLmtOOJru/clB8PAZPmOtbQadVWEGaslbGfiug
;®Ú1MÆŽ½&.ú•ð_e”Í×Fjé«ÓSÒ!y=[<5B>—“˸—ä̘<C38C>#þŽ<W:É…VtC¸üœVQýõ ø
uXtw3K6rnytVD7STdJaf5C6i3CwN7PjDdKsRPrW7hdENzpBnE6TtCZglwRWiZDYk
gO/HEDMf8unlBQv+49eMRI7bUkNlKYYnArdLJSNQX0yTSDM8zI2gxYOkWx1bbbs1
J+kU+IvyV5O7mVPm9CYe3kN4L2CNmx0JZqqhuB4q/KcxP9xXDVF69Oe7Bf/UIZDB
jzP9Be6koD54f1Y85/QZ/mbVyPIJ81G3iAiq7HofOhWv3JGT0gFYsphOrSCIH2oL
yCSyJ+sBb+G8ZXZWee7nLZWPcXIYvaqloV7PjCtwY5Oko56yuUvsccsDPSdIOKIT
jJfVOdAeY3MJLLK4TsBpPQ
--- 7MrKNOTQZIB2xnxzWuneRu6qy7E7pmDdW4Q4uwtBv+o
7|çûÒR-ŽÜA­½@Ñõ1 Ä8"M~Ëå°÷c]ºÔZ;q¤ÖÌר$¡ñx3ž)})´{·¤±³$V\äŒ

View File

@ -1,17 +1,29 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
f2vJWnYHKWDW3wR+21IZs+aGvy+//AGPXseyolrpFLnL0MPGqrrg23V0JtRUoiYD
0ik/xt1+kjrUGNuYUVQGfg6ud1ORbnDoBMk8UsBcorN7ujUHa+f4Eccs//57/gXa
fzVLCfHVYnX8lkdloFOhoIgMkX/Or+bv8flNR16C58WcLqjpXGDXTuP6aXMIL+fl
N8COzfNPkYAtyBqHdIP5ZJVOxmXL9MBDTVde3/LIE3vRdDPVJrb93yTTn0drk/0k
rH431b058Cze7Niq3p/RwVfjOmSLOfZPmyyFeDiTOBYV//4Bcepy1aozyjFvBTJ5
iMgxj8o6VdUDQoKW3MvPTdq8wnQ6pGmTbFcGd7EGXD5xIhtAs1noUOiLEzDGzc6Z
uguddRPp6J3oEUj79Lm0i7F31+9KeyKIv275QuNz5pby9qxUwhg2LgsWiK0og7NJ
u3+wJR3agk5prH2FhJ4b6Z0iC7uVttYLg8O+PVssVr/J5OPwvcPxfa6DOjQ8IW3Q
5u6k/6AeWAdT+zPYS3GraRBBnihRiRjy25d/tb7gVWtrF0zzz3zgCt5MH4Gb0rFR
QLP9UVSV5k3K7/SRiRx/JmXC+TBHk/jZgF0OyZ1u5Ofa59i8GNvUhsjmFxR+aA2n
g1U3lXXEN4RAAFu3r1qyGTPfJy53pqwo7Z9Tb1x3VUA
-> ssh-rsa GxPFJQ
QjiqDCicp5t7rtZD5lzZmXz1MTSFKjK+do/TBY1csv2afBT9xiyGHUTO/FfB9Gkl
ndZJrvTo8ciR17+i4sKoIP80uF+t/o+Cjhxd92PwrGdGXl2rz9nAsl6mn+2kvjIP
YVCwOAVisMs4NJ2e0LdDKBL/EyYIsG7ZGg4K6MQCpbeTctzkxyhxyvugeJ2P/TU9
8qE9LtoB5gWVMcEhBtDgHP8X0KoN14dBKxgFmRXIgMqRHLmhENb5f4LKnb+lMnBb
/9Zfh3z1PCLVxctQVW+MjRpdjQCNgzfEaad2Gq67ryDq+FvCNAnLNxXzfZ59xN3a
4tZVuMUAD0gpccmqsPHgXw
SfYIqzqLoHWpHEVXbIFsMK6erDAjFC0UDW4y5OcPmBMryMM9lnrDzacIWP6NWbQP
WCQT4HdI2bdTW7Yxhin1Mi8LfyGKd3xRziPv3p4a/jqvciKooTK5ftZKhbpFPfRI
oZTGPEwAiMo2yX+gETAW3zVht7fnrYhB3EVfpWi1bH5gtNWCOrjQDlWYWk9s12hi
dw6qxjjoP6CM7bi1niiDukyUJm7JfFm/Tui6RvzJOVD194J/UQuQlEoAK7f3UfPV
M7raJRWQpX1EuAPNyqBZgIIgtbYQLEUjhimquhB9nG3mR3T5I+HU0JYLhmNqTdpf
yv3Lw0ebxPowHpz1lCwpsA
-> ssh-rsa K9mW1w
C6yhBEpcxuMCk2aI2H73EDlUIPYitTzaFcbPOArqOHWVUn70K1yh21NxKEyZOT83
2lFAN5T7JKER6h6FACQRPl11DVygVz9L7MgAO+dw1ffMSh7wMBcNedPJPU8X3+pE
EqDghfw6rIqxpSBdcxeqXK8v7NcUrF2Jk+hUwYSJrByHcez9XYuKPGxVkMfu6rFe
5hkH69pzk2OtwWWV9lDIDx7eILkY3h1tligVlv5A4cJeAYdGdjT79JZl8Su77c8t
oBB4GqUq17gBvaGepEHWxdkqBfCfw76ks4+90wkdSnyxS4JkNalh2sK5sT8YI9B/
TOvgGNaDAI7dzzVTF/3dnw
--- JGhB0ykpL8iUoZPHOKCjuWC2cpV3Mmp2UGfZHerkFiU
<EFBFBD>i襔异漨穣聜X,肑Z訪鸅奍K'昼>繷w^e<>鉈萍<E98988>煬蘉5*鶤畓^D⿻
XV1e4vIzCtrnYfE4oJ3emkg9gV2lgxsO/9PB/PlXZvmLeQluvK+h0f6c9KqE9qu0
qjC1MNwGhEBen/kQQjNtwwbdiLAjgW3MoIBk9Ws53eXRpXO0I4Ciysbavo+WQO5N
pgOv+p7bOGGRQ5uVlU36R4KtdlT5y9C7hAQYUg9JGj2eGp7z/JaL0SuWPeTV2kOp
1iZJvmZS3D9jMlcDJK9Ap5Uv3PoW6A29xwCTJoQjQuccLsC/JtEw5HvGpEBZ5B8f
AMb3lxAHRwbelaW2JfihBIYFfno4cM/ixd6wvBkbZD/QyyzubIq6vhliOqFlCA1y
hhGg/DSK+YV8Nv8N4RI5Lw
--- 9RoiUv2UWxo58YkfgEBcTXK37APOds+FpiE+UjXlJNQ
Ý3c:¡¨™Y†zrm-¼Ø|Cu>ûØÔkI¶ ±;bóîäÜoYb¹‰rùI¦¾ÌÜJ=%ÆæëiêMXéüú?

View File

@ -1,17 +1,29 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
cPKkYAGp5UZxDUzXYpPTHmtPE5+TG0GLJnnKcewiyPNZuWMkRJdPFqkqGesy3JWy
0YOzFNwme18lh69P/hETLG0GZq0OHLaKTOdl6RV+0EgNAHf2yrym7z/y/PN6rF4u
t5mUz31MK0a49HCjzxoA2+Ntv4nceMQMmzE3A4tvTvwiD+9C5rkMbJM0HzrUFkME
tcywwx2aFYW821NCWd7ICdHjIXf8HZIQg6BVyTSz08e+pYX+9qD97hvRQRm3q5B4
cYUbtDiLjxywNyHoiOVT7gRUNgtL/aU/4Hdoqn6QBubKuNJuzK+nDnCmBdVU/tT6
z5q+U4quBGXh44YtnDUQh+RJ82ywuxTUK1TpC7LaNuCAu5509ZP+Ami6yvw4v/R+
1ZMdQc5UJczED/zEgD9xewvA/lnIy+f69IP4LdsAYangD4mrFoa76PZh48p2z73h
bEdmNVJoflBeWNQcpCCad6fKuUlpUNjPe+C6U1odRIZw+hjIB5XMuceYWf3siNR2
bSnsCLYBOOmXWKDNLYxqIwBS2eXe/U/kTBEC0AyX9chjRfFItkcPgOe0EU5CThoo
9d9O/SWaQ+g2xYIxff6HUUyxWK/ccVUrl1H7HD8I1r7e7JxR4g3KV/5CYj6/K+WL
y+/6KE3zBV3F+f7pA0Tzw9DheyTBdPzuBJ1rVw8COKo
-> ssh-rsa GxPFJQ
aNab2qfNwio6adBh7zRgdmXT8x14W4w+V3npnAdq3Rj980vCZ2P/gmznsfSZIiEw
W+GiX8rOY8cVzxc+wD9vMmwc9WSa0VvEIEv1lO6a3EIRAvtyZWu3UAxA/Sqpkyf8
HXDTC8ir+z4G71BD7X37J7wjUkSfi2sB0KuTjxFyVyD/Z36nkrESp8j8RFP827U3
qYbZxIIakH7IllHhqoJ41mQX5fXRwVk+MS01OVEZhu3NanKVDroVm4NanHIso234
dFJ9DtjV/zs1jY51z03BV/vGwCvHkC/X2S4lGiA/X1YxVFu0JX2WA9KilMq5VPji
IUvl/MCVtK70wZE8OToR0w
Tgf2/k+LAGHoeiCIN2R27ZEGli8s1jSq4w3g/BBE4pTot0lndypOcs4pPbH15ooi
UZSSL1BtIlsOGUkZCp2o4+WQSFq6h/ZrnkXTyCY9YMitkuJJhYSR5IzFSFaVPyuW
4fSFrEDjxAGiZ7UKYn4f7KWLKfwRakszW4vv9x2iDJT4oCdN4bFhPVf8bePHQ9sz
+NeEyNzA2NKR04e2fU4/3GyLq+GqOS/sNB0vYni61Gk2p89vLeVqxyLj/n0pWU0E
uMEYgjp9rhjj5qi4Hogwggav5Avz7/6ctmcDrilENmkpXc5BUwFADb+KakZvUy9s
xx7RDyDy2AFZaQ8vcqdujQ
-> ssh-rsa K9mW1w
t0o+YIfpHwIAtEQ2w3SVI9QMkx0VrexK6lIu+3VbP1hq1ZgBmmbnqX+fUFyMiYw3
X0TrG9sqjT44kdL3t6kkN96w78QRmlWB1LwkHU4XlYCW88MGiBIXhYLleSruJxcE
Fk4Ue4qYvLP2JCCipKT001IwxVrCoSi4/ciTbuylbEsHPlnEiiLeov/9rS3jUiER
UFgc7/T++d14tWel5HtLNaCczDKATSCNfJCOI5NLcsD8pbTvn8RuOrYDuiaBXENN
izKLy8j2DAes27jqPN34aq/pJsrYMlvJTrfhOzqpmCCSoZJ6unwTLHsnb3iJJ8/j
MLE5M6lPaYBm209RM558eA
--- Zwy50B+dasjZL8tkbT9ANog0izwkc1b8QZQzrQrgQcQ
qâ{èƒU_I1ÎÔC=^T(<Ôk¤n5TKŽ JŒV7Â"̈Q€E “ög§î‘á{U"Y°æª-·Køù‡
F6OFGy6oW90Jpr6Yp/pMxCa+VjSP49Ese3aQ13ktdrO+GnzzOF+RQKQ/fZNI2VSx
7jT7Z30ghIHQim6bTPEuDeL1949QBL9jCuMKTgxNIyH1NVnDIygfxgFu6tU35Q5N
T8GFF+CiO02ldvbKawMU0lPtygrgIOSgR7vsVaQnb7g52GVEX2Q5pfO8PPTP0bpQ
9RYO1Ct2qx6vS0jHB7KSF1dmZ3v+hDw7h+cd/hscCfPh/04OllMj3BuzKJnI4Fa6
BD3pfbn+LPTN5I/p/yKnnyrADtZZsMuLSKoFBsT1vl4bN7ZkB+UP4FZRx2bdIyj9
aMCI+ZW94ztEIZgCgoLx5w
--- LqABcibMWReWTIPnTGkZ3Ede2OZwD46J4Xx7gfYV9hk
l,ɳ·c8‰C7X<37>ꦡ-±Ã‚×ƹáÿÏ8ƒ(ªmuEhýãD!Sõ‡|!<Uó´ÄØ~ 0<>Tñ—Øz¼hÇ

View File

@ -1,24 +1,35 @@
age-encryption.org/v1
-> ssh-rsa JSzstA
JTJPzisDxIEZXztQKthbMnmwaMHHu7IL0oFyY7wFypkHp9U7NnKqay7a5xjdr9ZZ
L5S3FPq9UhniKTkT3UvnOEE7xmgxWGwsHIT6Psk1h8l9M/Gt43sqi9QWducx5uw8
UdWDU+zEiqRLZUnn78s1lY/IjD1xoEtuA30B355Bj7/EsXUf/iWoqoHqST1TBCgg
O0FCLsW3CwUoZy57SN7NKcgABviJAbT3xz+nGH14FgYoG2Z4F2QeghukGUEps/6X
jUMU/4bjID9uBC3x8nLEtTk4E4Sx3mrez+ZFft5msRr8+cPXP05avW40R86qob4Z
ga/XMco0eYvWGBn5c1Bplu2V1TfTkeArcnU0ATUr20QFYTn895ZqqQa4y6o+1wBl
k+qXjEuD+iKC6IJEO409kk+0CDn6HdE4jK0PT8UZdiLrZzgI+hvgfcZW4IQ+y6Fg
FpxS3VAizepCK+cYytK2IRMmuMRT8QYJczK7Sqn7RWOfLNW7Xr/kBDHYjESuo3dk
ZKY4Ae7eL9SGdWJLmT7oh1J0fv0ye+KonuIfUHNAmAx8y1J8bLlf192kgIr9ZQgY
nCBtPwXU+Zu5ZMyvjTMl0PeW9Di7egI9JT0wayECgZeHqFJxtoXcAX+x/dHuTc5p
YLtcIjvXSuvAauOw/KL4eVciQ/yx0ECUnWj4M9xiTHA
-> ssh-rsa GxPFJQ
kN8HcZyfehcuahd3R8BkBMzst0UJUQ4V7m/V0S74T8GxcTE7o6PXZCTeCLpS/rBx
NJmiIdFFiANtl+KGakn7UE/+1uaWEuHh/53E1MFcWU4t8T7PwOE0dnS70pbee1fb
UzD5/OzgZBlNCcBeSG+z+a8yble20SaxPdjT17Q5UEREnsXrEEwfJNHmo2rr1xli
GsuR2TT+z1fzLF2sxFzKmqkWWBtn4g4m+qGBu07uka8qcKezV/H2NWsYYZHniIYj
an7pqMvEn7Xa3HqhyNz3fpqnPYxeL5XA+u0Mqjlh74bDBW3e+GuNT83FiS7LaDHS
DkIlZVaoW0Seu/3PMy4ROw
HC5+zkX1LsbAQgTPjFOZqVazYNQi5hF+mxG7995Sl+O6nkqeovSoc6uY7VlvWcJy
86NcbYb+oNW7hwPL+L1AtkKPuEptSlvTf8JcCqrFsGpIib0le/nrtGwR0w82vrLG
1+BAvYgJ8y1Uq39+K/nR4m2dELmgZ/vqsx5dQEeZ2YxjKLfzhRtA9bq749SGE2Gw
CsF+3rww9Ozc1cDvqoeXRJgToM2Ie93gcUK+UkemegyJdNENbb8oIM395iVhmJ5P
D6RdonIEB8Ti3NZnaK+jlzfC/jbjPTzvd3S2auzfqA4fz+9UFanVSqr3zfUpukUl
4PfPVW8CkPojZYen6DBq6g
-> ssh-rsa K9mW1w
Y/U0GvBafrPJfN182I1NTYxhRLzO+2VVIVVOUJcU1iO/L8bOgwUV4REO3RjtVqJ7
6YTpjFf50HneGqwsA3tjTorsw3A5osBqQQf1IjMC2n8y/eNDc1+JzIv1o/lTGoxS
A+cDhkE6pcHoJc2BM+nAi7sUlwoeJ5KvZsPuWAaSZCguQeiwEPYroQCxKF+9oARR
HTta1JNZDFnqilfIpSkYjJYvKaxTkOKZx/44C2M8ZZ6F/HeASnBmBtRU9jtjewPv
krwJBH4mhPwt0gvR/rZmCj2QUvDHqnhxcULCu/q8S1MeLORjC/ee4cDtNqu5WACe
7mKir260GEs1J2oXRfjUuA
-> ssh-ed25519 rjda/A 723GschjqdjOJYPGOXaIlXA+O7k46VTyhY4y51PAV2I
P87ZXqIMbR00uPlz64+q6l7FUkcQ/iTOtohIGv/ouqU
-> ssh-ed25519 nWv9MA E64XYXUlVS9o0W7CAR78SSBji1fiXuEnrzDNvGIwZHg
iLJ0c6+v6JJUUedWc1N/g60NUF9EQsZpfu04ovP33qo
-> 6RLH{7j-grease
aMK2R8O/Hy6BDukGcw
--- iqZ3+1u9RlUdJ0hsTXl73r7k+Ri3vWKP4LNWCTJeIpE
¥¤$$^³ÜIq¾Ù>ÐNÿeñ$üÞ›ŠkÀ/Khn:<3A>^q4ú×Õd[=*H¦0þ¯
<÷j
L8YgmVtDJ+BNE0TUWV89ybOZECH48YTfTfDSBkPovXMnoOqK8oZbdMmt0Ya0Qjdz
cLKFaL7jIEzXYKX+kso/ofD/Ssk8tri5phzqYOYe6H+jcIOTeRgHTylBKTbIlK0F
z53FchUCJ52c9efWdizJKMLxsVEOWaQjfr3jh6mkQiSkUft9iqKT/fB+iTFW51Sj
f2bTJNbzZkTEqaOZNb2ZokJSsbel+siw9tfymRzE1CSbn3cZZ2CzmXgJy2Q7J1Xk
OZD3vxQkbIdWjUo+lZOXRytUQNt+sTf6E43Ac2320oO1rp0QN0E3+jtHYpKwqxKv
4banw4lnrXXRYohjNtT/ow
-> ssh-ed25519 RR/L5A 3ReqPQQZlaWw1XqyTbY+YyuMtetAu1ZQ1Yc9MDYQOwo
2w3Jnd8oNs3qFUeERzMFzz8tTsePqefEcZPbMjk4Fzs
-> ssh-ed25519 rjda/A yC7ADLngvLOavI1ppz5IOurjDCnW+WEAv0CPDhL3qHw
22QVJXc9EgAj2YhNU8BMutjUkAcv907Rgxlykha75H8
-> ssh-ed25519 iWiFbA fO96YbnzpIfaD9QSkAcORCcjNpChYVWWwTItuZ0MXzE
Es5p6sqk3tAC821ali6/8iWxT84ZDG3xnmaXhsPjHuU
--- 4gMOUdNCZAtkJmQmBy+BMCb313XHm07YJyq5VmIdaAA
©æ:êµϹBŸwºX„P¯:ô"Ö»<>ÉpœÄ€÷Dºçä=7>—XÊB#H<> ûhÙ½ç5‰¯c ¸>V

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More