Compare commits

..

151 commits

Author SHA1 Message Date
teutat3s 0475cfdd6a
Merge pull request 'tests/keycloak: try to reduce flakyness' (#284) from fix-keycloak-test into main
Reviewed-on: pub-solar/infra#284
Reviewed-by: Akshay Mankar <axeman@noreply.git.pub.solar>
2024-12-18 19:28:38 +00:00
teutat3s 23b81b310a
tests: try to reduce flakyness
All checks were successful
Flake checks / Check (pull_request) Successful in 41m3s
2024-12-18 11:47:12 -03:00
teutat3s 475af2f82f
Merge pull request 'maintenance: update forgejo, matrix-synapse, nextcloud and linux kernel' (#283) from maintenance-updates into main
Reviewed-on: pub-solar/infra#283
2024-12-17 20:48:23 +00:00
teutat3s 197ba721fe
flake.lock: Update
Some checks failed
Flake checks / Check (pull_request) Has been cancelled
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/785c1e02c7e465375df971949b8dcbde9ec362e5' (2024-12-02)
  → 'github:nix-community/disko/a08bfe06b39e94eec98dd089a2c1b18af01fef19' (2024-12-16)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/7109b680d161993918b0a126f38bc39763e5a709' (2024-12-09)
  → 'github:nixos/nixpkgs/bcba2fbf6963bf6bed3a749f9f4cf5bff4adb96d' (2024-12-14)
• Updated input 'unstable':
    'github:nixos/nixpkgs/a73246e2eef4c6ed172979932bc80e1404ba2d56' (2024-12-09)
  → 'github:nixos/nixpkgs/3566ab7246670a43abd2ffa913cc62dad9cdf7d5' (2024-12-13)
2024-12-16 19:01:08 +01:00
b12f 642b35fb06
Merge pull request 'logins: add chocolatebar for b12f' (#282) from b12f/wg-chocolatebar into main
Reviewed-on: pub-solar/infra#282
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
2024-12-12 16:42:31 +00:00
b12f d5bbe3d0f5
logins: add chocolatebar for b12f
All checks were successful
Flake checks / Check (pull_request) Successful in 31m51s
2024-12-12 16:41:50 +00:00
teutat3s 161ec7a7d1
Merge pull request 'update element-web' (#281) from update-element into main
Reviewed-on: pub-solar/infra#281
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
2024-12-10 11:13:20 +00:00
teutat3s 4e1678b1d1
Merge pull request 'bash: ignore leading space + duplicates in history' (#280) from bash-ignore-space into main
Reviewed-on: pub-solar/infra#280
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
2024-12-10 11:07:55 +00:00
teutat3s 6acc3f7927
flake.lock: Update
All checks were successful
Flake checks / Check (pull_request) Successful in 31m43s
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/190c31a89e5eec80dd6604d7f9e5af3802a58a13' (2024-12-05)
  → 'github:nixos/nixpkgs/7109b680d161993918b0a126f38bc39763e5a709' (2024-12-09)
• Updated input 'unstable':
    'github:nixos/nixpkgs/22c3f2cf41a0e70184334a958e6b124fb0ce3e01' (2024-12-07)
  → 'github:nixos/nixpkgs/a73246e2eef4c6ed172979932bc80e1404ba2d56' (2024-12-09)
2024-12-10 11:33:17 +01:00
teutat3s 386f2b2ba5
bash: ignore leading space + duplicates in history
All checks were successful
Flake checks / Check (pull_request) Successful in 28m23s
2024-12-09 18:49:58 +01:00
teutat3s 6645e10afa
Merge pull request 'security update for synapse, updates for element-web, mastodon' (#279) from security-updates into main
Reviewed-on: pub-solar/infra#279
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
2024-12-08 20:08:08 +00:00
teutat3s eef268b21b
style: fix formatting
All checks were successful
Flake checks / Check (pull_request) Successful in 41m25s
2024-12-08 18:59:27 +01:00
teutat3s 5192f382bc
flake.lock: Update
Some checks failed
Flake checks / Check (pull_request) Failing after 27s
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/639d1520df9417ca2761536c3072688569e83c80' (2024-11-18)
  → 'github:nix-community/disko/785c1e02c7e465375df971949b8dcbde9ec362e5' (2024-12-02)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/506278e768c2a08bec68eb62932193e341f55c90' (2024-11-01)
  → 'github:hercules-ci/flake-parts/205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9' (2024-12-04)
• Updated input 'flake-parts/nixpkgs-lib':
    'cc2f280002.tar.gz?narHash=sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s%3D' (2024-11-01)
  → '5487e69da4.tar.gz?narHash=sha256-1qRH7uAUsyQI7R1Uwl4T%2BXvdNv778H0Nb5njNrqvylY%3D' (2024-12-01)
• Updated input 'maunium-stickerpicker':
    'github:maunium/stickerpicker/333567f481e60443360aa7199d481e1a45b3a523?dir=web' (2024-06-19)
  → 'github:maunium/stickerpicker/89d3aece041c85ebe5a1ad4e620388af5227cbb0?dir=web' (2024-12-02)
• Updated input 'nix-darwin':
    'github:lnl7/nix-darwin/61cee20168a3ebb71a9efd70a55adebaadfbe4d4' (2024-11-19)
  → 'github:lnl7/nix-darwin/a35b08d09efda83625bef267eb24347b446c80b8' (2024-12-07)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/e8c38b73aeb218e27163376a2d617e61a2ad9b59' (2024-11-16)
  → 'github:nixos/nixpkgs/190c31a89e5eec80dd6604d7f9e5af3802a58a13' (2024-12-05)
• Updated input 'unstable':
    'github:nixos/nixpkgs/5e4fbfb6b3de1aa2872b76d49fafc942626e2add' (2024-11-15)
  → 'github:nixos/nixpkgs/22c3f2cf41a0e70184334a958e6b124fb0ce3e01' (2024-12-07)
2024-12-08 18:29:10 +01:00
teutat3s 3e32bfe106
Merge pull request 'auth: add user for each administrator' (#261) from per-admin-user into main
Reviewed-on: pub-solar/infra#261
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
Reviewed-by: Akshay Mankar <axeman@noreply.git.pub.solar>
2024-11-28 16:16:35 +00:00
teutat3s aee317b463
flake: format
Some checks failed
Flake checks / Check (pull_request) Failing after 46m45s
2024-11-26 17:58:30 +01:00
teutat3s 98b546f587
docs: update for per admin user SSH access 2024-11-26 17:58:26 +01:00
teutat3s 42b3052091
deploy: remove hard-coded SSH user barkeeper 2024-11-26 17:56:15 +01:00
teutat3s 6a0b9e7e88
Merge pull request 'matrix: Enable MSC4108 to allow signing in with QR Code' (#274) from matrix-rendezvous-server-attempt-2 into main
Reviewed-on: pub-solar/infra#274
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
2024-11-21 09:44:58 +00:00
teutat3s 90c8072f92
matrix: remove long-gone dimension from well-known
All checks were successful
Flake checks / Check (pull_request) Successful in 24m49s
2024-11-21 09:15:10 +01:00
Akshay Mankar 5076266842
matrix: Enable MSC4108 to allow Signing in with QR Code
Enable MSC3266 room summary API to enable room previews

Co-authored-by: teutat3s <teutates@mailbox.org>
2024-11-21 09:14:17 +01:00
b12f eb63779bb6
auth: use all sshPubKeys for disk unlock, fix tests, fix hm config
All checks were successful
Flake checks / Check (pull_request) Successful in 28m11s
2024-11-20 16:49:39 +01:00
b12f acc537decd
hosts: use correct wireguardDevices option 2024-11-20 16:49:39 +01:00
b12f 2b72d9a5a8
style: run nix fmt 2024-11-20 16:49:39 +01:00
b12f 5366d07d44
auth: add user for each administrator
After this has been tested successfully, root SSH login can be disabled.

The advantages of having a user for each adminstrator:

* Better security analysis: who issued executed what command, who
  touched which file, who used sudo at which time.
* Possibility of granular access, e.g. person X is only allowed to
  manage service Y
2024-11-20 16:49:38 +01:00
teutat3s 10f71b1959
Merge pull request 'maintenance: update element-web, forgejo, nextcloud, matrix-synapse and others' (#269) from flake-updates into main
Reviewed-on: pub-solar/infra#269
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-19 16:10:57 +00:00
teutat3s 8b8833e9c9
flake.lock: Update
Some checks failed
Flake checks / Check (pull_request) Has been cancelled
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/486250f404f4a4f4f33f8f669d83ca5f6e6b7dfc' (2024-11-10)
  → 'github:nix-community/disko/639d1520df9417ca2761536c3072688569e83c80' (2024-11-18)
• Updated input 'nix-darwin':
    'github:lnl7/nix-darwin/5c74ab862c8070cbf6400128a1b56abb213656da' (2024-11-09)
  → 'github:lnl7/nix-darwin/61cee20168a3ebb71a9efd70a55adebaadfbe4d4' (2024-11-19)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/9256f7c71a195ebe7a218043d9f93390d49e6884' (2024-11-10)
  → 'github:nixos/nixpkgs/e8c38b73aeb218e27163376a2d617e61a2ad9b59' (2024-11-16)
• Updated input 'unstable':
    'github:nixos/nixpkgs/76612b17c0ce71689921ca12d9ffdc9c23ce40b2' (2024-11-09)
  → 'github:nixos/nixpkgs/5e4fbfb6b3de1aa2872b76d49fafc942626e2add' (2024-11-15)
2024-11-19 16:30:13 +01:00
teutat3s 280dc37aa0
Merge pull request 'matrix-authentication-service: disable changing mail address' (#271) from matrix-mas-disable-email-change into main
Reviewed-on: pub-solar/infra#271
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-19 15:29:15 +00:00
teutat3s 3d8fe3cef2
Merge pull request 'prometheus: disable daily e2e notification again' (#270) from alert-disable-e2e into main
Reviewed-on: pub-solar/infra#270
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-19 15:29:04 +00:00
teutat3s 213c06ca87
matrix-authentication-service: disable changing mail
All checks were successful
Flake checks / Check (pull_request) Successful in 22m45s
address. This should be done via auth.pub.solar
2024-11-19 13:57:23 +01:00
teutat3s a491680165
prometheus: disable daily e2e notification again
All checks were successful
Flake checks / Check (pull_request) Successful in 27m35s
2024-11-19 13:56:42 +01:00
b12f 1ae1f68ce2
Merge pull request 'modules/forgejo: allow migrations from local networks' (#262) from forgejo/allow-local-migrations into main
Reviewed-on: pub-solar/infra#262
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
2024-11-14 11:10:44 +00:00
b12f 87f9bc92df
modules/forgejo: allow migrations from local networks 2024-11-14 11:10:44 +00:00
teutat3s 3b29b847b0
Merge pull request 'coturn: fix secret path' (#265) from fix-coturn-secret into main
Reviewed-on: pub-solar/infra#265
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-13 20:39:47 +00:00
teutat3s 4923f033f5
coturn: fix secret path
Some checks are pending
Flake checks / Check (pull_request) Waiting to run
this is fallout that was overlooked in #250
2024-11-13 21:25:12 +01:00
teutat3s 2424a3ec8b
Merge pull request 'keycloak: fix registration with pub.solar theme' (#264) from fix-keycloak-theme-for-registration into main
Reviewed-on: pub-solar/infra#264
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-13 19:48:15 +00:00
teutat3s b41edf0cfb
Merge pull request 'core: add activationScript to show closure diff' (#260) from closure-diffs into main
Reviewed-on: pub-solar/infra#260
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-13 19:47:17 +00:00
teutat3s 0d6da8d678
Merge pull request 'maintenance: updates for element-web, forgejo, matrix-synapse and others' (#259) from flake-updates into main
Reviewed-on: pub-solar/infra#259
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-13 19:47:05 +00:00
teutat3s b87670d07d
keycloak: fix registration with pub.solar theme
Some checks failed
Flake checks / Check (pull_request) Failing after 56m37s
This pulls in changes from
* pub-solar/keycloak-theme#3
* pub-solar/keycloak-theme#4
2024-11-13 20:34:38 +01:00
teutat3s 73333537a5
Merge pull request 'alertmanager: alert on high load only after 20m' (#255) from alerts-tweak-load into main
Reviewed-on: pub-solar/infra#255
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-12 14:47:53 +00:00
teutat3s 45d3b939bf
Merge pull request 'matrix-appservice-irc: reduce logging level to warn' (#256) from irc-reduce-logging into main
Reviewed-on: pub-solar/infra#256
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-12 14:47:44 +00:00
teutat3s 904c7ed1e4
Merge pull request 'secrets: remove leftover secret files' (#257) from secrets-cleanup into main
Reviewed-on: pub-solar/infra#257
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-12 14:47:35 +00:00
teutat3s ab85ba751a
alertmanager: enable e2e_dead_man_switch
All checks were successful
Flake checks / Check (pull_request) Successful in 23m13s
2024-11-12 13:41:42 +01:00
teutat3s a9c5edfeb3
alertmanager: don't alert on high memory page faults
This alert is non actionable, we still monitor high memory usage.
2024-11-12 13:40:46 +01:00
teutat3s 7067d93ee2
flake.lock: Update
All checks were successful
Flake checks / Check (pull_request) Successful in 40m40s
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/09a776702b004fdf9c41a024e1299d575ee18a7d' (2024-10-23)
  → 'github:nix-community/disko/486250f404f4a4f4f33f8f669d83ca5f6e6b7dfc' (2024-11-10)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/3d04084d54bedc3d6b8b736c70ef449225c361b1' (2024-10-01)
  → 'github:hercules-ci/flake-parts/506278e768c2a08bec68eb62932193e341f55c90' (2024-11-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'fb192fec7c.tar.gz?narHash=sha256-0xHYkMkeLVQAMa7gvkddbPqpxph%2BhDzdu1XdGPJR%2BOs%3D' (2024-10-01)
  → 'cc2f280002.tar.gz?narHash=sha256-lXvH/vOfb4aGYyvFmZK/HlsNsr/0CVWlwYvo2rxJk3s%3D' (2024-11-01)
• Updated input 'nix-darwin':
    'github:lnl7/nix-darwin/04193f188e4144d7047f83ad1de81d6034d175cd' (2024-10-24)
  → 'github:lnl7/nix-darwin/5c74ab862c8070cbf6400128a1b56abb213656da' (2024-11-09)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/89172919243df199fe237ba0f776c3e3e3d72367' (2024-10-20)
  → 'github:nixos/nixpkgs/9256f7c71a195ebe7a218043d9f93390d49e6884' (2024-11-10)
• Updated input 'unstable':
    'github:nixos/nixpkgs/2768c7d042a37de65bb1b5b3268fc987e534c49d' (2024-10-23)
  → 'github:nixos/nixpkgs/76612b17c0ce71689921ca12d9ffdc9c23ce40b2' (2024-11-09)
2024-11-11 20:05:12 +01:00
teutat3s e48fe612e2
core: add activationScript to show closure diff
All checks were successful
Flake checks / Check (pull_request) Successful in 23m35s
This is useful when updating a host, by doing a dry-run with deploy-rs
we get a list of changed package versions.
2024-11-11 18:02:47 +01:00
teutat3s 34ce43a5e0
secrets: remove leftover secret files
Some checks failed
Flake checks / Check (pull_request) Has been cancelled
After cleanup:
❯ find ./secrets -type f -name "*.age" | wc -l
64

❯ rg publicKeys secrets/secrets.nix  | wc -l
64
2024-11-07 12:22:27 +01:00
teutat3s 43b0c8d489
matrix-appservice-irc: reduce logging level to warn
All checks were successful
Flake checks / Check (pull_request) Successful in 22m38s
2024-11-06 21:29:27 +01:00
teutat3s afe52ca6af
alertmanager: alert on high load only after 20m
All checks were successful
Flake checks / Check (pull_request) Successful in 2m8s
2024-11-06 21:28:28 +01:00
teutat3s da529b023e
Merge pull request 'ci: use treefmt2 with flag --ci' (#248) from ci-treefmt into main
Reviewed-on: pub-solar/infra#248
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-06 14:40:03 +00:00
teutat3s cf39137340
Merge pull request 'docs: more garage CLI usage, avoid leaking secret' (#246) from docs-garage into main
Reviewed-on: pub-solar/infra#246
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-06 14:39:53 +00:00
teutat3s 18683d383f
Merge pull request 'docs: add examples for cachix usage' (#230) from docs-cachix into main
Reviewed-on: pub-solar/infra#230
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-11-06 14:39:44 +00:00
teutat3s d8a793190d
Merge pull request 'matrix-authentication-service: init, test, migrate synapse' (#250) from mas-init into main
Reviewed-on: pub-solar/infra#250
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
2024-10-30 20:02:53 +00:00
teutat3s 3ec5c9f343
style: fix formatting
All checks were successful
Flake checks / Check (pull_request) Successful in 22m4s
2024-10-30 20:32:47 +01:00
teutat3s 7ba5a7bdd6
matrix: disable sliding-sync proxy, it's built into
Some checks failed
Flake checks / Check (pull_request) Failing after 22s
synapse now, update synapse config to use matrix-authentication-service
2024-10-30 20:31:29 +01:00
b12f 041d311bb2
modules/matrix: rename used config options
Some checks failed
Flake checks / Check (pull_request) Failing after 23s
2024-10-30 18:37:47 +01:00
teutat3s 9d9bcf9a15
mas: move to module, add secrets for prod 2024-10-30 18:37:46 +01:00
b12f 4434a90136
modules/matrix: rename secrets to not include hostnames 2024-10-30 18:37:46 +01:00
teutat3s 472f9aa68b
dns: list.pub.solar should be A / AAAA records 2024-10-30 18:37:46 +01:00
teutat3s c9c2d06a98
dns: add CNAME record for mas.pub.solar 2024-10-30 18:37:46 +01:00
teutat3s 8244e605b6
fix: passkey support in pub.solar keycloak theme 2024-10-30 18:37:46 +01:00
teutat3s 9d7d251369
style: fix formatting 2024-10-30 18:37:46 +01:00
teutat3s 7775ad332e
matrix: do not change paths for nachtigall secrets 2024-10-30 18:37:46 +01:00
teutat3s d6cc9c8164
matrix-authentication-service: init host underground
to test mas, related to #242
2024-10-30 18:37:45 +01:00
teutat3s 4c51eda8b6
Merge pull request 'modules/tt-rss: pin on revision' (#253) from update-tt-rss into main
Reviewed-on: pub-solar/infra#253
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
2024-10-30 17:37:10 +00:00
b12f 471d7650ff
modules/tt-rss: pin on revision
All checks were successful
Flake checks / Check (pull_request) Successful in 21m25s
2024-10-30 18:35:18 +01:00
teutat3s 9cc50ed678
Merge pull request 'maintenance: updates for mastodon, matrix-synapse' (#249) from flake-updates-2024-10-24 into main
Reviewed-on: pub-solar/infra#249
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-24 16:16:06 +00:00
teutat3s 4309cc9cdd
ci: use treefmt2 with flag --ci
All checks were successful
Flake checks / Check (pull_request) Successful in 2m7s
Update treefmt to version 2.

This adds the following flags for CI usage:
"--no-cache, --fail-on-change and adjusting some other settings best suited to a CI".
See: https://treefmt.com/usage
2024-10-24 15:43:00 +02:00
teutat3s 08f5c5ce67
docs: more garage CLI usage, avoid leaking secret
All checks were successful
Flake checks / Check (pull_request) Successful in 2m3s
2024-10-24 15:10:44 +02:00
teutat3s 870e81ee4c
flake.lock: Update
All checks were successful
Flake checks / Check (pull_request) Successful in 25m54s
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/d7d57edb72e54891fa67a6f058a46b2bb405663b' (2024-10-16)
  → 'github:nix-community/disko/09a776702b004fdf9c41a024e1299d575ee18a7d' (2024-10-23)
• Updated input 'nix-darwin':
    'github:lnl7/nix-darwin/a60ac02f9466f85f092e576fd8364dfc4406b5a6' (2024-10-14)
  → 'github:lnl7/nix-darwin/04193f188e4144d7047f83ad1de81d6034d175cd' (2024-10-24)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/dc2e0028d274394f73653c7c90cc63edbb696be1' (2024-10-16)
  → 'github:nixos/nixpkgs/89172919243df199fe237ba0f776c3e3e3d72367' (2024-10-20)
• Updated input 'unstable':
    'github:nixos/nixpkgs/a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c' (2024-10-14)
  → 'github:nixos/nixpkgs/2768c7d042a37de65bb1b5b3268fc987e534c49d' (2024-10-23)
2024-10-24 14:53:39 +02:00
teutat3s cef7a561f3
Merge pull request 'garage: fix wildcard DNS cert renewal with wildcard CNAME records' (#245) from fix-dns-cert-renewal into main
Reviewed-on: pub-solar/infra#245
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-24 12:51:41 +00:00
teutat3s 281701b7b6
Merge pull request 'docs: fix IP for keycloak admin API' (#247) from update-docs into main
Reviewed-on: pub-solar/infra#247
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-24 12:51:31 +00:00
teutat3s 90bbaad7b7
Merge pull request 'trinkgenossin: fix network in initrd' (#244) from trinkgenossin-remote-luks into main
Reviewed-on: pub-solar/infra#244
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-24 12:51:18 +00:00
teutat3s 6a15c09509
docs: add hint how to get CACHIX_AUTH_TOKEN
All checks were successful
Flake checks / Check (pull_request) Successful in 21m8s
2024-10-23 20:59:07 +02:00
teutat3s 94d7db1331
docs: add examples for cachix usage 2024-10-23 20:59:06 +02:00
teutat3s 633f0a4402
docs: fix IP for keycloak admin API
All checks were successful
Flake checks / Check (pull_request) Successful in 20m57s
2024-10-23 20:28:55 +02:00
teutat3s 9758aeda5d
garage: fix wildcard DNS cert renewal with wildcard
All checks were successful
Flake checks / Check (pull_request) Successful in 20m13s
CNAME records

By usind wildcard CNAME records, we make lego think it needs to validate
challenges using these CNAME records. We actually want regular
_acme-challenge.* records, so use a environment variable to avoid CNAME
detection. This fixes DNS cert renewal. Still curious? See:
https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme/
2024-10-23 20:18:57 +02:00
teutat3s 2c29d27ce7
style: remove redundant brackets
All checks were successful
Flake checks / Check (pull_request) Successful in 21m41s
2024-10-23 20:18:03 +02:00
teutat3s 31a885926b
trinkgenossin: fix network in initrd, virtio_net
kernel module was missing. Also this is a QEMU host, hyperV is not
required.
2024-10-23 20:17:32 +02:00
teutat3s 0ae6bc637b
Merge pull request 'mastodon: host media files on pub.solar garage cluster' (#239) from mastodon-media-on-garage into main
Reviewed-on: pub-solar/infra#239
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-23 15:24:28 +00:00
teutat3s 5300f381b0
nginx: use safer request_uri variable
All checks were successful
Flake checks / Check (pull_request) Successful in 21m30s
Fix >> Problem: [http_splitting] Possible HTTP-Splitting vulnerability.
https://github.com/yandex/gixy/blob/master/docs/en/plugins/httpsplitting.md
2024-10-17 21:15:57 +02:00
teutat3s 8a18ee452b
garage: fix s3_api root_domain 2024-10-17 21:15:57 +02:00
teutat3s 666de2c8f4
mastodon: switch files.pub.solar from storj to garage
s3 backend
2024-10-17 21:15:55 +02:00
teutat3s b1391521b9
Merge pull request 'maintenance: update element-web, keycloak, mastodon, nextcloud' (#240) from flake-updates into main
Reviewed-on: pub-solar/infra#240
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-17 19:12:37 +00:00
teutat3s 987c0919ca
style: fix formatting
All checks were successful
Flake checks / Check (pull_request) Successful in 27m37s
2024-10-17 20:31:47 +02:00
teutat3s c39cf9c0b9
mastodon: update to version 4.3.0 from nixos-unstable
https://github.com/mastodon/mastodon/releases/tag/v4.3.0
https://github.com/NixOS/nixpkgs/pull/337545/files
2024-10-17 20:31:47 +02:00
teutat3s 3943f34c92
flake.lock: Update
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/48ebb577855fb2398653f033b3b2208a9249203d' (2024-10-05)
  → 'github:nix-community/disko/d7d57edb72e54891fa67a6f058a46b2bb405663b' (2024-10-16)
• Updated input 'nix-darwin':
    'github:lnl7/nix-darwin/8c8388ade72e58efdeae71b4cbb79e872c23a56b' (2024-10-03)
  → 'github:lnl7/nix-darwin/a60ac02f9466f85f092e576fd8364dfc4406b5a6' (2024-10-14)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/6e6b3dd395c3b1eb9be9f2d096383a8d05add030' (2024-10-04)
  → 'github:nixos/nixpkgs/dc2e0028d274394f73653c7c90cc63edbb696be1' (2024-10-16)
• Updated input 'unstable':
    'github:nixos/nixpkgs/bc947f541ae55e999ffdb4013441347d83b00feb' (2024-10-04)
  → 'github:nixos/nixpkgs/a3c0b3b21515f74fd2665903d4ce6bc4dc81c77c' (2024-10-14)
2024-10-17 20:31:17 +02:00
b12f e85807a29b
Merge pull request 'nextcloud: docs how to get debug logs' (#238) from nextcloud-fix-logs into main
Reviewed-on: pub-solar/infra#238
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
2024-10-16 15:29:26 +00:00
teutat3s c53d48384a
nextcloud: document how to get debugging logs
Some checks failed
Flake checks / Check (pull_request) Has been cancelled
2024-10-16 17:19:49 +02:00
teutat3s 9579f6adde
Merge pull request 'logins: add teutat3s secondary SSH public key' (#237) from teutat3s-add-ssh into main
Reviewed-on: pub-solar/infra#237
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-08 22:09:53 +00:00
teutat3s 01ca3b21c2
Merge pull request 'mastodon: actually use opensearch via module option' (#236) from mastodon-full-text-search into main
Reviewed-on: pub-solar/infra#236
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
2024-10-08 21:03:39 +00:00
teutat3s d085e49925
logins: add teutat3s secondary SSH public key
Some checks failed
Flake checks / Check (pull_request) Failing after 6m51s
2024-10-08 19:10:20 +02:00
teutat3s 092a45e3bd
mastodon: actually use opensearch via module option
All checks were successful
Flake checks / Check (pull_request) Successful in 19m43s
2024-10-08 19:09:17 +02:00
teutat3s a8d865bbca
Merge pull request 'maintenance updates for element-web, forgejo, mastodon, matrix-synapse, nextcloud and others' (#235) from flake-updates into main
Reviewed-on: pub-solar/infra#235
Reviewed-by: hensoko <hensoko@noreply.git.pub.solar>
Reviewed-by: Akshay Mankar <axeman@noreply.git.pub.solar>
2024-10-05 12:30:07 +00:00
teutat3s df2f0d4442
flake: refactor, bye srid
All checks were successful
Flake checks / Check (pull_request) Successful in 24m21s
Refactor flake to work without nixos-flake and use native NixOS module
system. This is because of recent changes to nixos-flake, like renaming it
to nixos-unified and changing the API without a changelog or guide how
to update.
2024-10-05 14:03:40 +02:00
teutat3s 8c8a757f8f
garage: update to 1.0.1
https://git.deuxfleurs.fr/Deuxfleurs/garage/releases/tag/v1.0.1
2024-10-05 13:03:40 +02:00
teutat3s 8600fc64c5
wireguard: fix trinkgenossin IPv4 address 2024-10-05 13:03:40 +02:00
teutat3s 37f210c96f
security: add libolm to permittedInsecurePackages 2024-10-05 13:03:40 +02:00
teutat3s d675fd8d00
flake.lock: Update
Flake lock file updates:

• Updated input 'deploy-rs':
    'github:serokell/deploy-rs/3867348fa92bc892eba5d9ddb2d7a97b9e127a8a' (2024-06-12)
  → 'github:serokell/deploy-rs/aa07eb05537d4cd025e2310397a6adcedfe72c76' (2024-09-27)
• Updated input 'disko':
    'github:nix-community/disko/435737144be0259559ca3b43f7d72252b1fdcc1b' (2024-08-22)
  → 'github:nix-community/disko/48ebb577855fb2398653f033b3b2208a9249203d' (2024-10-05)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/8471fe90ad337a8074e957b69ca4d0089218391d' (2024-08-01)
  → 'github:hercules-ci/flake-parts/3d04084d54bedc3d6b8b736c70ef449225c361b1' (2024-10-01)
• Updated input 'flake-parts/nixpkgs-lib':
    'a5d394176e.tar.gz?narHash=sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q%3D' (2024-08-01)
  → 'fb192fec7c.tar.gz?narHash=sha256-0xHYkMkeLVQAMa7gvkddbPqpxph%2BhDzdu1XdGPJR%2BOs%3D' (2024-10-01)
• Updated input 'home-manager':
    'github:nix-community/home-manager/e1391fb22e18a36f57e6999c7a9f966dc80ac073' (2024-07-03)
  → 'github:nix-community/home-manager/2f23fa308a7c067e52dfcc30a0758f47043ec176' (2024-09-22)
• Updated input 'nix-darwin':
    'github:lnl7/nix-darwin/a8968d88e5a537b0491f68ce910749cd870bdbef' (2024-08-22)
  → 'github:lnl7/nix-darwin/8c8388ade72e58efdeae71b4cbb79e872c23a56b' (2024-10-03)
• Updated input 'nixos-flake':
    'github:srid/nixos-flake/5734c1d9a5fe0bc8e8beaf389ad6227392ca0108' (2024-07-16)
  → 'github:srid/nixos-flake/47a26bc9118d17500bbe0c4adb5ebc26f776cc36' (2024-10-04)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/224042e9a3039291f22f4f2ded12af95a616cca0' (2024-08-21)
  → 'github:nixos/nixpkgs/6e6b3dd395c3b1eb9be9f2d096383a8d05add030' (2024-10-04)
• Updated input 'unstable':
    'github:nixos/nixpkgs/c374d94f1536013ca8e92341b540eba4c22f9c62' (2024-08-21)
  → 'github:nixos/nixpkgs/bc947f541ae55e999ffdb4013441347d83b00feb' (2024-10-04)
2024-10-05 13:02:20 +02:00
teutat3s 2e5a7bea4b
Merge pull request 'flora-6: remove' (#234) from remove-flora-6-sad-face into main
Reviewed-on: pub-solar/infra#234
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
2024-09-10 15:58:58 +00:00
b12f 4831430455
chore: run nix fmt
Some checks failed
Flake checks / Check (pull_request) Has been cancelled
2024-09-10 16:02:26 +02:00
teutat3s 663ef8feb1
alerts: fix condition 2024-09-10 16:02:26 +02:00
teutat3s 63fa03e971
alerts.pub.solar: use DNS challenge for cert 2024-09-10 16:02:26 +02:00
teutat3s faa71b7797
alerts: add check for healthy garage cluster 2024-09-10 16:02:26 +02:00
teutat3s 21a1ae15cb
trinkgenossin: fix duplicate promtail, prometheus-exporter 2024-09-10 16:02:26 +02:00
teutat3s 19723f3812
monitoring: add prometheus-exporter, promtail to
delite, blue-shell

add instance labels to garage scrape jobs
2024-09-10 16:02:26 +02:00
teutat3s ec5e9896fd
delite: use static IP in initrd, DHCP not working 2024-09-10 16:02:25 +02:00
teutat3s 47b076e0a6
loki: store logs in /var/lib/loki 2024-09-10 16:02:25 +02:00
teutat3s 02a146c507
dns: switch to opentofu + terraform-backend-git,
use opentofu encrypted state feature

https://opentofu.org/docs/language/state/encryption/#new-project
2024-09-10 16:02:25 +02:00
teutat3s 7e48428fb9
dns: remove old, unused DKIM key
We have our own mailserver now
2024-09-10 16:02:25 +02:00
teutat3s f4f6c14faa
flake: remove triton-vmtools, no longer needed
It was only used on flora-6
2024-09-10 16:02:25 +02:00
b12f 1ec5bafa30
flora-6: remove
This commit removes the flora-6 host. All services are moved to
trinkgenossin, with the drone service being removed completely in favour
of forgejo actions.
2024-09-10 16:02:24 +02:00
teutat3s 02629598aa
Merge pull request 'obs-portal: fix backups, docker command does not need a TTY' (#233) from obs-backup-fix into main
Reviewed-on: pub-solar/infra#233
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
2024-09-09 15:43:14 +00:00
teutat3s 44f708ec76
obs-portal: run backups 1h later to avoid lock conflict
Some checks failed
Flake checks / Check (pull_request) Has been cancelled
2024-09-09 17:28:57 +02:00
teutat3s cd82b83427
obs-portal: fix backups, docker command does not
All checks were successful
Flake checks / Check (pull_request) Successful in 20m28s
need a TTY
2024-08-31 22:05:11 +02:00
teutat3s 2d94ed5a0d
Merge pull request 'obs-portal: add backups' (#228) from obs-portal-backups into main
Reviewed-on: pub-solar/infra#228
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
Reviewed-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-31 19:43:10 +00:00
teutat3s 83e4bcd2df
Merge pull request 'mail: add backups' (#226) from mail-backups into main
Reviewed-on: pub-solar/infra#226
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
Reviewed-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-31 19:39:25 +00:00
teutat3s 09804f5c25
docs: how-to add backups for new hosts
All checks were successful
Flake checks / Check (pull_request) Successful in 3m43s
2024-08-29 16:36:11 +02:00
teutat3s 2eb54a331e
backups: add storagebox to programs.ssh.knownHosts 2024-08-29 16:36:09 +02:00
teutat3s 77b642f646
garage: increase nginx client_body_size to 64m
To make bigger garage uploads work well, avoiding error
HTTP 413 Entity Too Large
2024-08-29 16:24:32 +02:00
teutat3s 2e16c77956
secrets: rename restic-repo-storagebox{,-nachtigall}
To use a restic repository per host
2024-08-29 16:22:58 +02:00
teutat3s e2ba1aacf4
mail: add backups to garage bucket + storagebox
Restic backups to garage S3 bucket metronom-backups
2024-08-29 16:19:24 +02:00
teutat3s 27dc20dd04
obs-portal: add backups to garage bucket + storagebox
All checks were successful
Flake checks / Check (pull_request) Successful in 23m21s
Restic backups to garage S3 bucket nachtigall-backups
2024-08-29 10:09:04 +02:00
teutat3s a0fb6a60c3
Merge pull request 'devshell: add terraform-ls' (#227) from terraform-devshell into main
Reviewed-on: pub-solar/infra#227
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
Reviewed-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-28 15:55:29 +00:00
teutat3s d2389497c2
Merge pull request 'garage: initial cluster' (#222) from garage-cluster into main
Reviewed-on: pub-solar/infra#222
Reviewed-by: b12f <b12f@noreply.git.pub.solar>
Reviewed-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-28 15:55:16 +00:00
teutat3s c056d9c35e
Merge pull request 'mediawiki: add backups' (#225) from mediawiki-backups into main
Reviewed-on: pub-solar/infra#225
Reviewed-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-28 15:54:33 +00:00
teutat3s 4626fd85c0
mediawiki: add backups to garage bucket + storagebox
All checks were successful
Flake checks / Check (pull_request) Successful in 1m56s
Restic backups to garage S3 bucket nachtigall-backups
https://garagehq.deuxfleurs.fr/documentation/connect/backup/#restic
2024-08-28 17:13:34 +02:00
teutat3s c0a3d90d63
backups: add environmentFile option 2024-08-28 17:13:34 +02:00
teutat3s 1d92ef53ca
backups: storeName -> repoName 2024-08-28 17:13:33 +02:00
teutat3s 751d82f7e3
backups: rename pub-solar-os.backups.backups -> pub-solar-os.backups.restic 2024-08-28 17:12:22 +02:00
teutat3s fb8ee1278a
Merge pull request 'feat/tests' (#224) from feat/tests into main
Reviewed-on: pub-solar/infra#224
Reviewed-by: teutat3s <teutat3s@noreply.git.pub.solar>
2024-08-27 10:45:56 +00:00
teutat3s 66ed87e666
ci: avoid garbage collection of checks
All checks were successful
Flake checks / Check (pull_request) Successful in 17m36s
2024-08-27 12:37:37 +02:00
teutat3s 88b76beb5c
keycloak: use backups module
All checks were successful
Flake checks / Check (pull_request) Successful in 19m4s
Co-authored-by: b12f <b12f@noreply.git.pub.solar>
Co-authored-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-27 10:09:07 +02:00
teutat3s e857c6198b
modules/backup: init
Co-authored-by: b12f <b12f@noreply.git.pub.solar>
Co-authored-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-27 10:04:10 +02:00
teutat3s 998cf4c63d
website: force HTTPS
Co-authored-by: b12f <b12f@noreply.git.pub.solar>
Co-authored-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-27 10:03:43 +02:00
teutat3s a0b52d51e5
nachtigall: make postgres wait for zfs mount
Co-authored-by: b12f <b12f@noreply.git.pub.solar>
Co-authored-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-27 10:00:42 +02:00
teutat3s 701c62dd69
tests: create keycloak test, add working test for website
Co-authored-by: b12f <b12f@noreply.git.pub.solar>
Co-authored-by: Hendrik Sokolowski <hensoko@noreply.git.pub.solar>
2024-08-27 09:55:25 +02:00
teutat3s 711347abe6
docs: add how-to create garage bucket + key
All checks were successful
Flake checks / Check (pull_request) Successful in 6m38s
add new hosts to WireGuard example config
2024-08-26 11:56:45 +02:00
teutat3s 13bf3f5beb
docs: SSH to trinkgenossin for garage command
All checks were successful
Flake checks / Check (pull_request) Successful in 6m45s
2024-08-25 03:27:42 +02:00
teutat3s f639fbe050
devshell: add terraform-ls
All checks were successful
Flake checks / Check (pull_request) Successful in 5m49s
2024-08-25 02:37:36 +02:00
teutat3s f236962e17
garage: add monitoring, connect to grafana + loki
All checks were successful
Flake checks / Check (pull_request) Successful in 7m10s
https://garagehq.deuxfleurs.fr/documentation/reference-manual/monitoring/
2024-08-25 00:18:09 +02:00
teutat3s d32abd7a7f
wireguard: add trinkgenossin, delite, blue-shell 2024-08-25 00:13:53 +02:00
teutat3s 15b507904f
garage: init buckets.pub.solar, use nginx as reverse proxy
https://garagehq.deuxfleurs.fr/documentation/cookbook/reverse-proxy/
2024-08-24 21:48:48 +02:00
teutat3s b0790876ec
style: format using nixfmt-rfc-style
All checks were successful
Flake checks / Check (pull_request) Successful in 7m42s
2024-08-24 17:39:49 +02:00
teutat3s b6070d0f75
docs: initial docs for nixos-anywhere and garage setup
Some checks failed
Flake checks / Check (pull_request) Failing after 2m26s
2024-08-24 03:06:17 +02:00
teutat3s 25827a97d3
modules: add unlock-luks-on-boot 2024-08-24 03:05:28 +02:00
teutat3s 4a3d3ce84b
garage: init module 2024-08-24 03:05:16 +02:00
teutat3s 9eb746313e
flake: add disko
https://github.com/nix-community/disko
And add hosts to deploy-rs
2024-08-24 03:04:19 +02:00
teutat3s 83b7e3e11e
hosts: init blue-shell 2024-08-24 03:02:15 +02:00
teutat3s 4ef9781d10
hosts: init delite 2024-08-24 03:01:46 +02:00
teutat3s ca8e578b11
hosts: init trinkgenossin 2024-08-24 03:00:01 +02:00
teutat3s 49c21fe740
dns: add trinkgenossin, delite, blue-shell 2024-08-24 02:58:37 +02:00
175 changed files with 5868 additions and 2254 deletions

View file

@ -10,7 +10,7 @@ jobs:
- name: Check formatting
run: |
nix --accept-flake-config --access-tokens '' develop --command treefmt --fail-on-change
nix --accept-flake-config --access-tokens '' develop --command treefmt --ci
- name: Run flake checks
run: |
@ -18,14 +18,20 @@ jobs:
# Prevent cache garbage collection by creating GC roots
mkdir -p /var/lib/gitea-runner/tankstelle/.local/state/nix/results
for target in $(nix flake show --json --all-systems | jq '
for target in $(nix flake show --json --all-systems | jq --raw-output '
.["nixosConfigurations"] |
to_entries[] |
.key
' | tr -d '"'
.key'
); do
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' \
build --out-link /var/lib/gitea-runner/tankstelle/.local/state/nix/results/"$target" ".#nixosConfigurations.${target}.config.system.build.toplevel"
done
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' flake check
for check in $(nix flake show --json --all-systems | jq --raw-output '
.checks."x86_64-linux" |
to_entries[] |
.key'
); do
nix --print-build-logs --verbose --accept-flake-config --access-tokens '' \
build --out-link /var/lib/gitea-runner/tankstelle/.local/state/nix/results/"$check" ".#checks.x86_64-linux.${check}"
done

View file

@ -28,18 +28,18 @@ People with admin access to the infrastructure are added to [`logins/admins.nix`
SSH is not reachable from the open internet. Instead, SSH Port 22 is protected by a wireguard VPN network. Thus, to get root access on the servers, at least two pieces of information have to be added to the admins config:
1. **SSH Public key**: self-explanatory. Add your public key to your user attrset under `sshPubKeys`.
2. **Wireguard device**: each wireguard device has two parts: the public key and the IP addresses it should have in the wireguard network. The pub.solar wireguard network is spaced under `10.7.6.0/24` and `fd00:fae:fae:fae:fae::/80`. To add your device, it's best to choose a free number between 200 and 255 and use that in both the ipv4 and ipv6 ranges: `10.7.6.<ip-address>/32` `fd00:fae:fae:fae:fae:<ip-address>::/96`. For more information on how to generate keypairs, see [the NixOS Wireguard docs](https://nixos.wiki/wiki/WireGuard#Generate_keypair).
2. **Wireguard device**: each wireguard device has two parts: the public key and the IP addresses it should have in the wireguard network. The pub.solar wireguard network uses the subnets `10.7.6.0/24` and `fd00:fae:fae:fae:fae::/80`. To add your device, it's best to choose a free number between 200 and 255 and use that in both the ipv4 and ipv6 ranges: `10.7.6.<ip-address>/32` `fd00:fae:fae:fae:fae:<ip-address>::/96`. For more information on how to generate keypairs, see [the NixOS Wireguard docs](https://nixos.wiki/wiki/WireGuard#Generate_keypair).
One can access our hosts using this domain scheme:
```
ssh barkeeper@<hostname>.wg.pub.solar
ssh <unix-username>@<hostname>.wg.pub.solar
```
So, for example for `nachtigall`:
```
ssh barkeeper@nachtigall.wg.pub.solar
ssh teutat3s@nachtigall.wg.pub.solar
```
Example NixOS snippet for WireGuard client config
@ -63,12 +63,6 @@ Example NixOS snippet for WireGuard client config
#endpoint = "138.201.80.102:51820";
persistentKeepalive = 15;
}
{ # flora-6.pub.solar
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
allowedIPs = [ "10.7.6.2/32" "fd00:fae:fae:fae:fae:2::/96" ];
endpoint = "80.71.153.210:51820";
persistentKeepalive = 15;
}
{ # metronom.pub.solar
publicKey = "zOSYGO7MfnOOUnzaTcWiKRQM0qqxR3JQrwx/gtEtHmo=";
allowedIPs = [ "10.7.6.3/32" "fd00:fae:fae:fae:fae:3::/96" ];
@ -85,6 +79,39 @@ Example NixOS snippet for WireGuard client config
#endpoint = "80.244.242.5:51820";
persistentKeepalive = 15;
}
{
# trinkgenossin.pub.solar
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
allowedIPs = [
"10.7.6.5/32"
"fd00:fae:fae:fae:fae:5::/96"
];
#endpoint = "85.215.152.22:51820";
endpoint = "[2a01:239:35d:f500::1]:51820";
persistentKeepalive = 15;
}
{
# delite.pub.solar
publicKey = "ZT2qGWgMPwHRUOZmTQHWCRX4m14YwOsiszjsA5bpc2k=";
allowedIPs = [
"10.7.6.6/32"
"fd00:fae:fae:fae:fae:6::/96"
];
#endpoint = "5.255.119.132:51820";
endpoint = "[2a04:52c0:124:9d8c::2]:51820";
persistentKeepalive = 15;
}
{
# blue-shell.pub.solar
publicKey = "bcrIpWrKc1M+Hq4ds3aN1lTaKE26f2rvXhd+93QrzR8=";
allowedIPs = [
"10.7.6.7/32"
"fd00:fae:fae:fae:fae:7::/96"
];
#endpoint = "194.13.83.205:51820";
endpoint = "[2a03:4000:43:24e::1]:51820";
persistentKeepalive = 15;
}
];
};
};

36
docs/backups.md Normal file
View file

@ -0,0 +1,36 @@
# Backups
We use [Restic](https://restic.readthedocs.io/en/stable/) to create backups and push them to two repositories.
Check `./modules/backups.nix` and `./hosts/nachtigall/backups.nix` for working examples.
### Hetzner Storagebox
- Uses SFTP for transfer of backups
Adding a new host SSH public key to the storagebox:
First, [SSH to nachtigall](./administrative-access.md#ssh-access), then become root and add the new SSH public key
```
sudo -i
echo '<ssh-public-key>' | ssh -p23 u377325@u377325.your-storagebox.de install-ssh-key
```
[Link to Hetzner storagebox docs](https://docs.hetzner.com/robot/storage-box/backup-space-ssh-keys).
### Garage S3 buckets
- Uses S3 for transfer of backups
- One bucket per host, e.g. `nachtigall-backups`, `metronom-backups`
To start transfering backups from a new hosts, this is how to create a new bucket:
First, [SSH to trinkgenossin](./administrative-access.md#ssh-access), then use the `garage` CLI to create a new key and bucket:
```
export GARAGE_RPC_SECRET=<secret-in-keepass>
garage bucket create <hostname>-backups
garage key create <hostname>-backups-key
garage bucket allow <hostname>-backups --read --write --key <hostname>-backups-key
```

55
docs/cachix.md Normal file
View file

@ -0,0 +1,55 @@
# Cachix usage
URL: https://pub-solar.cachix.org
Requirements:
- [Install cachix](https://docs.cachix.org/installation)
- Optional: To push to the cache, you need to set `CACHIX_AUTH_TOKEN` in your environment. To generate one for you, follow the [Getting Started](https://docs.cachix.org/getting-started#authenticating) docs and login with your GitHub account.
- Add our binary cache [to your nix config](https://docs.cachix.org/faq#cachix-use-effects). To add the pub-solar cache, run:
```
cachix use pub-solar
```
Example to build and push a custom package of a host in this flake (e.g. after creating an overlay):
```
nix build --json -f . '.#nixosConfigurations.nachtigall.pkgs.keycloak^*' \
| jq -r '.[].outputs | to_entries[].value' \
| cachix push pub-solar
```
Example to build and push a package in the `nixpkgs` repo:
```
cd nixpkgs
nix build --json -f . 'pkgs.lix^*' \
| jq -r '.[].outputs | to_entries[].value' \
| cachix push pub-solar
```
Checking if a package has been correctly pushed to the cache:
```
nix build --json '/nix/store/f76xi83z4xk9sn6pbh38rh97yvqhb5m0-noto-fonts-color-emoji-png-2.042.drv^*' | jq -r '.[].outputs | to_entries[].value' | cachix push pub-solar
Pushing 1 paths (0 are already present) using zstd to cache pub-solar ⏳
✓ /nix/store/xpgpi84765dxqja3gd5pldj49xx2v0xl-noto-fonts-color-emoji-png-2.042 (10.30 MiB)
All done.
curl -I https://pub-solar.cachix.org/xpgpi84765dxqja3gd5pldj49xx2v0xl.narinfo
HTTP/2 200
date: Mon, 26 Aug 2024 09:31:10 GMT
content-type: text/x-nix-narinfo
traceparent: 00-b99db37cc9c2581b8d226cdf81e54507-794fc49193659c03-01
tracestate:
cache-control: public, max-age=14400
last-modified: Mon, 26 Aug 2024 09:31:10 GMT
cf-cache-status: EXPIRED
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=A67KGsCIsYjoFdvndxJ0rkmb7BZ5ztIpm8WUJKAiUPRVWvbYeXU9gU27P7zryiUtArbwrLzHhhMija0yyXk0kwNa3suz8gNzKK6z1CX1FWDZiiP07rnq7zAg8nZbSBiEU%2FZrU9nSrR6mhuL9ihbmW1Hf"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 8b92ceab0d19c80e-DUS
```

View file

@ -50,7 +50,7 @@ Docs: https://forgejo.org/docs/latest/admin/command-line/#delete
### Matrix
```
curl --header "Authorization: Bearer <admin-access-token>" --request POST http://172.18.0.3:8008/_synapse/admin/v1/deactivate/@<username>:pub.solar --data '{"erase": true}'
curl --header "Authorization: Bearer <admin-access-token>" --request POST http://127.0.0.1:8008/_synapse/admin/v1/deactivate/@<username>:pub.solar --data '{"erase": true}'
```
Docs: https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#deactivate-account

View file

@ -7,22 +7,29 @@ be manually deployed.
To deploy, make sure you have a [working development shell](./development-shell.md).
Then, run `deploy-rs` with the hostname of the server you want to deploy:
### Dry-run
Use `--dry-activate` to show a diff of updated packages and all services that
would be restarted by the update. This will also put all files in place without
switching to the new generation, enabling a quick switch to the new config at a
later moment.
For nachtigall.pub.solar:
```
deploy --targets '.#nachtigall' --magic-rollback false --auto-rollback false --keep-result --result-path ./results
deploy --targets '.#nachtigall' --ssh-user <unix-username> --magic-rollback false --auto-rollback false --keep-result --result-path ./results --dry-activate
```
For flora-6.pub.solar:
After reviewing the changes, apply the update with:
```
deploy --targets '.#flora-6' --magic-rollback false --auto-rollback false --keep-result --result-path ./results
deploy --targets '.#nachtigall' --ssh-user <unix-username> --magic-rollback false --auto-rollback false --keep-result --result-path ./results
```
For metronom.pub.solar (aarch64-linux):
```
deploy --targets '.#metronom' --magic-rollback false --auto-rollback false --keep-result --result-path ./results --remote-build
deploy --targets '.#metronom' --ssh-user <unix-username> --magic-rollback false --auto-rollback false --keep-result --result-path ./results --remote-build
```
Usually we skip all rollback functionality, but if you want to deploy a change
@ -31,9 +38,6 @@ that might lock you out, e.g. to SSH, it might make sense to set these to `true`
To skip flake checks, e.g. because you already ran them manually before
deployment, add the flag `--skip-checks` at the end of the command.
`--dry-activate` can be used to only put all files in place without switching,
to enable switching to the new config quickly at a later moment.
We use `--keep-result --result-path ./results` to keep the last `result`
symlink of each `deploy` from being garbage collected. That way, we keep builds
cached in the Nix store. This is optional and both flags can be removed if disk

View file

@ -1,18 +1,10 @@
# Changing DNS entries
Our current DNS provider is [namecheap](https://www.namecheap.com/).
We use [Terraform](https://www.terraform.io) to declaratively manage our pub.solar DNS records.
We use [OpenTofu](https://opentofu.org) to declaratively manage our pub.solar DNS records.
### Initial setup
Skip this step if you already have a `triton` profile setup.
```
triton profile create
```
Please follow https://docs.greenbaum.cloud/en/devops/triton-cli.html for the details.
You will need to setup the following [namecheap API credentials](https://www.namecheap.com/support/api/intro),
look for "namecheap API key" in the pub.solar Keepass database.
@ -28,13 +20,15 @@ You will probably also need to add your external IP to the [API allow list](http
dig -4 ip @dns.toys
```
Now, change into the terraform directory and initialize the terraform providers.
Now, change into the terraform directory and initialize the terraform providers. To decrypt existing state,
search for "terraform state passphrase" in the pub.solar Keepass database.
```
cd terraform
export TRITON_KEY_ID=$(cat ~/.config/triton/profiles.d/lev-1-pub_solar.json | jq --raw-output .keyId)
export TF_VAR_state_passphrase=$(secret-tool lookup pub.solar terraform-state-passphrase-dns)
terraform init
alias tofu="terraform-backend-git --access-logs --tf tofu git terraform"
tofu init
```
Make your changes, e.g. in `dns.tf`.
@ -46,20 +40,21 @@ $EDITOR dns.tf
Plan your changes using:
```
terraform plan -out pub-solar-infra.plan
tofu plan -out pub-solar-infra.plan
```
After verification, apply your changes with:
```
terraform apply "pub-solar-infra.plan"
tofu apply "pub-solar-infra.plan"
```
### Useful links
We use the Manta remote backend to save the terraform state for collaboration.
We use terraform-backend-git remote backend with opentofu state encryption for collaboration.
- https://www.terraform.io/language/v1.2.x/settings/backends/manta
- https://github.com/plumber-cd/terraform-backend-git
- https://opentofu.org/docs/language/state/encryption
Namecheap Terraform provider docs:

View file

@ -1,19 +0,0 @@
# Drone CI
We currently use two CI systems, [drone CI](https://drone.io), reachable via
https://ci.pub.solar and [Forgejo Actions](https://forgejo.org/docs/latest/user/actions/),
which UI is integrated into https://git.pub.solar, for example
https://git.pub.solar/pub-solar/infra/actions.
### Signing the `.drone.yml` file
Login to https://ci.pub.solar by clicking on the user icon in the bottom left.
After logging in, you can view your personal API token by clicking on the same
icon. If you're using the nix [development-shell](./development-shell.md), the
`drone` command will already be installed.
```
export DRONE_TOKEN=<your-drone-api-token>
drone --token $DRONE_TOKEN sign --save pub-solar/os
```

84
docs/garage.md Normal file
View file

@ -0,0 +1,84 @@
# Garage
### How-To create a new bucket + keys
Requirements:
- `garage` RPC credentials, in the shared keepass, search for 'garage rpc secret'.
- [Setup WireGuard](./administrative-access.md#ssh-access) for hosts: `trinkgenossin`, optionally: `delite`, `blue-shell`
```
ssh <unix-username>@trinkgenossin.wg.pub.solar
```
```
# Add a few spaces to avoid leaking the secret to the shell history
export GARAGE_RPC_SECRET=<secret-in-keepass>
```
Now, you can run the following command to check the cluster status:
```
garage status
```
Command to list all existing buckets:
```
garage bucket list
```
Creating a new bucket and access keys:
```
garage bucket create <bucket-name>
garage key create <bucket-name>-key
garage bucket allow <bucket-name> --read --write --key <bucket-name>-key
```
Full example for `mastodon` bucket:
```
garage bucket create mastodon
garage key create mastodon-key
garage bucket allow mastodon --read --write --key mastodon-key
```
Then [setup your favourite S3 client](https://garagehq.deuxfleurs.fr/documentation/connect/cli/)
or use the bucket with any [S3 compatible software](https://garagehq.deuxfleurs.fr/documentation/connect/).
Further reading:
- https://garagehq.deuxfleurs.fr/documentation/quick-start/
- https://garagehq.deuxfleurs.fr/documentation/connect/
- https://garagehq.deuxfleurs.fr/documentation/connect/apps/#mastodon
### Notes on manual setup steps
```
ssh <unix-username>@trinkgenossin.wg.pub.solar
# Add a few spaces to avoid leaking the secret to the shell history
export GARAGE_RPC_SECRET=<secret-in-keepass>
# Uses the default config /etc/garage.toml
garage node id
garage node connect <node-id2>
garage node connect <node-id3>
garage status
#Zones
#DE-1 DE-2 NL-1
garage layout assign fdaa -z DE-1 -c 800G -t trinkgenossin
garage layout assign 8835 -z DE-2 -c 800G -t blue-shell
garage layout assign 73da -z NL-1 -c 800G -t delite
garage layout show
garage layout apply --version 1
```
Source: https://garagehq.deuxfleurs.fr/documentation/cookbook/real-world/#creating-a-cluster-layout

19
docs/nextcloud.md Normal file
View file

@ -0,0 +1,19 @@
# Nextcloud debugging
Set loglevel to `0` for debug logs:
```nix
services.nextcloud.settings.loglevel = 0;
```
Then, logs appear in the `phpfpm-nextcloud.service` logs:
```bash
sudo journalctl -fu phpfpm-nextcloud
```
Make sure to set the loglevel back to the default `2` warning after debugging:
```nix
services.nextcloud.settings.loglevel = 2;
```

View file

@ -41,3 +41,7 @@ wrapped-ruby-mastodon-gems: 4.2.1 → 4.2.3
zfs-kernel: 2.2.1-6.1.64 → 2.2.2-6.1.66
zfs-user: 2.2.1 → 2.2.2
```
### Deploying updates
See [deploying.md](./deploying.md).

13
docs/nixos-anywhere.md Normal file
View file

@ -0,0 +1,13 @@
```
curl -L https://github.com/nix-community/nixos-images/releases/download/nixos-unstable/nixos-kexec-installer-noninteractive-x86_64-linux.tar.gz | tar -xzf- -C /root
/root/kexec/run
```
```
mkdir -p /etc/secrets/initrd
ssh-keygen -t ed25519 -f /etc/secrets/initrd/ssh_host_ed25519_key
```
```
nix run github:nix-community/nixos-anywhere -- --flake .#blue-shell root@194.13.83.205
```

View file

@ -52,11 +52,11 @@
"utils": "utils"
},
"locked": {
"lastModified": 1718194053,
"narHash": "sha256-FaGrf7qwZ99ehPJCAwgvNY5sLCqQ3GDiE/6uLhxxwSY=",
"lastModified": 1727447169,
"narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=",
"owner": "serokell",
"repo": "deploy-rs",
"rev": "3867348fa92bc892eba5d9ddb2d7a97b9e127a8a",
"rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76",
"type": "github"
},
"original": {
@ -87,6 +87,26 @@
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1734343412,
"narHash": "sha256-b7G8oFp0Nj01BYUJ6ENC9Qf/HsYAIZvN9k/p0Kg/PFU=",
"owner": "nix-community",
"repo": "disko",
"rev": "a08bfe06b39e94eec98dd089a2c1b18af01fef19",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "disko",
"type": "github"
}
},
"element-stickers": {
"inputs": {
"maunium-stickerpicker": [
@ -165,11 +185,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1722555600,
"narHash": "sha256-XOQkdLafnb/p9ij77byFQjDf5m5QYl9b2REiVClC+x4=",
"lastModified": 1733312601,
"narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "8471fe90ad337a8074e957b69ca4d0089218391d",
"rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github"
},
"original": {
@ -214,18 +234,19 @@
"type": "github"
}
},
"flake-utils_3": {
"fork": {
"locked": {
"lastModified": 1653893745,
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
"lastModified": 1729963002,
"narHash": "sha256-2zrYfd/qdfExU5zVwvH80uJnKc/dMeK6zp3O1UtW2Mo=",
"owner": "teutat3s",
"repo": "nixpkgs",
"rev": "005faaacbeede0296dec5c844f508027ab8a3ff6",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"owner": "teutat3s",
"ref": "init-matrix-authentication-service-module",
"repo": "nixpkgs",
"type": "github"
}
},
@ -236,11 +257,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": {
@ -259,11 +280,11 @@
]
},
"locked": {
"lastModified": 1707424749,
"narHash": "sha256-eTvts5E3zmD4/DoAI9KedQjRwica0cg36wwIVp1NWbM=",
"lastModified": 1731518114,
"narHash": "sha256-h9Wb3VjmXBZwTO3prRweUKwp2H9hZHCQKrkbU+2WPQs=",
"ref": "main",
"rev": "1202a23c205b3c07a5feb5caf6813f21b3c69307",
"revCount": 30,
"rev": "060ecccc5f8c92a0705ab91ff047811efd559468",
"revCount": 36,
"type": "git",
"url": "https://git.pub.solar/pub-solar/keycloak-theme"
},
@ -277,11 +298,11 @@
"flake": false,
"locked": {
"dir": "web",
"lastModified": 1718796561,
"narHash": "sha256-RKAAHve17lrJokgAPkM2k/E+f9djencwwg3Xcd70Yfw=",
"lastModified": 1733177811,
"narHash": "sha256-1n7bPSCRw7keTCIu4tJGnUlkoId6H1+dPsTPzKo3Rrk=",
"owner": "maunium",
"repo": "stickerpicker",
"rev": "333567f481e60443360aa7199d481e1a45b3a523",
"rev": "89d3aece041c85ebe5a1ad4e620388af5227cbb0",
"type": "github"
},
"original": {
@ -299,11 +320,11 @@
]
},
"locked": {
"lastModified": 1724299755,
"narHash": "sha256-P5zMA17kD9tqiqMuNXwupkM7buM3gMNtoZ1VuJTRDE4=",
"lastModified": 1733570843,
"narHash": "sha256-sQJAxY1TYWD1UyibN/FnN97paTFuwBw3Vp3DNCyKsMk=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "a8968d88e5a537b0491f68ce910749cd870bdbef",
"rev": "a35b08d09efda83625bef267eb24347b446c80b8",
"type": "github"
},
"original": {
@ -313,28 +334,13 @@
"type": "github"
}
},
"nixos-flake": {
"locked": {
"lastModified": 1721140942,
"narHash": "sha256-iEqZGdnkG+Hm0jZhS59NJwEyB6z9caVnudWPGHZ/FAE=",
"owner": "srid",
"repo": "nixos-flake",
"rev": "5734c1d9a5fe0bc8e8beaf389ad6227392ca0108",
"type": "github"
},
"original": {
"owner": "srid",
"repo": "nixos-flake",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1724242322,
"narHash": "sha256-HMpK7hNjhEk4z5SFg5UtxEio9OWFocHdaQzCfW1pE7w=",
"lastModified": 1734202038,
"narHash": "sha256-LwcGIkORU8zfQ/8jAgptgPY8Zf9lGKB0vtNdQyEkaN8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "224042e9a3039291f22f4f2ded12af95a616cca0",
"rev": "bcba2fbf6963bf6bed3a749f9f4cf5bff4adb96d",
"type": "github"
},
"original": {
@ -344,50 +350,33 @@
"type": "github"
}
},
"nixpkgs-2205": {
"locked": {
"lastModified": 1685573264,
"narHash": "sha256-Zffu01pONhs/pqH07cjlF10NnMDLok8ix5Uk4rhOnZQ=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "380be19fbd2d9079f677978361792cb25e8a3635",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-22.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1722555339,
"narHash": "sha256-uFf2QeW7eAHlYXuDktm9c25OxOyCoUOQmh5SZ9amE5Q=",
"lastModified": 1733096140,
"narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/a5d394176e64ab29c852d03346c1fc9b0b7d33eb.tar.gz"
"url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz"
}
},
"root": {
"inputs": {
"agenix": "agenix",
"deploy-rs": "deploy-rs",
"disko": "disko",
"element-stickers": "element-stickers",
"element-themes": "element-themes",
"flake-parts": "flake-parts",
"fork": "fork",
"home-manager": "home-manager",
"keycloak-theme-pub-solar": "keycloak-theme-pub-solar",
"maunium-stickerpicker": "maunium-stickerpicker",
"nix-darwin": "nix-darwin",
"nixos-flake": "nixos-flake",
"nixpkgs": "nixpkgs",
"nixpkgs-2205": "nixpkgs-2205",
"simple-nixos-mailserver": "simple-nixos-mailserver",
"triton-vmtools": "triton-vmtools",
"unstable": "unstable"
}
},
@ -493,37 +482,13 @@
"type": "github"
}
},
"triton-vmtools": {
"inputs": {
"flake-utils": "flake-utils_3",
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"dir": "vmtools",
"lastModified": 1698443513,
"narHash": "sha256-wX2JIJ3JmJn6MAurdyjwZU+FZjLCwBArMrVSeeCb/ZU=",
"ref": "main",
"rev": "0d039dcf06afb8cbddd7ac54bae4d0d185f3e88e",
"revCount": 85,
"type": "git",
"url": "https://git.pub.solar/pub-solar/infra-vintage?dir=vmtools"
},
"original": {
"dir": "vmtools",
"ref": "main",
"type": "git",
"url": "https://git.pub.solar/pub-solar/infra-vintage?dir=vmtools"
}
},
"unstable": {
"locked": {
"lastModified": 1724224976,
"narHash": "sha256-Z/ELQhrSd7bMzTO8r7NZgi9g5emh+aRKoCdaAv5fiO0=",
"lastModified": 1734119587,
"narHash": "sha256-AKU6qqskl0yf2+JdRdD0cfxX4b9x3KKV5RqA6wijmPM=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "c374d94f1536013ca8e92341b540eba4c22f9c62",
"rev": "3566ab7246670a43abd2ffa913cc62dad9cdf7d5",
"type": "github"
},
"original": {

107
flake.nix
View file

@ -3,8 +3,7 @@
# Track channels with commits tested and built by hydra
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
unstable.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-2205.url = "github:nixos/nixpkgs/nixos-22.05";
fork.url = "github:teutat3s/nixpkgs/init-matrix-authentication-service-module";
nix-darwin.url = "github:lnl7/nix-darwin/master";
nix-darwin.inputs.nixpkgs.follows = "nixpkgs";
@ -13,11 +12,13 @@
home-manager.inputs.nixpkgs.follows = "nixpkgs";
flake-parts.url = "github:hercules-ci/flake-parts";
nixos-flake.url = "github:srid/nixos-flake";
deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs";
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs";
agenix.inputs.darwin.follows = "nix-darwin";
@ -26,9 +27,6 @@
keycloak-theme-pub-solar.url = "git+https://git.pub.solar/pub-solar/keycloak-theme?ref=main";
keycloak-theme-pub-solar.inputs.nixpkgs.follows = "nixpkgs";
triton-vmtools.url = "git+https://git.pub.solar/pub-solar/infra-vintage?ref=main&dir=vmtools";
triton-vmtools.inputs.nixpkgs.follows = "nixpkgs";
element-themes.url = "github:aaronraimist/element-themes/master";
element-themes.flake = false;
@ -53,7 +51,6 @@
];
imports = [
inputs.nixos-flake.flakeModule
./logins
./lib
./overlays
@ -65,6 +62,7 @@
system,
pkgs,
config,
lib,
...
}:
{
@ -77,6 +75,27 @@
unstable = import inputs.unstable { inherit system; };
master = import inputs.master { inherit system; };
};
checks =
let
nixos-lib = import (inputs.nixpkgs + "/nixos/lib") { };
testDir = builtins.attrNames (builtins.readDir ./tests);
testFiles = builtins.filter (n: builtins.match "^.*.nix$" n != null) testDir;
in
builtins.listToAttrs (
map (x: {
name = "test-${lib.strings.removeSuffix ".nix" x}";
value = nixos-lib.runTest (
import (./tests + "/${x}") {
inherit self;
inherit pkgs;
inherit lib;
inherit config;
}
);
}) testFiles
);
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
deploy-rs
@ -89,53 +108,55 @@
nvfetcher
shellcheck
shfmt
treefmt
inputs.unstable.legacyPackages.${system}.treefmt2
nixos-generators
inputs.nixpkgs-2205.legacyPackages.${system}.terraform
inputs.unstable.legacyPackages.${system}.opentofu
terraform-backend-git
terraform-ls
jq
];
};
devShells.ci = pkgs.mkShell { buildInputs = with pkgs; [ nodejs ]; };
};
flake =
let
username = "barkeeper";
in
{
inherit username;
flake = {
nixosModules = builtins.listToAttrs (
map (x: {
name = x;
value = import (./modules + "/${x}");
}) (builtins.attrNames (builtins.readDir ./modules))
);
nixosModules = builtins.listToAttrs (
map (x: {
name = x;
value = import (./modules + "/${x}");
}) (builtins.attrNames (builtins.readDir ./modules))
);
checks = builtins.mapAttrs (
system: deployLib: deployLib.deployChecks self.deploy
) inputs.deploy-rs.lib;
checks = builtins.mapAttrs (
system: deployLib: deployLib.deployChecks self.deploy
) inputs.deploy-rs.lib;
formatter."x86_64-linux" = inputs.unstable.legacyPackages."x86_64-linux".nixfmt-rfc-style;
formatter."x86_64-linux" = inputs.unstable.legacyPackages."x86_64-linux".nixfmt-rfc-style;
deploy.nodes = self.lib.deploy.mkDeployNodes self.nixosConfigurations {
nachtigall = {
hostname = "nachtigall.wg.pub.solar";
sshUser = username;
};
flora-6 = {
hostname = "flora-6.wg.pub.solar";
sshUser = username;
};
metronom = {
hostname = "metronom.wg.pub.solar";
sshUser = username;
};
tankstelle = {
hostname = "tankstelle.wg.pub.solar";
sshUser = username;
};
deploy.nodes = self.lib.deploy.mkDeployNodes self.nixosConfigurations {
nachtigall = {
hostname = "nachtigall.wg.pub.solar";
};
metronom = {
hostname = "metronom.wg.pub.solar";
};
tankstelle = {
hostname = "tankstelle.wg.pub.solar";
};
underground = {
hostname = "80.244.242.3";
};
trinkgenossin = {
hostname = "trinkgenossin.wg.pub.solar";
};
delite = {
hostname = "delite.wg.pub.solar";
};
blue-shell = {
hostname = "blue-shell.wg.pub.solar";
};
};
};
};
}

View file

@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
...
}:
{
boot.loader.grub.enable = true;
boot.kernelParams = [
"boot.shell_on_fail=1"
"ip=dhcp"
];
# This option defines the first version of NixOS you have installed on this particular machine,
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
#
# Most users should NEVER change this value after the initial install, for any reason,
# even if you've upgraded your system to a new NixOS release.
#
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
# to actually do that.
#
# This value being lower than the current NixOS release does NOT mean your system is
# out of date, out of support, or vulnerable.
#
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
# and migrated your data accordingly.
#
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
system.stateVersion = "24.05"; # Did you read the comment?
}

View file

@ -1,11 +1,13 @@
{ ... }:
{ flake, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
./configuration.nix
./triton-vmtools.nix
./disk-config.nix
./networking.nix
./wireguard.nix
#./backups.nix
];
}

View file

@ -0,0 +1,101 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/vdb";
content = {
type = "gpt";
partitions = {
bios = {
size = "1M";
type = "EF02"; # for grub MBR
};
boot = {
size = "1G";
type = "8300";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/boot";
mountOptions = [ "defaults" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "cryptroot";
extraOpenArgs = [ ];
# if you want to use the key for interactive login be sure there is no trailing newline
# for example use `echo -n "password" > /tmp/secret.key`
passwordFile = "/tmp/luks-password";
content = {
type = "lvm_pv";
vg = "vg0";
};
};
};
};
};
};
data = {
type = "disk";
device = "/dev/vdc";
content = {
type = "gpt";
partitions = {
luks = {
size = "100%";
content = {
type = "luks";
name = "cryptdata";
extraOpenArgs = [ ];
# if you want to use the key for interactive login be sure there is no trailing newline
# for example use `echo -n "password" > /tmp/secret.key`
passwordFile = "/tmp/luks-password";
content = {
type = "filesystem";
format = "xfs";
mountpoint = "/var/lib/garage/data";
mountOptions = [ "defaults" ];
};
};
};
};
};
};
};
lvm_vg = {
vg0 = {
type = "lvm_vg";
lvs = {
root = {
size = "100G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [ "defaults" ];
};
};
swap = {
size = "16G";
content = {
type = "swap";
};
};
metadata = {
size = "50G";
content = {
type = "filesystem";
format = "btrfs";
mountpoint = "/var/lib/garage/meta";
mountOptions = [ "defaults" ];
};
};
};
};
};
};
}

View file

@ -0,0 +1,27 @@
# 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 + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"sr_mod"
"virtio_blk"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -0,0 +1,26 @@
{
config,
pkgs,
flake,
...
}:
{
services.garage.settings.rpc_public_addr = "[2a03:4000:43:24e::1]:3901";
networking.hostName = "blue-shell";
networking.hostId = "00000005";
networking.useDHCP = false;
systemd.network.enable = true;
systemd.network.networks."10-wan" = {
matchConfig.Name = "ens3";
address = [
"194.13.83.205/22"
"2a03:4000:43:24e::1/64"
];
gateway = [
"194.13.80.1"
"fe80::1"
];
};
}

View file

@ -0,0 +1,51 @@
{
config,
pkgs,
flake,
...
}:
let
wireguardIPv4 = "10.7.6.7";
wireguardIPv6 = "fd00:fae:fae:fae:fae:7::";
in
{
networking.firewall.allowedUDPPorts = [ 51820 ];
age.secrets.wg-private-key.file = "${flake.self}/secrets/blue-shell-wg-private-key.age";
networking.wireguard.interfaces = {
wg-ssh = {
listenPort = 51820;
mtu = 1300;
ips = [
"${wireguardIPv4}/32"
"${wireguardIPv6}/96"
];
privateKeyFile = config.age.secrets.wg-private-key.path;
peers = flake.self.logins.wireguardDevices ++ [
{
# trinkgenossin.pub.solar
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
allowedIPs = [
"10.7.6.5/32"
"fd00:fae:fae:fae:fae:5::/96"
];
#endpoint = "85.215.152.22:51820";
endpoint = "[2a01:239:35d:f500::1]:51820";
persistentKeepalive = 15;
}
];
};
};
services.openssh.listenAddresses = [
{
addr = wireguardIPv4;
port = 22;
}
{
addr = "[${wireguardIPv6}]";
port = 22;
}
];
}

View file

@ -1,9 +1,35 @@
{ self, ... }:
{
self,
inputs,
config,
...
}:
{
flake = {
nixosConfigurations = {
nachtigall = self.nixos-flake.lib.mkLinuxSystem {
nixosModules = {
home-manager = {
imports = [
inputs.home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = {
flake = {
inherit self inputs config;
};
};
}
];
};
};
nixosConfigurations = {
nachtigall = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.nixosModules.home-manager
./nachtigall
@ -11,6 +37,7 @@
self.nixosModules.unlock-zfs-on-boot
self.nixosModules.core
self.nixosModules.docker
self.nixosModules.backups
self.nixosModules.nginx
self.nixosModules.collabora
@ -42,32 +69,20 @@
];
};
flora-6 = self.nixos-flake.lib.mkLinuxSystem {
imports = [
self.inputs.agenix.nixosModules.default
self.nixosModules.home-manager
./flora-6
self.nixosModules.overlays
self.nixosModules.core
self.nixosModules.keycloak
self.nixosModules.caddy
self.nixosModules.drone
self.nixosModules.forgejo-actions-runner
self.nixosModules.grafana
self.nixosModules.prometheus
self.nixosModules.loki
];
};
metronom = self.nixos-flake.lib.mkLinuxSystem {
imports = [
metronom = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.nixosModules.home-manager
./metronom
self.nixosModules.overlays
self.nixosModules.unlock-zfs-on-boot
self.nixosModules.core
self.nixosModules.backups
self.nixosModules.mail
self.nixosModules.prometheus-exporters
self.nixosModules.promtail
@ -76,17 +91,117 @@
];
};
tankstelle = self.nixos-flake.lib.mkLinuxSystem {
imports = [
tankstelle = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.nixosModules.home-manager
./tankstelle
self.nixosModules.overlays
self.nixosModules.core
self.nixosModules.backups
self.nixosModules.prometheus-exporters
self.nixosModules.promtail
];
};
trinkgenossin = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.nixosModules.home-manager
./trinkgenossin
self.nixosModules.backups
self.nixosModules.overlays
self.nixosModules.unlock-luks-on-boot
self.nixosModules.core
self.nixosModules.garage
self.nixosModules.nginx
# This module is already using options, and those options are used by the grafana module
self.nixosModules.keycloak
self.nixosModules.grafana
self.nixosModules.prometheus
self.nixosModules.loki
];
};
delite = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.inputs.disko.nixosModules.disko
self.nixosModules.home-manager
./delite
self.nixosModules.overlays
self.nixosModules.unlock-luks-on-boot
self.nixosModules.core
self.nixosModules.prometheus-exporters
self.nixosModules.promtail
self.nixosModules.garage
self.nixosModules.nginx
];
};
blue-shell = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.inputs.disko.nixosModules.disko
self.nixosModules.home-manager
./blue-shell
self.nixosModules.overlays
self.nixosModules.unlock-luks-on-boot
self.nixosModules.core
self.nixosModules.prometheus-exporters
self.nixosModules.promtail
self.nixosModules.garage
self.nixosModules.nginx
];
};
underground = self.inputs.nixpkgs.lib.nixosSystem {
specialArgs = {
flake = {
inherit self inputs config;
};
};
modules = [
self.inputs.agenix.nixosModules.default
self.nixosModules.home-manager
./underground
self.nixosModules.overlays
self.nixosModules.unlock-luks-on-boot
self.nixosModules.core
self.nixosModules.backups
self.nixosModules.keycloak
self.nixosModules.postgresql
self.nixosModules.matrix
self.nixosModules.matrix-irc
self.nixosModules.nginx
self.nixosModules.nginx-matrix
];
};
};
};
}

View file

@ -0,0 +1,33 @@
{
flake,
config,
pkgs,
...
}:
{
boot.loader.grub.enable = true;
boot.kernelParams = [
"boot.shell_on_fail=1"
"ip=5.255.119.132::5.255.119.1:255.255.255.0:delite::off"
];
# This option defines the first version of NixOS you have installed on this particular machine,
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
#
# Most users should NEVER change this value after the initial install, for any reason,
# even if you've upgraded your system to a new NixOS release.
#
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
# to actually do that.
#
# This value being lower than the current NixOS release does NOT mean your system is
# out of date, out of support, or vulnerable.
#
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
# and migrated your data accordingly.
#
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
system.stateVersion = "24.05"; # Did you read the comment?
}

13
hosts/delite/default.nix Normal file
View file

@ -0,0 +1,13 @@
{ flake, ... }:
{
imports = [
./hardware-configuration.nix
./configuration.nix
./disk-config.nix
./networking.nix
./wireguard.nix
#./backups.nix
];
}

View file

@ -0,0 +1,84 @@
{
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/vda";
content = {
type = "gpt";
partitions = {
bios = {
size = "1M";
type = "EF02"; # for grub MBR
};
boot = {
size = "1G";
type = "8300";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/boot";
mountOptions = [ "defaults" ];
};
};
luks = {
size = "100%";
content = {
type = "luks";
name = "cryptroot";
extraOpenArgs = [ ];
# if you want to use the key for interactive login be sure there is no trailing newline
# for example use `echo -n "password" > /tmp/secret.key`
passwordFile = "/tmp/luks-password";
content = {
type = "lvm_pv";
vg = "vg0";
};
};
};
};
};
};
};
lvm_vg = {
vg0 = {
type = "lvm_vg";
lvs = {
root = {
size = "40G";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [ "defaults" ];
};
};
swap = {
size = "8G";
content = {
type = "swap";
};
};
data = {
size = "800G";
content = {
type = "filesystem";
format = "xfs";
mountpoint = "/var/lib/garage/data";
mountOptions = [ "defaults" ];
};
};
metadata = {
size = "50G";
content = {
type = "filesystem";
format = "btrfs";
mountpoint = "/var/lib/garage/meta";
mountOptions = [ "defaults" ];
};
};
};
};
};
};
}

View file

@ -0,0 +1,26 @@
# 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 + "/profiles/qemu-guest.nix") ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"virtio_blk"
];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -0,0 +1,26 @@
{
config,
pkgs,
flake,
...
}:
{
services.garage.settings.rpc_public_addr = "[2a04:52c0:124:9d8c::2]:3901";
networking.hostName = "delite";
networking.hostId = "00000004";
networking.useDHCP = false;
systemd.network.enable = true;
systemd.network.networks."10-wan" = {
matchConfig.Name = "ens3";
address = [
"5.255.119.132/24"
"2a04:52c0:124:9d8c::2/48"
];
gateway = [
"5.255.119.1"
"2a04:52c0:124::1"
];
};
}

View file

@ -0,0 +1,51 @@
{
config,
pkgs,
flake,
...
}:
let
wireguardIPv4 = "10.7.6.6";
wireguardIPv6 = "fd00:fae:fae:fae:fae:6::";
in
{
networking.firewall.allowedUDPPorts = [ 51820 ];
age.secrets.wg-private-key.file = "${flake.self}/secrets/delite-wg-private-key.age";
networking.wireguard.interfaces = {
wg-ssh = {
listenPort = 51820;
mtu = 1300;
ips = [
"${wireguardIPv4}/32"
"${wireguardIPv6}/96"
];
privateKeyFile = config.age.secrets.wg-private-key.path;
peers = flake.self.logins.wireguardDevices ++ [
{
# trinkgenossin.pub.solar
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
allowedIPs = [
"10.7.6.5/32"
"fd00:fae:fae:fae:fae:5::/96"
];
#endpoint = "85.215.152.22:51820";
endpoint = "[2a01:239:35d:f500::1]:51820";
persistentKeepalive = 15;
}
];
};
};
services.openssh.listenAddresses = [
{
addr = wireguardIPv4;
port = 22;
}
{
addr = "[${wireguardIPv6}]";
port = 22;
}
];
}

View file

@ -1,72 +0,0 @@
{
config,
lib,
pkgs,
flake,
...
}:
let
psCfg = config.pub-solar;
in
{
config = {
# Override nix.conf for more agressive garbage collection
nix.extraOptions = lib.mkForce ''
experimental-features = flakes nix-command
min-free = 536870912
keep-outputs = false
keep-derivations = false
fallback = true
'';
# # #
# # # Triton host specific options
# # # DO NOT ALTER below this line, changes might render system unbootable
# # #
# Use the systemd-boot EFI boot loader.
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# Force getting the hostname from cloud-init
networking.hostName = lib.mkDefault "";
# We use cloud-init to configure networking, this option should fix
# systemd-networkd-wait-online timeouts
#systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
systemd.network.wait-online.ignoredInterfaces = [
"docker0"
"wg-ssh"
];
# List services that you want to enable:
services.cloud-init.enable = true;
services.cloud-init.ext4.enable = true;
services.cloud-init.network.enable = true;
# use the default NixOS cloud-init config, but add some SmartOS customization to it
environment.etc."cloud/cloud.cfg.d/90_smartos.cfg".text = ''
datasource_list: [ SmartOS ]
# Do not create the centos/ubuntu/debian user
users: [ ]
# mount second disk with label ephemeral0, gets formated by cloud-init
# this will fail to get added to /etc/fstab as it's read-only, but should
# mount at boot anyway
mounts:
- [ vdb, /data, auto, "defaults,nofail" ]
'';
# We manage the firewall with nix, too
# altough triton can also manage firewall rules via the triton fwrule subcommand
networking.firewall.enable = true;
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "22.05"; # Did you read the comment?
};
}

View file

@ -1,6 +0,0 @@
{ pkgs, flake, ... }:
{
environment.systemPackages = with pkgs; [
flake.inputs.triton-vmtools.packages.${pkgs.system}.default
];
}

View file

@ -1,13 +1,29 @@
{ flake, ... }:
{ config, flake, ... }:
{
age.secrets."restic-repo-droppie" = {
file = "${flake.self}/secrets/restic-repo-droppie.age";
age.secrets."restic-repo-storagebox-metronom" = {
file = "${flake.self}/secrets/restic-repo-storagebox-metronom.age";
mode = "400";
owner = "root";
};
age.secrets."restic-repo-storagebox" = {
file = "${flake.self}/secrets/restic-repo-storagebox.age";
age.secrets.restic-repo-garage-metronom = {
file = "${flake.self}/secrets/restic-repo-garage-metronom.age";
mode = "400";
owner = "root";
};
age.secrets.restic-repo-garage-metronom-env = {
file = "${flake.self}/secrets/restic-repo-garage-metronom-env.age";
mode = "400";
owner = "root";
};
pub-solar-os.backups.repos.storagebox = {
passwordFile = config.age.secrets."restic-repo-storagebox-metronom".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/metronom-backups";
};
pub-solar-os.backups.repos.garage = {
passwordFile = config.age.secrets."restic-repo-garage-metronom".path;
environmentFile = config.age.secrets."restic-repo-garage-metronom-env".path;
repository = "s3:https://buckets.pub.solar/metronom-backups";
};
}

View file

@ -23,6 +23,14 @@
pools = [ "root_pool" ];
};
# Declarative SSH private key
age.secrets."metronom-root-ssh-key" = {
file = "${flake.self}/secrets/metronom-root-ssh-key.age";
path = "/root/.ssh/id_ed25519";
mode = "400";
owner = "root";
};
# Declarative SSH private key
#age.secrets."metronom-root-ssh-key" = {
# file = "${flake.self}/secrets/metronom-root-ssh-key.age";

View file

@ -7,6 +7,6 @@
./networking.nix
./wireguard.nix
#./backups.nix
./backups.nix
];
}

View file

@ -18,16 +18,7 @@
"fd00:fae:fae:fae:fae:3::/96"
];
privateKeyFile = config.age.secrets.wg-private-key.path;
peers = flake.self.logins.admins.wireguardDevices ++ [
{
# flora-6.pub.solar
endpoint = "80.71.153.210:51820";
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
allowedIPs = [
"10.7.6.2/32"
"fd00:fae:fae:fae:fae:2::/96"
];
}
peers = flake.self.logins.wireguardDevices ++ [
{
# nachtigall.pub.solar
endpoint = "138.201.80.102:51820";
@ -37,6 +28,17 @@
"fd00:fae:fae:fae:fae:1::/96"
];
}
{
# trinkgenossin.pub.solar
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
allowedIPs = [
"10.7.6.5/32"
"fd00:fae:fae:fae:fae:5::/96"
];
#endpoint = "85.215.152.22:51820";
endpoint = "[2a01:239:35d:f500::1]:51820";
persistentKeepalive = 15;
}
];
};
};

View file

@ -1,13 +1,34 @@
{ flake, ... }:
{ config, flake, ... }:
{
age.secrets."restic-repo-droppie" = {
file = "${flake.self}/secrets/restic-repo-droppie.age";
mode = "400";
owner = "root";
};
age.secrets."restic-repo-storagebox" = {
file = "${flake.self}/secrets/restic-repo-storagebox.age";
age.secrets."restic-repo-storagebox-nachtigall" = {
file = "${flake.self}/secrets/restic-repo-storagebox-nachtigall.age";
mode = "400";
owner = "root";
};
age.secrets.restic-repo-garage-nachtigall = {
file = "${flake.self}/secrets/restic-repo-garage-nachtigall.age";
mode = "400";
owner = "root";
};
age.secrets.restic-repo-garage-nachtigall-env = {
file = "${flake.self}/secrets/restic-repo-garage-nachtigall-env.age";
mode = "400";
owner = "root";
};
pub-solar-os.backups.repos.storagebox = {
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
};
pub-solar-os.backups.repos.garage = {
passwordFile = config.age.secrets."restic-repo-garage-nachtigall".path;
environmentFile = config.age.secrets."restic-repo-garage-nachtigall-env".path;
repository = "s3:https://buckets.pub.solar/nachtigall-backups";
};
}

View file

@ -48,9 +48,77 @@
owner = "root";
};
pub-solar-os.auth.enable = true;
# keycloak
age.secrets.keycloak-database-password = {
file = "${flake.self}/secrets/keycloak-database-password.age";
mode = "600";
#owner = "keycloak";
};
nixpkgs.config.permittedInsecurePackages = [ "keycloak-23.0.6" ];
pub-solar-os.auth = {
enable = true;
database-password-file = config.age.secrets.keycloak-database-password.path;
};
# matrix-synapse
age.secrets."matrix-synapse-signing-key" = {
file = "${flake.self}/secrets/matrix-synapse-signing-key.age";
mode = "400";
owner = "matrix-synapse";
};
age.secrets."matrix-synapse-secret-config.yaml" = {
file = "${flake.self}/secrets/matrix-synapse-secret-config.yaml.age";
mode = "400";
owner = "matrix-synapse";
};
age.secrets."matrix-synapse-sliding-sync-secret" = {
file = "${flake.self}/secrets/matrix-synapse-sliding-sync-secret.age";
mode = "400";
owner = "matrix-synapse";
};
age.secrets."matrix-authentication-service-secret-config.yml" = {
file = "${flake.self}/secrets/matrix-authentication-service-secret-config.yml.age";
mode = "400";
owner = "matrix-authentication-service";
};
pub-solar-os.matrix = {
enable = true;
synapse = {
sliding-sync.enable = false;
signing_key_path = config.age.secrets."matrix-synapse-signing-key".path;
extra-config-files = [
config.age.secrets."matrix-synapse-secret-config.yaml".path
# The registration file is automatically generated after starting the
# appservice for the first time.
# cp /var/lib/mautrix-telegram/telegram-registration.yaml \
# /var/lib/matrix-synapse/
# chown matrix-synapse:matrix-synapse \
# /var/lib/matrix-synapse/telegram-registration.yaml
"/var/lib/matrix-synapse/telegram-registration.yaml"
];
app-service-config-files = [
"/var/lib/matrix-synapse/telegram-registration.yaml"
"/var/lib/matrix-appservice-irc/registration.yml"
# "/matrix-appservice-slack-registration.yaml"
# "/hookshot-registration.yml"
# "/matrix-mautrix-signal-registration.yaml"
# "/matrix-mautrix-telegram-registration.yaml"
];
};
matrix-authentication-service.extra-config-files = [
config.age.secrets."matrix-authentication-service-secret-config.yml".path
];
};
systemd.services.postgresql = {
after = [ "var-lib-postgresql.mount" ];
requisite = [ "var-lib-postgresql.mount" ];
};
# This value determines the NixOS release with which your system is to be
# compatible, in order to avoid breaking some software such as database

View file

@ -9,5 +9,12 @@
./networking.nix
./wireguard.nix
./backups.nix
"${flake.inputs.fork}/nixos/modules/services//matrix/matrix-authentication-service.nix"
"${flake.inputs.unstable}/nixos/modules/services/web-apps/mastodon.nix"
];
disabledModules = [
"services/matrix/matrix-authentication-service.nix "
"services/web-apps/mastodon.nix"
];
}

View file

@ -18,16 +18,7 @@
"fd00:fae:fae:fae:fae:1::/96"
];
privateKeyFile = config.age.secrets.wg-private-key.path;
peers = flake.self.logins.admins.wireguardDevices ++ [
{
# flora-6.pub.solar
endpoint = "80.71.153.210:51820";
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
allowedIPs = [
"10.7.6.2/32"
"fd00:fae:fae:fae:fae:2::/96"
];
}
peers = flake.self.logins.wireguardDevices ++ [
{
# tankstelle.pub.solar
endpoint = "80.244.242.5:51820";
@ -37,6 +28,17 @@
"fd00:fae:fae:fae:fae:4::/96"
];
}
{
# trinkgenossin.pub.solar
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
allowedIPs = [
"10.7.6.5/32"
"fd00:fae:fae:fae:fae:5::/96"
];
#endpoint = "85.215.152.22:51820";
endpoint = "[2a01:239:35d:f500::1]:51820";
persistentKeepalive = 15;
}
];
};
};

View file

@ -5,8 +5,8 @@
mode = "400";
owner = "root";
};
age.secrets."restic-repo-storagebox" = {
file = "${flake.self}/secrets/restic-repo-storagebox.age";
age.secrets."restic-repo-storagebox-tankstelle" = {
file = "${flake.self}/secrets/restic-repo-storagebox-tankstelle.age";
mode = "400";
owner = "root";
};

View file

@ -18,7 +18,7 @@
"fd00:fae:fae:fae:fae:4::/96"
];
privateKeyFile = config.age.secrets.wg-private-key.path;
peers = flake.self.logins.admins.wireguardDevices ++ [
peers = flake.self.logins.wireguardDevices ++ [
{
# nachtigall.pub.solar
endpoint = "138.201.80.102:51820";
@ -29,13 +29,15 @@
];
}
{
# flora-6.pub.solar
endpoint = "80.71.153.210:51820";
publicKey = "jtSR5G2P/nm9s8WrVc26Xc/SQLupRxyXE+5eIeqlsTU=";
# trinkgenossin.pub.solar
publicKey = "QWgHovHxtqiQhnHLouSWiT6GIoQDmuvnThYL5c/rvU4=";
allowedIPs = [
"10.7.6.2/32"
"fd00:fae:fae:fae:fae:2::/96"
"10.7.6.5/32"
"fd00:fae:fae:fae:fae:5::/96"
];
#endpoint = "85.215.152.22:51820";
endpoint = "[2a01:239:35d:f500::1]:51820";
persistentKeepalive = 15;
}
];
};

View file

@ -0,0 +1,35 @@
{
flake,
config,
lib,
pkgs,
...
}:
{
boot.loader.grub.enable = true;
boot.loader.grub.devices = [ "/dev/vda" ];
boot.kernelParams = [
"boot.shell_on_fail=1"
"ip=dhcp"
];
# This option defines the first version of NixOS you have installed on this particular machine,
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
#
# Most users should NEVER change this value after the initial install, for any reason,
# even if you've upgraded your system to a new NixOS release.
#
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
# to actually do that.
#
# This value being lower than the current NixOS release does NOT mean your system is
# out of date, out of support, or vulnerable.
#
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
# and migrated your data accordingly.
#
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
system.stateVersion = "24.05"; # Did you read the comment?
}

View file

@ -0,0 +1,12 @@
{ flake, ... }:
{
imports = [
./hardware-configuration.nix
./configuration.nix
./networking.nix
./wireguard.nix
#./backups.nix
];
}

View file

@ -8,45 +8,47 @@
modulesPath,
...
}:
{
imports = [ ];
boot.initrd.availableKernelModules = [
"ahci"
"ata_piix"
"uhci_hcd"
"virtio_pci"
"xhci_pci"
"sr_mod"
"virtio_blk"
"virtio_net"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ "kvm-amd" ];
boot.extraModulePackages = [ ];
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-uuid/52a1fd17-63d7-4d0a-b7ff-74aceaf6085a";
};
fileSystems."/" = {
device = "/dev/disk/by-label/nixos";
autoResize = true;
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "vfat";
};
fileSystems."/data" = {
device = "/dev/disk/by-label/ephemeral0";
fsType = "ext4";
options = [
"defaults"
"nofail"
];
};
swapDevices = [ ];
fileSystems."/var/lib/garage/data" = {
device = "/dev/disk/by-label/data";
fsType = "xfs";
};
networking.useDHCP = lib.mkDefault false;
networking.networkmanager.enable = lib.mkForce false;
fileSystems."/var/lib/garage/meta" = {
device = "/dev/disk/by-label/metadata";
fsType = "btrfs";
};
swapDevices = [ { device = "/dev/disk/by-label/swap"; } ];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,15 @@
{
config,
pkgs,
flake,
...
}:
{
services.garage.settings.rpc_public_addr = "[2a01:239:35d:f500::1]:3901";
networking.hostName = "trinkgenossin";
networking.hostId = "00000003";
networking.enableIPv6 = true;
networking.useDHCP = true;
}

View file

@ -4,21 +4,25 @@
flake,
...
}:
let
wireguardIPv4 = "10.7.6.5";
wireguardIPv6 = "fd00:fae:fae:fae:fae:5::";
in
{
networking.firewall.allowedUDPPorts = [ 51820 ];
age.secrets.wg-private-key.file = "${flake.self}/secrets/flora6-wg-private-key.age";
age.secrets.wg-private-key.file = "${flake.self}/secrets/trinkgenossin-wg-private-key.age";
networking.wireguard.interfaces = {
wg-ssh = {
listenPort = 51820;
mtu = 1300;
ips = [
"10.7.6.2/32"
"fd00:fae:fae:fae:fae:2::/96"
"${wireguardIPv4}/32"
"${wireguardIPv6}/96"
];
privateKeyFile = config.age.secrets.wg-private-key.path;
peers = flake.self.logins.admins.wireguardDevices ++ [
peers = flake.self.logins.wireguardDevices ++ [
{
# nachtigall.pub.solar
endpoint = "138.201.80.102:51820";
@ -47,17 +51,35 @@
"fd00:fae:fae:fae:fae:4::/96"
];
}
{
# delite.pub.solar
endpoint = "5.255.119.132:51820";
publicKey = "ZT2qGWgMPwHRUOZmTQHWCRX4m14YwOsiszjsA5bpc2k=";
allowedIPs = [
"10.7.6.6/32"
"fd00:fae:fae:fae:fae:6::/96"
];
}
{
# blue-shell.pub.solar
endpoint = "194.13.83.205:51820";
publicKey = "bcrIpWrKc1M+Hq4ds3aN1lTaKE26f2rvXhd+93QrzR8=";
allowedIPs = [
"10.7.6.7/32"
"fd00:fae:fae:fae:fae:7::/96"
];
}
];
};
};
services.openssh.listenAddresses = [
{
addr = "10.7.6.2";
addr = wireguardIPv4;
port = 22;
}
{
addr = "[fd00:fae:fae:fae:fae:2::]";
addr = "[${wireguardIPv6}]";
port = 22;
}
];

View file

@ -0,0 +1,72 @@
{
flake,
config,
pkgs,
...
}:
{
# Use GRUB2 as the boot loader.
boot.loader.grub = {
enable = true;
devices = [ "/dev/vda" ];
};
pub-solar-os.networking.domain = "test.pub.solar";
systemd.tmpfiles.rules = [ "f /tmp/dbf 1777 root root 10d password" ];
# keycloak
pub-solar-os.auth = {
enable = true;
database-password-file = "/tmp/dbf";
};
services.keycloak.database.createLocally = true;
# matrix-synapse
# test.pub.solar /.well-known is required for federation
services.nginx.virtualHosts."${config.pub-solar-os.networking.domain}" = {
default = true;
enableACME = true;
forceSSL = true;
};
age.secrets."staging-matrix-synapse-secret-config.yaml" = {
file = "${flake.self}/secrets/staging-matrix-synapse-secret-config.yaml.age";
mode = "400";
owner = "matrix-synapse";
};
age.secrets."staging-matrix-authentication-service-secret-config.yml" = {
file = "${flake.self}/secrets/staging-matrix-authentication-service-secret-config.yml.age";
mode = "400";
owner = "matrix-authentication-service";
};
pub-solar-os.matrix = {
enable = true;
synapse = {
extra-config-files = [
config.age.secrets."staging-matrix-synapse-secret-config.yaml".path
# The registration file is automatically generated after starting the
# appservice for the first time.
# cp /var/lib/mautrix-telegram/telegram-registration.yaml \
# /var/lib/matrix-synapse/
# chown matrix-synapse:matrix-synapse \
# /var/lib/matrix-synapse/telegram-registration.yaml
#"/var/lib/matrix-synapse/telegram-registration.yaml"
];
app-service-config-files = [
"/var/lib/matrix-appservice-irc/registration.yml"
#"/var/lib/matrix-synapse/telegram-registration.yaml"
];
};
matrix-authentication-service.extra-config-files = [
config.age.secrets."staging-matrix-authentication-service-secret-config.yml".path
];
};
services.openssh.openFirewall = true;
system.stateVersion = "24.05";
}

View file

@ -0,0 +1,16 @@
{ flake, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
./configuration.nix
./networking.nix
"${flake.inputs.fork}/nixos/modules/services//matrix/matrix-authentication-service.nix"
];
disabledModules = [
"services/matrix/matrix-authentication-service.nix "
];
}

View file

@ -0,0 +1,47 @@
# 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 + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [
"ahci"
"xhci_pci"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-label/cryptroot";
};
fileSystems."/" = {
device = "/dev/disk/by-label/root";
fsType = "ext4";
};
fileSystems."/boot" = {
device = "/dev/disk/by-label/boot";
fsType = "ext4";
};
swapDevices = [
{ device = "/dev/disk/by-label/swap"; }
];
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View file

@ -0,0 +1,30 @@
{
config,
pkgs,
flake,
...
}:
{
networking.hostName = "underground";
networking = {
defaultGateway = {
address = "80.244.242.1";
interface = "enp1s0";
};
nameservers = [
"95.129.51.51"
"80.244.244.244"
];
interfaces.enp1s0 = {
useDHCP = false;
ipv4.addresses = [
{
address = "80.244.242.3";
prefixLength = 29;
}
];
};
};
}

View file

@ -38,6 +38,14 @@
"fd00:fae:fae:fae:fae:200::/96"
];
}
{
# chocolatebar
publicKey = "AS9w0zDUFLcH6IiF6T1vsyZPWPJ3p5fKsjIsM2AoZz8=";
allowedIPs = [
"10.7.6.205/32"
"fd00:fae:fae:fae:fae:205::/96"
];
}
];
};
@ -63,6 +71,7 @@
teutat3s = {
sshPubKeys = {
teutat3s-1 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFro/k4Mgqyh8yV/7Zwjc0dv60ZM7bROBU9JNd99P/4co6fxPt1pJiU/pEz2Dax/HODxgcO+jFZfvPEuLMCeAl0= YubiKey #10593996 PIV Slot 9a";
teutat3s-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHcU6KPy4b1MQXd6EJhcYwbJu7E+0IrBZF/IP6T7gbMf teutat3s@dumpyourvms";
};
secretEncryptionKeys = {

View file

@ -6,19 +6,16 @@ in
{
flake = {
logins = {
admins =
lib.lists.foldl
(logins: adminConfig: {
sshPubKeys = logins.sshPubKeys ++ (lib.attrsets.attrValues adminConfig.sshPubKeys);
wireguardDevices =
logins.wireguardDevices
++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else [ ]);
})
{
sshPubKeys = [ ];
wireguardDevices = [ ];
}
(lib.attrsets.attrValues admins);
admins = admins;
wireguardDevices = lib.lists.foldl (
wireguardDevices: adminConfig:
wireguardDevices ++ (if adminConfig ? "wireguardDevices" then adminConfig.wireguardDevices else [ ])
) [ ] (lib.attrsets.attrValues admins);
sshPubKeys = lib.lists.foldl (
sshPubKeys: adminConfig:
sshPubKeys
++ (if adminConfig ? "sshPubKeys" then lib.attrsets.attrValues adminConfig.sshPubKeys else [ ])
) [ ] (lib.attrsets.attrValues admins);
robots.sshPubKeys = lib.attrsets.attrValues robots;
};
};

View file

@ -1,7 +1,8 @@
{
# Used for restic backups to droppie, a server run by @b12f
"root@droppie" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZQSephFJU0NMbVbhwvVJ2/m6jcPYo1IsWCsoarqKin root@droppie";
"root@droppie" =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBZQSephFJU0NMbVbhwvVJ2/m6jcPYo1IsWCsoarqKin root@droppie";
# robot user on flora-6
"hakkonaut@flora-6" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGP5MvCwNRtCcP1pSDrn0XZTNlpOqYnjHDm9/OI4hECW hakkonaut@flora-6";
"hakkonaut" =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGP5MvCwNRtCcP1pSDrn0XZTNlpOqYnjHDm9/OI4hECW hakkonaut";
}

292
modules/backups/default.nix Normal file
View file

@ -0,0 +1,292 @@
{
flake,
config,
lib,
pkgs,
...
}:
let
utils = import "${flake.inputs.nixpkgs}/nixos/lib/utils.nix" {
inherit lib;
inherit config;
inherit pkgs;
};
# Type for a valid systemd unit option. Needed for correctly passing "timerConfig" to "systemd.timers"
inherit (utils.systemdUtils.unitOptions) unitOption;
inherit (lib)
literalExpression
mkOption
mkPackageOption
types
;
in
{
options.pub-solar-os.backups = {
repos = mkOption {
description = ''
Configuration of Restic repositories.
'';
type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = {
passwordFile = mkOption {
type = types.str;
description = ''
Read the repository password from a file.
'';
example = "/etc/nixos/restic-password";
};
environmentFile = mkOption {
type = with types; nullOr str;
default = null;
description = ''
Read repository secrets as environment variables from a file.
'';
example = "/etc/nixos/restic-env";
};
repository = mkOption {
type = with types; nullOr str;
default = null;
description = ''
repository to backup to.
'';
example = "sftp:backup@192.168.1.100:/backups/${name}";
};
};
}
)
);
default = { };
example = {
remotebackup = {
repository = "sftp:backup@host:/backups/home";
passwordFile = "/etc/nixos/secrets/restic-password";
environmentFile = "/etc/nixos/secrets/restic-env";
};
};
};
restic = mkOption {
description = ''
Periodic backups to create with Restic.
'';
type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = {
paths = mkOption {
# This is nullable for legacy reasons only. We should consider making it a pure listOf
# after some time has passed since this comment was added.
type = types.nullOr (types.listOf types.str);
default = [ ];
description = ''
Which paths to backup, in addition to ones specified via
`dynamicFilesFrom`. If null or an empty array and
`dynamicFilesFrom` is also null, no backup command will be run.
This can be used to create a prune-only job.
'';
example = [
"/var/lib/postgresql"
"/home/user/backup"
];
};
exclude = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Patterns to exclude when backing up. See
https://restic.readthedocs.io/en/latest/040_backup.html#excluding-files for
details on syntax.
'';
example = [
"/var/cache"
"/home/*/.cache"
".git"
];
};
timerConfig = mkOption {
type = types.nullOr (types.attrsOf unitOption);
default = {
OnCalendar = "daily";
Persistent = true;
};
description = ''
When to run the backup. See {manpage}`systemd.timer(5)` for
details. If null no timer is created and the backup will only
run when explicitly started.
'';
example = {
OnCalendar = "00:05";
RandomizedDelaySec = "5h";
Persistent = true;
};
};
user = mkOption {
type = types.str;
default = "root";
description = ''
As which user the backup should run.
'';
example = "postgresql";
};
extraBackupArgs = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Extra arguments passed to restic backup.
'';
example = [ "--exclude-file=/etc/nixos/restic-ignore" ];
};
extraOptions = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Extra extended options to be passed to the restic --option flag.
'';
example = [ "sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'" ];
};
initialize = mkOption {
type = types.bool;
default = false;
description = ''
Create the repository if it doesn't exist.
'';
};
pruneOpts = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
A list of options (--keep-\* et al.) for 'restic forget
--prune', to automatically prune old snapshots. The
'forget' command is run *after* the 'backup' command, so
keep that in mind when constructing the --keep-\* options.
'';
example = [
"--keep-daily 7"
"--keep-weekly 5"
"--keep-monthly 12"
"--keep-yearly 75"
];
};
runCheck = mkOption {
type = types.bool;
default = (builtins.length config.pub-solar-os.backups.restic.${name}.checkOpts > 0);
defaultText = literalExpression ''builtins.length config.services.backups.${name}.checkOpts > 0'';
description = "Whether to run the `check` command with the provided `checkOpts` options.";
example = true;
};
checkOpts = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
A list of options for 'restic check'.
'';
example = [ "--with-cache" ];
};
dynamicFilesFrom = mkOption {
type = with types; nullOr str;
default = null;
description = ''
A script that produces a list of files to back up. The
results of this command are given to the '--files-from'
option. The result is merged with paths specified via `paths`.
'';
example = "find /home/matt/git -type d -name .git";
};
backupPrepareCommand = mkOption {
type = with types; nullOr str;
default = null;
description = ''
A script that must run before starting the backup process.
'';
};
backupCleanupCommand = mkOption {
type = with types; nullOr str;
default = null;
description = ''
A script that must run after finishing the backup process.
'';
};
package = mkPackageOption pkgs "restic" { };
createWrapper = lib.mkOption {
type = lib.types.bool;
default = true;
description = ''
Whether to generate and add a script to the system path, that has the same environment variables set
as the systemd service. This can be used to e.g. mount snapshots or perform other opterations, without
having to manually specify most options.
'';
};
};
}
)
);
default = { };
example = {
localbackup = {
paths = [ "/home" ];
exclude = [ "/home/*/.cache" ];
initialize = true;
};
remotebackup = {
paths = [ "/home" ];
extraOptions = [
"sftp.command='ssh backup@host -i /etc/nixos/secrets/backup-private-key -s sftp'"
];
timerConfig = {
OnCalendar = "00:05";
RandomizedDelaySec = "5h";
};
};
};
};
};
config = {
services.restic.backups =
let
repos = config.pub-solar-os.backups.repos;
restic = config.pub-solar-os.backups.restic;
repoNames = builtins.attrNames repos;
backupNames = builtins.attrNames restic;
createBackups =
backupName:
map (repoName: {
name = "${backupName}-${repoName}";
value = repos."${repoName}" // restic."${backupName}";
}) repoNames;
in
builtins.listToAttrs (lib.lists.flatten (map createBackups backupNames));
# Used for pub-solar-os.backups.repos.storagebox
programs.ssh.knownHosts = {
"u377325.your-storagebox.de".publicKey =
"ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5EB5p/5Hp3hGW1oHok+PIOH9Pbn7cnUiGmUEBrCVjnAw+HrKyN8bYVV0dIGllswYXwkG/+bgiBlE6IVIBAq+JwVWu1Sss3KarHY3OvFJUXZoZyRRg/Gc/+LRCE7lyKpwWQ70dbelGRyyJFH36eNv6ySXoUYtGkwlU5IVaHPApOxe4LHPZa/qhSRbPo2hwoh0orCtgejRebNtW5nlx00DNFgsvn8Svz2cIYLxsPVzKgUxs8Zxsxgn+Q/UvR7uq4AbAhyBMLxv7DjJ1pc7PJocuTno2Rw9uMZi1gkjbnmiOh6TTXIEWbnroyIhwc8555uto9melEUmWNQ+C+PwAK+MPw==";
"[u377325.your-storagebox.de]:23".publicKey =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIICf9svRenC/PLKIL9nk6K/pxQgoiFC41wTNvoIncOxs";
};
};
}

View file

@ -54,9 +54,5 @@
};
time.timeZone = "Etc/UTC";
home-manager.users.${config.pub-solar-os.authentication.username} = {
home.stateVersion = "23.05";
};
};
}

View file

@ -31,13 +31,17 @@
networking.hosts = {
"10.7.6.1" = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
"10.7.6.2" = [ "flora-6.wg.${config.pub-solar-os.networking.domain}" ];
"10.7.6.3" = [ "metronom.wg.${config.pub-solar-os.networking.domain}" ];
"10.7.6.4" = [ "tankstelle.wg.${config.pub-solar-os.networking.domain}" ];
"10.7.6.5" = [ "trinkgenossin.wg.${config.pub-solar-os.networking.domain}" ];
"10.7.6.6" = [ "delite.wg.${config.pub-solar-os.networking.domain}" ];
"10.7.6.7" = [ "blue-shell.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:1::" = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:2::" = [ "flora-6.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:3::" = [ "metronom.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:4::" = [ "tankstelle.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:5::" = [ "trinkgenossin.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:6::" = [ "delite.wg.${config.pub-solar-os.networking.domain}" ];
"fd00:fae:fae:fae:fae:7::" = [ "blue-shell.wg.${config.pub-solar-os.networking.domain}" ];
};
services.openssh = {

View file

@ -6,7 +6,21 @@
...
}:
{
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ ];
nixpkgs.config = lib.mkDefault {
allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ ];
permittedInsecurePackages = [ "olm-3.2.16" ];
};
system.activationScripts.diff-closures = {
text = ''
if [[ -e /run/current-system ]]; then
${config.nix.package}/bin/nix store diff-closures \
/run/current-system "$systemConfig" \
--extra-experimental-features nix-command
fi
'';
supportsDryActivation = true;
};
nix = {
# Use default version alias for nix package

View file

@ -1,19 +1,33 @@
{ flake, config, ... }:
{ flake, lib, ... }:
{
home-manager.users.${config.pub-solar-os.authentication.username} = {
programs.git.enable = true;
programs.starship.enable = true;
programs.bash.enable = true;
programs.neovim = {
enable = true;
vimAlias = true;
viAlias = true;
defaultEditor = true;
# configure = {
# packages.myVimPackages = with pkgs.vimPlugins; {
# start = [vim-nix vim-surrund rainbow];
# };
# };
};
};
home-manager.users = (
lib.attrsets.foldlAttrs (
acc: name: value:
acc
// {
${name} = {
programs.git.enable = true;
programs.starship.enable = true;
programs.bash = {
enable = true;
historyControl = [
"ignoredups"
"ignorespace"
];
};
programs.neovim = {
enable = true;
vimAlias = true;
viAlias = true;
defaultEditor = true;
# configure = {
# packages.myVimPackages = with pkgs.vimPlugins; {
# start = [vim-nix vim-surrund rainbow];
# };
# };
};
};
}
) { } flake.self.logins.admins
);
}

View file

@ -11,18 +11,6 @@
inherit (lib) mkOption types;
in
{
username = mkOption {
description = "Username for the adminstrative user";
type = types.str;
default = flake.self.username;
};
sshPubKeys = mkOption {
description = "SSH Keys that should have administrative root access";
type = types.listOf types.str;
default = flake.self.logins.admins.sshPubKeys;
};
root.initialHashedPassword = mkOption {
description = "Hashed password of the root account";
type = types.str;
@ -43,36 +31,60 @@
};
config = {
users.users.${config.pub-solar-os.authentication.username} = {
name = config.pub-solar-os.authentication.username;
group = config.pub-solar-os.authentication.username;
extraGroups = [
"wheel"
"docker"
];
isNormalUser = true;
openssh.authorizedKeys.keys = config.pub-solar-os.authentication.sshPubKeys;
};
users.groups.${config.pub-solar-os.authentication.username} = { };
users.users =
(lib.attrsets.foldlAttrs (
acc: name: value:
acc
// {
${name} = {
name = name;
group = name;
extraGroups = [
"wheel"
"docker"
];
isNormalUser = true;
openssh.authorizedKeys.keys = lib.attrsets.attrValues value.sshPubKeys;
};
}
) { } flake.self.logins.admins)
// {
# TODO: Remove when we stop locking ourselves out.
root.openssh.authorizedKeys.keys = flake.self.logins.sshPubKeys;
root.initialHashedPassword = config.pub-solar-os.authentication.root.initialHashedPassword;
# TODO: Remove when we stop locking ourselves out.
users.users.root.openssh.authorizedKeys.keys = config.pub-solar-os.authentication.sshPubKeys;
${config.pub-solar-os.authentication.robot.username} = {
description = "CI and automation user";
home = "/home/${config.pub-solar-os.authentication.robot.username}";
createHome = true;
useDefaultShell = true;
uid = 998;
group = "${config.pub-solar-os.authentication.robot.username}";
isSystemUser = true;
openssh.authorizedKeys.keys = config.pub-solar-os.authentication.robot.sshPubKeys;
};
};
users.users.${config.pub-solar-os.authentication.robot.username} = {
description = "CI and automation user";
home = "/home/${config.pub-solar-os.authentication.robot.username}";
createHome = true;
useDefaultShell = true;
uid = 998;
group = "${config.pub-solar-os.authentication.robot.username}";
isSystemUser = true;
openssh.authorizedKeys.keys = config.pub-solar-os.authentication.robot.sshPubKeys;
};
home-manager.users = (
lib.attrsets.foldlAttrs (
acc: name: value:
acc
// {
${name} = {
home.stateVersion = "23.05";
};
}
) { } flake.self.logins.admins
);
users.groups.${config.pub-solar-os.authentication.robot.username} = { };
users.users.root.initialHashedPassword =
config.pub-solar-os.authentication.root.initialHashedPassword;
users.groups =
(lib.attrsets.foldlAttrs (
acc: name: value:
acc // { "${name}" = { }; }
) { } flake.self.logins.admins)
// {
${config.pub-solar-os.authentication.robot.username} = { };
};
security.sudo.wheelNeedsPassword = false;
};

View file

@ -18,7 +18,7 @@
min-port = 49000;
max-port = 50000;
use-auth-secret = true;
static-auth-secret-file = "/run/agenix/coturn-static-auth-secret";
static-auth-secret-file = config.age.secrets."coturn-static-auth-secret".path;
realm = "turn.${config.pub-solar-os.networking.domain}";
cert = "${config.security.acme.certs.${realm}.directory}/full.pem";
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";

View file

@ -1,114 +0,0 @@
{
config,
lib,
pkgs,
flake,
...
}:
{
age.secrets.drone-secrets = {
file = "${flake.self}/secrets/drone-secrets.age";
mode = "600";
owner = "drone";
};
age.secrets.drone-db-secrets = {
file = "${flake.self}/secrets/drone-db-secrets.age";
mode = "600";
owner = "drone";
};
users.users.drone = {
description = "Drone Service";
home = "/var/lib/drone";
useDefaultShell = true;
uid = 994;
group = "drone";
isSystemUser = true;
};
users.groups.drone = { };
systemd.tmpfiles.rules = [ "d '/var/lib/drone-db' 0750 drone drone - -" ];
services.caddy.virtualHosts."ci.${config.pub-solar-os.networking.domain}" = {
logFormat = lib.mkForce ''
output discard
'';
extraConfig = ''
reverse_proxy :4000
'';
};
systemd.services."docker-network-drone" =
let
docker = config.virtualisation.oci-containers.backend;
dockerBin = "${pkgs.${docker}}/bin/${docker}";
in
{
serviceConfig.Type = "oneshot";
before = [ "docker-drone-server.service" ];
script = ''
${dockerBin} network inspect drone-net >/dev/null 2>&1 || ${dockerBin} network create drone-net --subnet 172.20.0.0/24
'';
};
virtualisation = {
docker = {
enable = true; # sadly podman is not supported rightnow
extraOptions = ''
--data-root /data/docker
'';
};
oci-containers = {
backend = "docker";
containers."drone-db" = {
image = "postgres:14";
autoStart = true;
user = "994";
volumes = [ "/var/lib/drone-db:/var/lib/postgresql/data" ];
extraOptions = [ "--network=drone-net" ];
environmentFiles = [ config.age.secrets.drone-db-secrets.path ];
};
containers."drone-server" = {
image = "drone/drone:2";
autoStart = true;
user = "994";
ports = [ "127.0.0.1:4000:80" ];
dependsOn = [ "drone-db" ];
extraOptions = [
"--network=drone-net"
"--pull=always"
"--add-host=nachtigall.${config.pub-solar-os.networking.domain}:10.7.6.1"
];
environment = {
DRONE_GITEA_SERVER = "https://git.${config.pub-solar-os.networking.domain}";
DRONE_SERVER_HOST = "ci.${config.pub-solar-os.networking.domain}";
DRONE_SERVER_PROTO = "https";
DRONE_DATABASE_DRIVER = "postgres";
};
environmentFiles = [ config.age.secrets.drone-secrets.path ];
};
containers."drone-docker-runner" = {
image = "drone/drone-runner-docker:1";
autoStart = true;
# needs to run as root
#user = "994";
volumes = [ "/var/run/docker.sock:/var/run/docker.sock" ];
dependsOn = [ "drone-db" ];
extraOptions = [
"--network=drone-net"
"--pull=always"
"--add-host=nachtigall.${config.pub-solar-os.networking.domain}:10.7.6.1"
];
environment = {
DRONE_RPC_HOST = "ci.${config.pub-solar-os.networking.domain}";
DRONE_RPC_PROTO = "https";
DRONE_RUNNER_CAPACITY = "2";
DRONE_RUNNER_NAME = "flora-6-docker-runner";
};
environmentFiles = [ config.age.secrets.drone-secrets.path ];
};
};
};
}

View file

@ -1,67 +0,0 @@
{
config,
lib,
pkgs,
flake,
...
}:
{
age.secrets.forgejo-actions-runner-token = {
file = "${flake.self}/secrets/forgejo-actions-runner-token.age";
mode = "440";
};
# Trust docker bridge interface traffic
# Needed for the docker runner to communicate with the act_runner cache
networking.firewall.trustedInterfaces = [ "br-+" ];
users.users.gitea-runner = {
home = "/var/lib/gitea-runner/flora-6";
useDefaultShell = true;
group = "gitea-runner";
isSystemUser = true;
};
users.groups.gitea-runner = { };
systemd.services."gitea-runner-flora\\x2d6".serviceConfig = {
DynamicUser = lib.mkForce false;
};
systemd.tmpfiles.rules = [
"d '/data/gitea-actions-runner' 0750 gitea-runner gitea-runner - -"
"d '/var/lib/gitea-runner' 0750 gitea-runner gitea-runner - -"
];
# forgejo actions runner
# https://forgejo.org/docs/latest/admin/actions/
# https://docs.gitea.com/usage/actions/quickstart
services.gitea-actions-runner = {
package = pkgs.forgejo-runner;
instances."flora-6" = {
enable = true;
name = config.networking.hostName;
url = "https://git.pub.solar";
tokenFile = config.age.secrets.forgejo-actions-runner-token.path;
settings = {
cache = {
enabled = true;
dir = "/data/gitea-actions-runner/actcache";
host = "";
port = 0;
external_server = "";
};
};
labels = [
# provide a debian 12 bookworm base with Node.js for actions
"debian-latest:docker://git.pub.solar/pub-solar/actions-base-image:20-bookworm"
# fake the ubuntu name, commonly used in actions examples
"ubuntu-latest:docker://git.pub.solar/pub-solar/actions-base-image:20-bookworm"
# alpine with Node.js
"alpine-latest:docker://node:20-alpine"
# nix flakes enabled image with Node.js
"nix-flakes:docker://git.pub.solar/pub-solar/nix-flakes-node:latest"
];
};
};
}

View file

@ -141,6 +141,12 @@
LOGIN_REMEMBER_DAYS = 365;
};
# See https://docs.gitea.com/administration/config-cheat-sheet#migrations-migrations
migrations = {
# This allows migrations from the same forgejo instance
ALLOW_LOCALNETWORKS = true;
};
# https://forgejo.org/docs/next/admin/config-cheat-sheet/#indexer-indexer
indexer = {
REPO_INDEXER_ENABLED = true;
@ -182,7 +188,7 @@
OnCalendar = "*-*-* 00:00:00 Etc/UTC";
};
initialize = true;
passwordFile = config.age.secrets."restic-repo-storagebox".path;
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d gitea > /tmp/forgejo-backup.sql

142
modules/garage/default.nix Normal file
View file

@ -0,0 +1,142 @@
{
config,
lib,
pkgs,
flake,
...
}:
{
age.secrets."garage-rpc-secret" = {
file = "${flake.self}/secrets/garage-rpc-secret.age";
mode = "400";
};
age.secrets."garage-admin-token" = {
file = "${flake.self}/secrets/garage-admin-token.age";
mode = "400";
};
age.secrets."acme-namecheap-env" = {
file = "${flake.self}/secrets/acme-namecheap-env.age";
mode = "400";
};
networking.firewall.allowedTCPPorts = [
3900
3901
3902
];
networking.firewall.interfaces.wg-ssh.allowedTCPPorts = [ 3903 ];
security.acme = {
defaults = {
# LEGO_DISABLE_CNAME_SUPPORT=true set here to fix issues with CNAME
# detection, as we use wildcard DNS for garage
environmentFile = config.age.secrets.acme-namecheap-env.path;
};
certs = {
# Wildcard certificate gets created automatically
"buckets.${config.pub-solar-os.networking.domain}" = {
# disable http challenge
webroot = null;
# enable dns challenge
dnsProvider = "namecheap";
};
# Wildcard certificate gets created automatically
"web.${config.pub-solar-os.networking.domain}" = {
# disable http challenge
webroot = null;
# enable dns challenge
dnsProvider = "namecheap";
};
};
};
services.nginx = {
upstreams.s3_backend.servers = {
"[::1]:3900" = { };
};
upstreams.web_backend.servers = {
"[::1]:3902" = { };
};
virtualHosts."buckets.${config.pub-solar-os.networking.domain}" = {
serverAliases = [ "*.buckets.${config.pub-solar-os.networking.domain}" ];
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://s3_backend";
extraConfig = ''
client_max_body_size 64m;
proxy_max_temp_file_size 0;
'';
};
};
virtualHosts."web.${config.pub-solar-os.networking.domain}" = {
serverAliases = [ "*.web.${config.pub-solar-os.networking.domain}" ];
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://web_backend";
};
};
};
services.garage = {
enable = true;
package = pkgs.garage_1_0_1;
settings = {
data_dir = "/var/lib/garage/data";
metadata_dir = "/var/lib/garage/meta";
db_engine = "lmdb";
replication_factor = 3;
compression_level = 2;
rpc_bind_addr = "[::]:3901";
s3_api = {
s3_region = "eu-central";
api_bind_addr = "[::]:3900";
root_domain = ".buckets.${config.pub-solar-os.networking.domain}";
};
s3_web = {
bind_addr = "[::]:3902";
root_domain = ".web.${config.pub-solar-os.networking.domain}";
index = "index.html";
};
admin = {
api_bind_addr = "[::]:3903";
};
};
};
users.users.garage = {
isSystemUser = true;
home = "/var/lib/garage";
group = "garage";
};
users.groups.garage = { };
# Adapted from https://git.clan.lol/clan/clan-core/src/commit/23a9e35c665ff531fe1193dcc47056432fbbeacf/clanModules/garage/default.nix
# Disabled DynamicUser https://github.com/NixOS/nixpkgs/blob/nixos-24.05/nixos/modules/services/web-servers/garage.nix
# for mounts + permissions to work
systemd.services.garage = {
serviceConfig = {
user = "garage";
group = "garage";
DynamicUser = false;
LoadCredential = [
"rpc_secret_path:${config.age.secrets.garage-rpc-secret.path}"
"admin_token_path:${config.age.secrets.garage-admin-token.path}"
];
Environment = [
"GARAGE_ALLOW_WORLD_READABLE_SECRETS=true"
"GARAGE_RPC_SECRET_FILE=%d/rpc_secret_path"
"GARAGE_ADMIN_TOKEN_FILE=%d/admin_token_path"
];
};
};
}

View file

@ -33,15 +33,18 @@
group = "grafana";
user = "grafana";
};
"grafana-dashboards/grafana-garage-dashboard-prometheus.json" = {
source = ./grafana-dashboards/grafana-garage-dashboard-prometheus.json;
group = "grafana";
user = "grafana";
};
};
services.caddy.virtualHosts."grafana.${config.pub-solar-os.networking.domain}" = {
logFormat = lib.mkForce ''
output discard
'';
extraConfig = ''
reverse_proxy :${toString config.services.grafana.settings.server.http_port}
'';
services.nginx.virtualHosts."grafana.${config.pub-solar-os.networking.domain}" = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass =
"http://127.0.0.1:${toString config.services.grafana.settings.server.http_port}";
};
services.grafana = {
@ -64,7 +67,7 @@
password = "\$__file{${config.age.secrets.grafana-smtp-password.path}}";
from_address = "no-reply@pub.solar";
from_name = "grafana.pub.solar";
ehlo_identity = "flora-6.pub.solar";
ehlo_identity = "grafana.pub.solar";
};
security = {
admin_email = "crew@pub.solar";

File diff suppressed because it is too large Load diff

View file

@ -6,23 +6,22 @@
...
}:
{
options.pub-solar-os.auth = {
enable = lib.mkEnableOption "Enable keycloak to run on the node";
options.pub-solar-os.auth = with lib; {
enable = mkEnableOption "Enable keycloak to run on the node";
realm = lib.mkOption {
realm = mkOption {
description = "Name of the realm";
type = lib.types.str;
type = types.str;
default = config.pub-solar-os.networking.domain;
};
database-password-file = mkOption {
description = "Database password file path";
type = types.str;
};
};
config = lib.mkIf config.pub-solar-os.auth.enable {
age.secrets.keycloak-database-password = {
file = "${flake.self}/secrets/keycloak-database-password.age";
mode = "600";
#owner = "keycloak";
};
services.nginx.virtualHosts."auth.${config.pub-solar-os.networking.domain}" = {
enableACME = true;
forceSSL = true;
@ -46,7 +45,7 @@
# keycloak
services.keycloak = {
enable = true;
database.passwordFile = config.age.secrets.keycloak-database-password.path;
database.passwordFile = config.pub-solar-os.auth.database-password-file;
settings = {
hostname = "auth.${config.pub-solar-os.networking.domain}";
http-host = "127.0.0.1";
@ -59,14 +58,12 @@
};
};
services.restic.backups.keycloak-storagebox = {
pub-solar-os.backups.restic.keycloak = {
paths = [ "/tmp/keycloak-backup.sql" ];
timerConfig = {
OnCalendar = "*-*-* 03:00:00 Etc/UTC";
};
initialize = true;
passwordFile = config.age.secrets."restic-repo-storagebox".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d keycloak > /tmp/keycloak-backup.sql
'';

View file

@ -25,7 +25,7 @@
};
};
replication_factor = 1;
path_prefix = "/data/loki";
path_prefix = "/var/lib/loki";
storage = {
filesystem = {
chunks_directory = "chunks/";
@ -108,7 +108,7 @@
};
clients = [
{
url = "http://flora-6.wg.pub.solar:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
url = "http://trinkgenossin.wg.pub.solar:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
}
];
scrape_configs = [
@ -118,7 +118,7 @@
max_age = "24h";
labels = {
job = "systemd-journal";
host = "flora-6";
host = "trinkgenossin";
};
};
relabel_configs = [

View file

@ -67,4 +67,20 @@
};
security.acme.acceptTerms = true;
security.acme.defaults.email = "security@pub.solar";
pub-solar-os.backups.restic.mail = {
paths = [
"/var/vmail"
"/var/dkim"
];
timerConfig = {
OnCalendar = "*-*-* 02:00:00 Etc/UTC";
};
initialize = true;
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 3"
];
};
}

View file

@ -91,7 +91,7 @@
OnCalendar = "*-*-* 02:00:00 Etc/UTC";
};
initialize = true;
passwordFile = config.age.secrets."restic-repo-storagebox".path;
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
pruneOpts = [
"--keep-daily 7"

View file

@ -7,6 +7,21 @@
}:
{
age.secrets."mastodon-active-record-encryption-deterministic-key" = {
file = "${flake.self}/secrets//mastodon-active-record-encryption-deterministic-key.age";
mode = "400";
owner = config.services.mastodon.user;
};
age.secrets."mastodon-active-record-encryption-key-derivation-salt" = {
file = "${flake.self}/secrets//mastodon-active-record-encryption-key-derivation-salt.age";
mode = "400";
owner = config.services.mastodon.user;
};
age.secrets."mastodon-active-record-encryption-primary-key" = {
file = "${flake.self}/secrets//mastodon-active-record-encryption-primary-key.age";
mode = "400";
owner = config.services.mastodon.user;
};
age.secrets."mastodon-secret-key-base" = {
file = "${flake.self}/secrets/mastodon-secret-key-base.age";
mode = "400";
@ -54,6 +69,9 @@
webProcesses = 2;
# Threads per process used by the mastodon-web service
webThreads = 5;
activeRecordEncryptionDeterministicKeyFile = "/run/agenix/mastodon-active-record-encryption-deterministic-key";
activeRecordEncryptionKeyDerivationSaltFile = "/run/agenix/mastodon-active-record-encryption-key-derivation-salt";
activeRecordEncryptionPrimaryKeyFile = "/run/agenix/mastodon-active-record-encryption-primary-key";
secretKeyBaseFile = "/run/agenix/mastodon-secret-key-base";
otpSecretFile = "/run/agenix/mastodon-otp-secret";
vapidPrivateKeyFile = "/run/agenix/mastodon-vapid-private-key";
@ -67,20 +85,20 @@
passwordFile = "/run/agenix/mastodon-smtp-password";
fromAddress = "mastodon-notifications@pub.solar";
};
# Defined in ./opensearch.nix
elasticsearch.host = "127.0.0.1";
mediaAutoRemove = {
olderThanDays = 7;
};
extraEnvFiles = [ "/run/agenix/mastodon-extra-env-secrets" ];
extraConfig = {
WEB_DOMAIN = "mastodon.${config.pub-solar-os.networking.domain}";
# Defined in ./opensearch.nix
ES_HOST = "127.0.0.1";
# S3 File storage (optional)
# -----------------------
S3_ENABLED = "true";
S3_BUCKET = "pub-solar-mastodon";
S3_REGION = "europe-west-1";
S3_ENDPOINT = "https://gateway.tardigradeshare.io";
S3_BUCKET = "mastodon";
S3_REGION = "eu-central";
S3_ENDPOINT = "https://buckets.pub.solar";
S3_ALIAS_HOST = "files.${config.pub-solar-os.networking.domain}";
# Translation (optional)
# -----------------------
@ -106,7 +124,7 @@
OnCalendar = "*-*-* 04:00:00 Etc/UTC";
};
initialize = true;
passwordFile = config.age.secrets."restic-repo-storagebox".path;
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d mastodon > /tmp/mastodon-backup.sql

View file

@ -16,11 +16,6 @@ let
synapseClientPort = "${toString listenerWithClient.port}";
in
{
systemd.services.matrix-appservice-irc.serviceConfig.SystemCallFilter = lib.mkForce [
"@system-service @pkey"
"~@privileged @resources"
"@chown"
];
services.matrix-appservice-irc = {
enable = true;
localpart = "irc_bot";
@ -40,7 +35,8 @@ in
port = 1113;
};
logging = {
level = "debug";
# set to debug for debugging
level = "warn";
maxFiles = 5;
toCosole = true;
};

View file

@ -1,6 +1,7 @@
{
flake,
config,
lib,
pkgs,
...
}:
@ -9,304 +10,369 @@ let
serverDomain = "${config.pub-solar-os.networking.domain}";
in
{
age.secrets."matrix-synapse-signing-key" = {
file = "${flake.self}/secrets/matrix-synapse-signing-key.age";
mode = "400";
owner = "matrix-synapse";
options.pub-solar-os = {
matrix = {
enable = lib.mkEnableOption "Enable matrix-synapse and matrix-authentication-service to run on the node";
synapse = {
app-service-config-files = lib.mkOption {
description = "List of app service config files";
type = lib.types.listOf lib.types.str;
default = [ ];
};
extra-config-files = lib.mkOption {
description = "List of extra synapse config files";
type = lib.types.listOf lib.types.str;
default = [ ];
};
signing_key_path = lib.mkOption {
description = "Path to file containing the signing key";
type = lib.types.str;
default = "${config.services.matrix-synapse.dataDir}/homeserver.signing.key";
};
sliding-sync.enable = lib.mkEnableOption {
description = "Whether to enable a sliding-sync proxy, no longer needed with synapse version 1.114+";
default = false;
};
};
matrix-authentication-service = {
extra-config-files = lib.mkOption {
description = "List of extra mas config files";
type = lib.types.listOf lib.types.str;
default = [ ];
};
};
};
};
age.secrets."matrix-synapse-secret-config.yaml" = {
file = "${flake.self}/secrets/matrix-synapse-secret-config.yaml.age";
mode = "400";
owner = "matrix-synapse";
};
age.secrets."matrix-synapse-sliding-sync-secret" = {
file = "${flake.self}/secrets/matrix-synapse-sliding-sync-secret.age";
mode = "400";
owner = "matrix-synapse";
};
services.matrix-synapse = {
enable = true;
settings = {
server_name = serverDomain;
public_baseurl = "https://${publicDomain}/";
database = {
name = "psycopg2";
args = {
host = "/run/postgresql";
cp_max = 10;
cp_min = 5;
database = "matrix";
config = lib.mkIf config.pub-solar-os.matrix.enable {
services.matrix-synapse = {
enable = true;
settings = {
server_name = serverDomain;
public_baseurl = "https://${publicDomain}/";
database = {
name = "psycopg2";
args = {
host = "/run/postgresql";
cp_max = 10;
cp_min = 5;
database = "matrix";
};
allow_unsafe_locale = false;
txn_limit = 0;
};
allow_unsafe_locale = false;
txn_limit = 0;
};
listeners = [
{
bind_addresses = [ "127.0.0.1" ];
port = 8008;
resources = [
{
compress = true;
names = [ "client" ];
}
{
compress = false;
names = [ "federation" ];
}
];
tls = false;
type = "http";
x_forwarded = true;
}
{
bind_addresses = [ "127.0.0.1" ];
port = 8012;
resources = [ { names = [ "metrics" ]; } ];
tls = false;
type = "metrics";
}
];
listeners = [
{
bind_addresses = [ "127.0.0.1" ];
port = 8008;
resources = [
{
compress = true;
names = [ "client" ];
}
{
compress = false;
names = [ "federation" ];
}
];
tls = false;
type = "http";
x_forwarded = true;
}
{
bind_addresses = [ "127.0.0.1" ];
port = 8012;
resources = [ { names = [ "metrics" ]; } ];
tls = false;
type = "metrics";
}
];
account_threepid_delegates.msisdn = "";
alias_creation_rules = [
{
action = "allow";
alias = "*";
room_id = "*";
user_id = "*";
}
];
allow_guest_access = false;
allow_public_rooms_over_federation = true;
allow_public_rooms_without_auth = false;
auto_join_rooms = [
"#community:${serverDomain}"
"#general:${serverDomain}"
];
account_threepid_delegates.msisdn = "";
alias_creation_rules = [
{
action = "allow";
alias = "*";
room_id = "*";
user_id = "*";
}
];
allow_guest_access = false;
allow_public_rooms_over_federation = true;
allow_public_rooms_without_auth = false;
auto_join_rooms = [
"#community:${serverDomain}"
"#general:${serverDomain}"
];
autocreate_auto_join_rooms = true;
caches.global_factor = 0.5;
autocreate_auto_join_rooms = true;
caches.global_factor = 0.5;
default_room_version = "10";
disable_msisdn_registration = true;
enable_media_repo = true;
enable_metrics = true;
mau_stats_only = true;
enable_registration = false;
enable_registration_captcha = false;
enable_registration_without_verification = false;
enable_room_list_search = true;
encryption_enabled_by_default_for_room_type = "off";
event_cache_size = "100K";
federation_rr_transactions_per_room_per_second = 50;
federation_client_minimum_tls_version = "1.2";
forget_rooms_on_leave = true;
include_profile_data_on_invite = true;
instance_map = { };
limit_profile_requests_to_users_who_share_rooms = false;
default_room_version = "10";
disable_msisdn_registration = true;
enable_media_repo = true;
enable_metrics = true;
mau_stats_only = true;
enable_registration = false;
enable_registration_captcha = false;
enable_registration_without_verification = false;
enable_room_list_search = true;
encryption_enabled_by_default_for_room_type = "off";
event_cache_size = "100K";
max_spider_size = "10M";
max_upload_size = "50M";
media_storage_providers = [ ];
# https://github.com/element-hq/synapse/issues/11203
# No YAML deep-merge, so this needs to be in secret extraConfigFiles
# together with msc3861
#experimental_features = {
# # Room summary API
# msc3266_enabled = true;
# # Rendezvous server for QR Code generation
# msc4108_enabled = true;
#};
password_config = {
enabled = false;
localdb_enabled = false;
pepper = "";
};
federation_rr_transactions_per_room_per_second = 50;
federation_client_minimum_tls_version = "1.2";
forget_rooms_on_leave = true;
include_profile_data_on_invite = true;
instance_map = { };
limit_profile_requests_to_users_who_share_rooms = false;
presence.enabled = true;
push.include_content = false;
max_spider_size = "10M";
max_upload_size = "50M";
media_storage_providers = [ ];
rc_admin_redaction = {
burst_count = 50;
per_second = 1;
};
rc_federation = {
concurrent = 3;
reject_limit = 50;
sleep_delay = 500;
sleep_limit = 10;
window_size = 1000;
};
rc_invites = {
per_issuer = {
password_config = {
enabled = false;
localdb_enabled = false;
pepper = "";
};
presence.enabled = true;
push.include_content = false;
rc_admin_redaction = {
burst_count = 50;
per_second = 1;
};
rc_federation = {
concurrent = 3;
reject_limit = 50;
sleep_delay = 500;
sleep_limit = 10;
window_size = 1000;
};
rc_invites = {
per_issuer = {
burst_count = 10;
per_second = 0.3;
};
per_room = {
burst_count = 10;
per_second = 0.3;
};
per_user = {
burst_count = 5;
per_second = 3.0e-3;
};
};
rc_joins = {
local = {
burst_count = 10;
per_second = 0.1;
};
remote = {
burst_count = 10;
per_second = 1.0e-2;
};
};
rc_login = {
account = {
burst_count = 3;
per_second = 0.17;
};
address = {
burst_count = 3;
per_second = 0.17;
};
failed_attempts = {
burst_count = 3;
per_second = 0.17;
};
};
rc_message = {
burst_count = 10;
per_second = 0.3;
per_second = 0.2;
};
per_room = {
burst_count = 10;
per_second = 0.3;
};
per_user = {
burst_count = 5;
per_second = 3.0e-3;
};
};
rc_joins = {
local = {
burst_count = 10;
per_second = 0.1;
};
remote = {
burst_count = 10;
per_second = 1.0e-2;
};
};
rc_login = {
account = {
rc_registration = {
burst_count = 3;
per_second = 0.17;
};
address = {
burst_count = 3;
per_second = 0.17;
};
failed_attempts = {
burst_count = 3;
per_second = 0.17;
redaction_retention_period = "7d";
forgotten_room_retention_period = "7d";
redis.enabled = false;
registration_requires_token = false;
registrations_require_3pid = [ "email" ];
report_stats = false;
require_auth_for_profile_requests = false;
room_list_publication_rules = [
{
action = "allow";
alias = "*";
room_id = "*";
user_id = "*";
}
];
signing_key_path = config.pub-solar-os.matrix.synapse.signing_key_path;
stream_writers = { };
trusted_key_servers = [ { server_name = "matrix.org"; } ];
suppress_key_server_warning = true;
turn_allow_guests = false;
turn_uris = [
"turn:${config.services.coturn.realm}:3478?transport=udp"
"turn:${config.services.coturn.realm}:3478?transport=tcp"
];
turn_user_lifetime = "1h";
url_preview_accept_language = [
"en-US"
"en"
];
url_preview_enabled = true;
url_preview_ip_range_blacklist = [
"127.0.0.0/8"
"10.0.0.0/8"
"172.16.0.0/12"
"192.168.0.0/16"
"100.64.0.0/10"
"192.0.0.0/24"
"169.254.0.0/16"
"192.88.99.0/24"
"198.18.0.0/15"
"192.0.2.0/24"
"198.51.100.0/24"
"203.0.113.0/24"
"224.0.0.0/4"
"::1/128"
"fe80::/10"
"fc00::/7"
"2001:db8::/32"
"ff00::/8"
"fec0::/10"
];
user_directory = {
prefer_local_users = false;
search_all_users = false;
};
user_ips_max_age = "28d";
app_service_config_files = config.pub-solar-os.matrix.synapse.app-service-config-files;
};
rc_message = {
burst_count = 10;
per_second = 0.2;
};
rc_registration = {
burst_count = 3;
per_second = 0.17;
};
redaction_retention_period = "7d";
forgotten_room_retention_period = "7d";
redis.enabled = false;
registration_requires_token = false;
registrations_require_3pid = [ "email" ];
report_stats = false;
require_auth_for_profile_requests = false;
room_list_publication_rules = [
{
action = "allow";
alias = "*";
room_id = "*";
user_id = "*";
}
withJemalloc = true;
extraConfigFiles = config.pub-solar-os.matrix.synapse.extra-config-files;
extras = [
"oidc"
"redis"
];
signing_key_path = "/run/agenix/matrix-synapse-signing-key";
stream_writers = { };
trusted_key_servers = [ { server_name = "matrix.org"; } ];
suppress_key_server_warning = true;
turn_allow_guests = false;
turn_uris = [
"turn:${config.services.coturn.realm}:3478?transport=udp"
"turn:${config.services.coturn.realm}:3478?transport=tcp"
];
turn_user_lifetime = "1h";
url_preview_accept_language = [
"en-US"
"en"
];
url_preview_enabled = true;
url_preview_ip_range_blacklist = [
"127.0.0.0/8"
"10.0.0.0/8"
"172.16.0.0/12"
"192.168.0.0/16"
"100.64.0.0/10"
"192.0.0.0/24"
"169.254.0.0/16"
"192.88.99.0/24"
"198.18.0.0/15"
"192.0.2.0/24"
"198.51.100.0/24"
"203.0.113.0/24"
"224.0.0.0/4"
"::1/128"
"fe80::/10"
"fc00::/7"
"2001:db8::/32"
"ff00::/8"
"fec0::/10"
];
user_directory = {
prefer_local_users = false;
search_all_users = false;
};
user_ips_max_age = "28d";
app_service_config_files = [
"/var/lib/matrix-synapse/telegram-registration.yaml"
"/var/lib/matrix-appservice-irc/registration.yml"
# "/matrix-appservice-slack-registration.yaml"
# "/hookshot-registration.yml"
# "/matrix-mautrix-signal-registration.yaml"
# "/matrix-mautrix-telegram-registration.yaml"
];
plugins = [ config.services.matrix-synapse.package.plugins.matrix-synapse-shared-secret-auth ];
};
withJemalloc = true;
services.matrix-authentication-service = {
enable = true;
createDatabase = true;
extraConfigFiles = config.pub-solar-os.matrix.matrix-authentication-service.extra-config-files;
extraConfigFiles = [
"/run/agenix/matrix-synapse-secret-config.yaml"
# The registration file is automatically generated after starting the
# appservice for the first time.
# cp /var/lib/mautrix-telegram/telegram-registration.yaml \
# /var/lib/matrix-synapse/
# chown matrix-synapse:matrix-synapse \
# /var/lib/matrix-synapse/telegram-registration.yaml
"/var/lib/matrix-synapse/telegram-registration.yaml"
];
extras = [
"oidc"
"redis"
];
plugins = [ config.services.matrix-synapse.package.plugins.matrix-synapse-shared-secret-auth ];
};
services.matrix-sliding-sync = {
enable = true;
settings = {
SYNCV3_SERVER = "https://${publicDomain}";
SYNCV3_BINDADDR = "127.0.0.1:8011";
# The bind addr for Prometheus metrics, which will be accessible at
# /metrics at this address
SYNCV3_PROM = "127.0.0.1:9100";
# https://element-hq.github.io/matrix-authentication-service/reference/configuration.html
settings = {
account.email_change_allowed = false;
http.public_base = "https://mas.${config.pub-solar-os.networking.domain}";
http.issuer = "https://mas.${config.pub-solar-os.networking.domain}";
http.listeners = [
{
name = "web";
resources = [
{ name = "discovery"; }
{ name = "human"; }
{ name = "oauth"; }
{ name = "compat"; }
{ name = "graphql"; }
{
name = "assets";
path = "${config.services.matrix-authentication-service.package}/share/matrix-authentication-service/assets";
}
];
binds = [
{
host = "0.0.0.0";
port = 8090;
}
];
proxy_protocol = false;
}
{
name = "internal";
resources = [
{ name = "health"; }
];
binds = [
{
host = "0.0.0.0";
port = 8081;
}
];
proxy_protocol = false;
}
];
passwords.enabled = false;
};
};
environmentFile = config.age.secrets."matrix-synapse-sliding-sync-secret".path;
};
services.restic.backups.matrix-synapse-storagebox = {
paths = [
"/var/lib/matrix-synapse"
"/var/lib/matrix-appservice-irc"
"/var/lib/mautrix-telegram"
"/tmp/matrix-synapse-backup.sql"
];
timerConfig = {
OnCalendar = "*-*-* 05:00:00 Etc/UTC";
services.matrix-sliding-sync = {
enable = config.pub-solar-os.matrix.synapse.sliding-sync.enable;
settings = {
SYNCV3_SERVER = "https://${publicDomain}";
SYNCV3_BINDADDR = "127.0.0.1:8011";
# The bind addr for Prometheus metrics, which will be accessible at
# /metrics at this address
SYNCV3_PROM = "127.0.0.1:9100";
};
environmentFile = config.age.secrets."matrix-synapse-sliding-sync-secret".path;
};
pub-solar-os.backups.restic.matrix-synapse = {
paths = [
"/var/lib/matrix-synapse"
"/var/lib/matrix-appservice-irc"
"/var/lib/mautrix-telegram"
"/tmp/matrix-synapse-backup.sql"
];
timerConfig = {
OnCalendar = "*-*-* 05:00:00 Etc/UTC";
};
initialize = true;
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix > /tmp/matrix-synapse-backup.sql
'';
backupCleanupCommand = ''
rm /tmp/matrix-synapse-backup.sql
'';
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 3"
];
};
initialize = true;
passwordFile = config.age.secrets."restic-repo-storagebox".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d matrix > /tmp/matrix-synapse-backup.sql
'';
backupCleanupCommand = ''
rm /tmp/matrix-synapse-backup.sql
'';
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 3"
];
};
}

View file

@ -232,4 +232,27 @@ in
};
};
};
pub-solar-os.backups.restic.mediawiki = {
paths = [
"/var/lib/mediawiki/images"
"/var/lib/mediawiki/uploads"
"/tmp/mediawiki-backup.sql"
];
timerConfig = {
OnCalendar = "*-*-* 00:30:00 Etc/UTC";
};
initialize = true;
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d mediawiki > /tmp/mediawiki-backup.sql
'';
backupCleanupCommand = ''
rm /tmp/mediawiki-backup.sql
'';
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 3"
];
};
}

View file

@ -145,7 +145,7 @@
OnCalendar = "*-*-* 01:00:00 Etc/UTC";
};
initialize = true;
passwordFile = config.age.secrets."restic-repo-storagebox".path;
passwordFile = config.age.secrets."restic-repo-storagebox-nachtigall".path;
repository = "sftp:u377325@u377325.your-storagebox.de:/backups";
backupPrepareCommand = ''
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump -d nextcloud > /tmp/nextcloud-backup.sql

View file

@ -1,8 +1,7 @@
{ config, ... }:
let
objStorHost = "link.tardigradeshare.io";
objStorBucket = "s/jw24ad6l4a6zxsnd32cmf5hp5nsq/pub-solar-mastodon";
objStorHost = "mastodon.web.pub.solar";
in
{
services.nginx.virtualHosts = {
@ -10,6 +9,12 @@ in
enableACME = true;
forceSSL = true;
# Use variable to force nginx to perform a DNS resolution on its value,
# the IP of the object storage provider may not always remain the same.
extraConfig = ''
set $s3_backend 'https://${objStorHost}';
'';
locations = {
"= /" = {
index = "index.html";
@ -25,7 +30,6 @@ in
deny all;
}
resolver 8.8.8.8;
proxy_set_header Host ${objStorHost};
proxy_set_header Connection \'\';
proxy_set_header Authorization \'\';
@ -40,7 +44,7 @@ in
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_ignore_headers Set-Cookie;
proxy_pass https://${objStorHost}/${objStorBucket}$request_uri?download;
proxy_pass $s3_backend$request_uri;
proxy_intercept_errors off;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_server_name on;

View file

@ -10,25 +10,20 @@ let
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-XSS-Protection "1; mode=block";
'';
clientConfig = import ./element-client-config.nix { inherit lib pkgs; };
clientConfig = import ./element-client-config.nix { inherit config lib pkgs; };
wellKnownClient = domain: {
"m.homeserver".base_url = "https://matrix.${domain}";
"m.identity_server".base_url = "https://matrix.${domain}";
"org.matrix.msc3575.proxy".url = "https://matrix.${domain}";
"org.matrix.msc2965.authentication" = {
issuer = "https://mas.${domain}/";
account = "https://mas.${domain}/account";
};
"im.vector.riot.e2ee".default = true;
"io.element.e2ee" = {
default = true;
secure_backup_required = false;
secure_backup_setup_methods = [ ];
};
"m.integrations" = {
managers = [
{
api_url = "https://dimension.${domain}/api/v1/scalar";
ui_url = "https://dimension.${domain}/element";
}
];
};
};
wellKnownServer = domain: { "m.server" = "matrix.${domain}:8448"; };
wellKnownSupport = {
@ -85,6 +80,27 @@ in
root = pkgs.element-stickerpicker;
};
"mas.${config.pub-solar-os.networking.domain}" = {
root = "/dev/null";
forceSSL = lib.mkDefault true;
enableACME = lib.mkDefault true;
locations = {
"/" = {
proxyPass = "http://127.0.0.1:8090";
extraConfig = ''
${commonHeaders}
proxy_http_version 1.1;
# Forward the client IP address
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
};
};
};
"matrix.${config.pub-solar-os.networking.domain}" = {
root = "/dev/null";
@ -99,28 +115,41 @@ in
locations = {
# For telegram
"/c3c3f34b-29fb-5feb-86e5-98c75ec8214b" = {
priority = 100;
proxyPass = "http://127.0.0.1:8009";
extraConfig = commonHeaders;
};
# sliding-sync
"~ ^/(client/|_matrix/client/unstable/org.matrix.msc3575/sync)" = {
proxyPass = "http://127.0.0.1:8011";
extraConfig = commonHeaders;
# Forward to the auth service
"~ ^/_matrix/client/(.*)/(login|logout|refresh)" = {
priority = 100;
proxyPass = "http://127.0.0.1:8090";
extraConfig = ''
${commonHeaders}
proxy_http_version 1.1;
# Forward the client IP address
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
'';
};
"~* ^(/_matrix|/_synapse/client|/_synapse/oidc)" = {
# Forward to Synapse
# as per https://element-hq.github.io/synapse/latest/reverse_proxy.html#nginx
"~ ^(/_matrix|/_synapse/client)" = {
priority = 200;
proxyPass = "http://127.0.0.1:8008";
extraConfig = ''
${commonHeaders}
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
client_body_buffer_size 25M;
client_max_body_size 50M;
proxy_max_temp_file_size 0;
proxy_http_version 1.1;
'';
};
};

View file

@ -1,9 +1,14 @@
{ pkgs, lib, ... }:
{
config,
pkgs,
lib,
...
}:
{
default_server_config = {
"m.homeserver" = {
base_url = "https://matrix.pub.solar";
server_name = "pub.solar";
base_url = "https://matrix.${config.pub-solar-os.networking.domain}";
server_name = "${config.pub-solar-os.networking.domain}";
};
"m.identity_server" = {
base_url = "";

View file

@ -7,7 +7,7 @@
services.nginx.virtualHosts = {
"www.${config.pub-solar-os.networking.domain}" = {
enableACME = true;
addSSL = true;
forceSSL = true;
extraConfig = ''
error_log /dev/null;

View file

@ -22,6 +22,13 @@ in
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
resolver.addresses = [
# quad9.net
"9.9.9.9"
"149.112.112.112"
"[2620:fe::fe]"
"[2620:fe::9]"
];
appendHttpConfig = ''
# https://my.f5.com/manage/s/article/K51798430
proxy_headers_hash_bucket_size 128;

View file

@ -147,4 +147,26 @@ in
};
};
};
pub-solar-os.backups.restic.obs-portal = {
paths = [
"/var/lib/obs-portal/data"
"/tmp/obs-portal-backup.sql"
];
timerConfig = {
OnCalendar = "*-*-* 01:30:00 Etc/UTC";
};
initialize = true;
backupPrepareCommand = ''
${pkgs.docker}/bin/docker exec -i --user postgres obs-portal-db pg_dump obs > /tmp/obs-portal-backup.sql
'';
backupCleanupCommand = ''
rm /tmp/obs-portal-backup.sql
'';
pruneOpts = [
"--keep-daily 7"
"--keep-weekly 4"
"--keep-monthly 3"
];
};
}

View file

@ -25,9 +25,4 @@
full_page_writes = false;
};
};
systemd.services.postgresql = {
after = [ "var-lib-postgresql.mount" ];
requisite = [ "var-lib-postgresql.mount" ];
};
}

View file

@ -142,8 +142,8 @@ lib.mapAttrsToList
cpu_using_90percent = {
condition = ''100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) >= 90'';
time = "10m";
description = "{{$labels.instance}} is running with cpu usage > 90% for at least 10 minutes: {{$value}}";
time = "20m";
description = "{{$labels.instance}} is running with cpu usage > 90% for at least 20 minutes: {{$value}}";
};
reboot = {
@ -198,10 +198,10 @@ lib.mapAttrsToList
description = "{{$labels.instance}}: healtcheck {{$labels.job}} fails!";
};
*/
cert_expiry = {
condition = "(probe_ssl_earliest_cert_expiry - time())/(3600*24) < 30";
description = "{{$labels.instance}}: The TLS certificate will expire in less than 30 days: {{$value}}s";
};
#cert_expiry = {
# condition = "(probe_ssl_earliest_cert_expiry - time())/(3600*24) < 30";
# description = "{{$labels.instance}}: The TLS certificate will expire in less than 30 days: {{$value}}s";
#};
# ignore devices that disabled S.M.A.R.T (example if attached via USB)
@ -234,10 +234,10 @@ lib.mapAttrsToList
};
*/
host_memory_under_memory_pressure = {
condition = "rate(node_vmstat_pgmajfault[1m]) > 1000";
description = "{{$labels.instance}}: The node is under heavy memory pressure. High rate of major page faults: {{$value}}";
};
#host_memory_under_memory_pressure = {
# condition = "rate(node_vmstat_pgmajfault[1m]) > 1000";
# description = "{{$labels.instance}}: The node is under heavy memory pressure. High rate of major page faults: {{$value}}";
#};
# ext4_errors = {
# condition = "ext4_errors_value > 0";
@ -250,4 +250,10 @@ lib.mapAttrsToList
# description =
# "alertmanager: number of active silences has changed: {{$value}}";
# };
garage_cluster_healthy = {
condition = "cluster_healthy == 0";
time = "15m";
description = "garage cluster on {{$labels.instance}} is not healthy: {{$labels.result}}!";
};
})

View file

@ -5,10 +5,6 @@
flake,
...
}:
let
# TODO add hosts here
blackboxTargets = [ "https://pablo.tools" ];
in
{
age.secrets.alertmanager-envfile = {
file = "${flake.self}/secrets/alertmanager-envfile.age";
@ -16,48 +12,33 @@ in
owner = "alertmanager";
};
services.caddy.virtualHosts."alerts.${config.pub-solar-os.networking.domain}" = {
logFormat = lib.mkForce ''
output discard
'';
extraConfig = ''
bind 10.7.6.2 fd00:fae:fae:fae:fae:2::
tls internal
reverse_proxy :${toString config.services.prometheus.alertmanager.port}
'';
security.acme.certs = {
"alerts.${config.pub-solar-os.networking.domain}" = {
# disable http challenge
webroot = null;
# enable dns challenge
dnsProvider = "namecheap";
};
};
services.nginx.virtualHosts."alerts.${config.pub-solar-os.networking.domain}" = {
enableACME = true;
forceSSL = true;
listenAddresses = [
"10.7.6.5"
"[fd00:fae:fae:fae:fae:5::]"
];
locations."/" = {
proxyPass = "http://127.0.0.1:${toString config.services.prometheus.alertmanager.port}";
};
};
services.prometheus = {
enable = true;
port = 9001;
exporters = {
blackbox = {
enable = true;
# Default port is 9115
# Listen on 0.0.0.0, bet we only open the firewall for wg0
openFirewall = false;
configFile = pkgs.writeTextFile {
name = "blackbox-exporter-config";
text = ''
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
valid_status_codes: [] # Defaults to 2xx
method: GET
no_follow_redirects: false
fail_if_ssl: false
fail_if_not_ssl: false
tls_config:
insecure_skip_verify: false
preferred_ip_protocol: "ip4" # defaults to "ip6"
ip_protocol_fallback: true # fallback to "ip6"
'';
};
};
node = {
enable = true;
enabledCollectors = [ "systemd" ];
@ -69,39 +50,9 @@ in
scrape_timeout = "9s";
};
scrapeConfigs = [
{
job_name = "blackbox";
scrape_interval = "2m";
metrics_path = "/probe";
params = {
module = [ "http_2xx" ];
};
static_configs = [ { targets = blackboxTargets; } ];
relabel_configs = [
{
source_labels = [ "__address__" ];
target_label = "__param_target";
}
{
source_labels = [ "__param_target" ];
target_label = "instance";
}
{
target_label = "__address__";
replacement = "127.0.0.1:9115"; # The blackbox exporter's real hostname:port.
}
];
}
{
job_name = "node-exporter";
static_configs = [
{
targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ];
labels = {
instance = "flora-6";
};
}
{
targets = [ "nachtigall.wg.${config.pub-solar-os.networking.domain}" ];
labels = {
@ -124,6 +75,30 @@ in
instance = "tankstelle";
};
}
{
targets = [
"trinkgenossin.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
];
labels = {
instance = "trinkgenossin";
};
}
{
targets = [
"delite.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
];
labels = {
instance = "delite";
};
}
{
targets = [
"blue-shell.wg.${config.pub-solar-os.networking.domain}:${toString config.services.prometheus.exporters.node.port}"
];
labels = {
instance = "blue-shell";
};
}
];
}
{
@ -138,6 +113,29 @@ in
}
];
}
{
job_name = "garage";
static_configs = [
{
targets = [ "trinkgenossin.wg.${config.pub-solar-os.networking.domain}:3903" ];
labels = {
instance = "trinkgenossin";
};
}
{
targets = [ "delite.wg.${config.pub-solar-os.networking.domain}:3903" ];
labels = {
instance = "delite";
};
}
{
targets = [ "blue-shell.wg.${config.pub-solar-os.networking.domain}:3903" ];
labels = {
instance = "blue-shell";
};
}
];
}
];
ruleFiles = [

View file

@ -18,7 +18,7 @@
};
clients = [
{
url = "http://flora-6.wg.pub.solar:${toString flake.self.nixosConfigurations.flora-6.config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
url = "http://trinkgenossin.wg.pub.solar:${toString flake.self.nixosConfigurations.trinkgenossin.config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
}
];
scrape_configs = [

View file

@ -10,6 +10,7 @@ let
version = "7ebfbc91e92bb133beb907c6bde79279ee5156df";
src = pkgs.fetchgit {
url = "https://git.tt-rss.org/fox/ttrss-auth-oidc.git";
rev = "7ebfbc91e92bb133beb907c6bde79279ee5156df";
hash = "sha256-G6vZBvSWms6s6nHZWsxJjMGuubt/imiBvbp6ykwrZbg=";
};
installPhase = ''

View file

@ -0,0 +1,20 @@
{ flake, config, ... }:
{
boot.initrd.network = {
enable = true;
ssh = {
enable = true;
# To prevent ssh clients from freaking out because a different host key is used,
# a different port for ssh is useful (assuming the same host has also a regular sshd running)
port = 2222;
# Please create this manually the first time.
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
authorizedKeys = flake.self.logins.sshPubKeys;
};
postCommands = ''
# Automatically ask for the password on SSH login
echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1' >> /root/.profile
'';
};
}

View file

@ -11,7 +11,7 @@
# Please create this manually the first time.
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
authorizedKeys = config.pub-solar-os.authentication.sshPubKeys;
authorizedKeys = flake.self.logins.sshPubKeys;
};
# this will automatically load the zfs password prompt on login
# and kill the other prompt so boot can continue

View file

@ -16,6 +16,8 @@
element-stickerpicker = prev.callPackage ./pkgs/element-stickerpicker {
inherit (inputs) element-stickers maunium-stickerpicker;
};
mastodon = unstable.mastodon;
matrix-authentication-service = unstable.matrix-authentication-service;
}
)
];

View file

@ -0,0 +1,48 @@
age-encryption.org/v1
-> ssh-ed25519 NID4eA WtfgDmnK5l9s9DMhWgmk+tel+/uqPx8SHBd0qfWY3jk
ZS3Qu4v3pnA+lYzJ3kad7T3LhcY7oE8fPsGQ1uQH1AA
-> ssh-ed25519 9RQHxg SpHG3ijNizTi1YXvZCJS79Uwt4oGkYzqIme+eqQi9AQ
GqVhyfaTF6tLwuo0vIby0vBv3JufHz59IdNX9ifWtSA
-> ssh-ed25519 eP5MMw 9uU7tlyOzOxlsW/bfUmzjgicU3i2J5uCGWEVIljnHiM
tDJdTB1rBJTXVaGFOOmtG5n2Ae0XOCsi41S0EagRmeM
-> ssh-ed25519 uYcDNw ge+lEVE8+pS/S+eO+6sPqo/czym30CJbQnhTp11NsW4
jxL7Xhn/7JRylJ/JbeGkmhMMeJ8G2KPEKVVq1icQXKU
-> ssh-rsa f5THog
Ybod3f7gvCiBUcNyLV6AXoBchtRGspQah9JwygSGCtBKmWPOUSw3/DVva9nPVwHB
q4t05bEHINMZIoWy4l3VQ1jw+GTxW+6OeWDHrxHOG2hlu1/OT0tZnsQIjWwT/6Sg
fzy6X04yD2ADkwHH6VJYjC2Lxa7kEOeCeKOACyyab7rlXk+HauytUDlcF3Nl3nOc
JQZzfwIORU0XWVy+gDocwVqDaRJXZxhMW8oDjlU8BKgf/DpvExLfuZ9AHHJBU0Y9
HefbTbGO1s5J0T+HEkuIDce9iPQEe8ufaSVO6tKyHpgguIAiLIkjqrdLNRmXv/y8
9W653Xqar7fimd/sykb4K/PpdwvQcB9Ogy23t6s3Qxz5yPtC2m8IC3lgR+N+/nJO
n29QuXFBNUZu/QBXnWMS2QF09MGE2aav/CiwFuNiTf5D4UGGN3Y7XhX/KVOFJTZX
r1GLtch6rvD9RtfyKxAdbtCqbBEQJmoiut9ia5EzG4TvdPAE4XK3QNTn2BSmfjvI
3aXiXOFSbdJqkxyI6ZU2mUMMor3OWrXxWizDDYef6iHZxGlWFqA/kVXyZgdwTK9n
8Re6SYR8roH7T35eILzP4sskElN32UO/A+JyGfP1lOclGTlOrtp4HYTfY0NhhRJT
L7YIB0pNbaRxMBsxsxwU47j3qMkaO1uzP+DgpUacWJY
-> ssh-rsa kFDS0A
GJjiIApapBS6F8pmh6lblCHG3FlVWL+WKN1Gi2u/6Pa1YbkiBCgYFTQBwm5GsBMR
4tQwRJcQQDGgGddIH4/QcMAl1fTYLm3N1w8rueywgAbOwaWktKnJFYTj7lS6PSNr
bZyqyiGvgi0oYYSVjRnm7MmCrycuKmhcGHv1ijj5J8yOxe6qFsomsn9QZm1DmR/m
EZmc5DIYXjhuauzGgqtPVmjHi6hXTN8NX7Fg81aegko79yA12hmyHmaBj4P96Kqv
RyWZ9Moc3ccyxq74jNzp0eFuPNhUJuNBqrKozCc2Lo3KQAmoqI27THkF/HA8ECGP
BJDK7JdHBXyHhf/Fc5O5xOxHieIU8tHR0LLJn7VEvQyqTlKmWkZ5J53AqE8UDmm9
0gY6zFh7h3SjyBwqktzGJ9zXn3bp4fpg0M1+SaYp9Qf6hkJ9k79Zth4s4ggxgvOl
veib2sg3PCmL1OCMPMtyW3JkKsq0J+PtJdlAC9cmVvfvAMHKy2+aADsLt0H8Cpt2
cNOxbnU29eLWgG9uzcCXfqqNtmSia6LUMu71GahAuteZUV8RnDOZdCNW4U2Ohnq/
9znMqERVo0d3LgjaB0P3HXCCqhVFYTTDWg31R6N2RzSh7mb02CFgt7N+vHleQqAo
G/6Pb+kKYSEbU884z95+o56eQrvPunCN9Vu1CjEBfG4
-> piv-p256 vRzPNw A2dcPImS0ih5CjePQP5oPrPfwns6zAMP0J72P7fyzD/A
p46umKyZjbc1MjOQGnJIRu6V99O+/PmVXQvryX/9XW4
-> piv-p256 zqq/iw A5nBHU2O+bxsFqplf2GV6pK5wQ+hJ9l7tyFIe57QVKzw
Ik6aUY3t4geZ3yiWPqBGlBem9xNU83x7t3UA7pYB55I
-> ssh-ed25519 YFSOsg OhynWXlurzqU3ohq1ecH018Ja4wyWazDLv6isajeBUE
Xnjo8yS9IkMwCGNeLi6BABYxjXDLbpuTrVfwAxjDWdQ
-> ssh-ed25519 iHV63A 5CVIOtSwima5gIvwoAYExcy1tfOo8942RQ+SsflPbAM
4HV21GcuyddIjonOZZFgjgpR5smjce7OlMN3DCy0/sU
-> ssh-ed25519 BVsyTA mkLu2Vpr16bAZWimh6sViq5HlB1+lNOc2WPCxzgfqAg
cIDgWit139jipd7XmZcT8mTRDKK8rJV9xIxIaPVL9pM
-> ssh-ed25519 +3V2lQ eqfktAyV2Pia7T7XEfcYiHN9Jd4zivMzJk3in4XOTx0
gZzO+MTyBOJR1EgGn4Mhh4rnIyr3N9gmlFty83ou+GU
--- yJrzTzStOkRCNRu3Y+knfqTqHrwW0S0Bsko7oG/s86o
®,Bgm°þ÷€fåT¾èä`1†&1³%7Q˜(¯•¸Ÿ:?ßÝ
êÎø—æ‡ðj£ùÄO_rqwÃÏi£O®´D·)@0•ZK'óô+apU§<Ö`ºõµœctª. þ¡<C3BE>ÌXÇNæ+íŒÂh†Ù=‰'‡VÑn^HHöv±5aa²nKÝþ×

View file

@ -1,43 +1,43 @@
age-encryption.org/v1
-> ssh-ed25519 Y0ZZaw TsTaRLA+9WtN9+FJWpXeP12Af5EXMbo+ANTaLC9YlC8
Yols084RY1C9gfOrDMwJcFRuGZ/5dgGuJey7RXqm7g0
-> ssh-ed25519 uYcDNw ZLAINtv10PGMtK5TL5Tf0NyK/r1iww+vTC09ElMGoX0
EgBB3aiHHdaDue9+Zdxg6mTV2VHeLoDN9wT+hlAzVMk
-> ssh-ed25519 NID4eA jIwfpP0rFLANj63MsJAse0R+TQbGf7mUStdusSLkkCg
RHyxZqWGYMvhQYfZUc89GPly42u7MR9gSpR8aFWH6LI
-> ssh-ed25519 uYcDNw JGsVrWwxwA8ftUM+Fo1jFigWfpvNUwoNkK5zKIu582Y
BzM82Iqmta2Dtb8xey2nkoil7mDipn1iZtGMPKwPcPI
-> ssh-rsa f5THog
aiJqMs3/u06tzs8lx2ISlQm87TDatqEn47v3LB3HehPanRpZx9O1HUIRTeiWkMU9
XroGe27HQCCPd63QunBHUH7WStA10IS4rHVpMcULB5IM4jwcbOhSYSiGyY2sbv8+
Nn/04ZOwrfzTabC7moV1DqAw6hnlDqKWp/q5N6xMb780w5vn6Poni3OJfuLaBWaT
r6WhE5evVt3F4jyYI64fB2hFw4AR2N/zIMOMvBncLFwJf9lbIFdbsENZf94cYceF
Tj150xdMPuErBsSJQOlfDYSmyioNN3UJUWiYsDeM3nbPEVPHhfTk6b2/lMhSQkcY
KcuMj/mN/7w7i4HSxW6mUcK2sUMV1BcSSGYRH9ZFf7kq++KpyiP7vB8vaZkcKbfJ
qqrIcXTuXhR+/bWZWqf/GQOVwRwe1TnqN5MoZHipg3a/UCe0gMM617VwZcfhBzjA
eW6VUdjSewwA8YHEuDrAeoQ4CMs7y56EaIlr2IlQy6uzJPX9eeO0auO9RZ5AR40a
7un0FrlTJX9uorpCD/zi3tvd22W5qVoMGZ8vXJShZmT9he9K3Bv6XbzG4DJQ9/nv
xZ676HUYhWeyYZFBvt6DnEBneiDJFeaV2AeuQY+juHBOfBrbYmlE0S4Pd8uRSJ7w
u5UJTT+RV5TkZhpCqqYm7DphYocnrv7Ic+QKmvKE4ls
LkPMatwkNWAElm+RQiCHtHH2QPgVsAAd5b4qF0R0O6r+0CYzEF2OAOZ0LDsytTB8
7oHAHxA6kAga/pqKUaJl28xw7ujVIb1CunZFvVSxtOTYRrEy1Rxe3AKUOm+ZmfPL
66Ef58HWMCHzK9sc/ojo7Us4okfRhJBklB9lnORkSfdkvEHLeq0R0FfDtDCnynRD
SKqlx3VbdWe9k6UOJidA+dY8Wx0w2TQM1c21nDr4vXsXpZf6ttT4HvrqbSrS9V1c
nGofWP+72WinOpFRDQdLvdKvaNbLPwhigqL1VqaIcsnye5zZjQDNn+SYf55byBkS
CMXj238UqvdDxB4E3mBEgpFxOnyi6kLQXcPEBF/xQ5fER0RS5MkWkuH4Up+BCQ+/
CppqZrw85OOa9jAyWxil3yLQNAnLGi/P+mesPxSI+i2Not9wbUTALr4COG+1qvfF
2MbHiqREoajnQUJjhGhXaAA332X7hNuOF/DjmBr7i81oWVmKs6TjCDVL7Yo9xu3j
BcFqMlaOgr8gObwnyJ9BbtW4sBtnOeD5onPxWluV1+Ql8Idjmu/BKeuqIyGX6wFl
606lbprSTRVjLZWvg3gWaIMlXdcnat9PmHeRk/yzTrHke2aFSkvUKLymnRCHETae
Rh8ILeQTq36Ul9r7qklBNu4M7/f+jeX7gYPH/yDUCXc
-> ssh-rsa kFDS0A
HhilpvIiUps80SXYUXg5vqNmcy8SACvxpC5dTVBU2n+4OVXQY/35Il5ZOrUX3U7a
arfVp/KaQF7Oncu3x8F6Tp1ibUwmoyAV6OYqqs128nEPwkNbJvwrLY3aEBm+NIzm
gMlLRjj6EP84TVWgOsenQCS4l957f0QoNVxQ3f+GWdOiZZJFsv//ndsflng8zPlF
bGZy8c1TxDZfOD0/kW3Nx05c9X0EHKOEoDUc0p4qntrWlflxcvLONCgv1gZuPMF+
jMsPFP81eu3rkEUxefJ1qbvvGuW0cbzfwiStv7iGQ+Skh/vcoM0qw6p+csNKyHVO
8nYFcs9kD8067zMnyuqiUHASfZ4rPqTji0iiPC5kZn6N0YSgz2bybkXcoqmy3m6y
qs0S+RD99o2vCLhW46hZyKAgUyTU1DW42EmnZkPrLoqV7uin8fAwPO/98Q/b3Rkr
zBRtyTEbooHvOCL8limiRtDl+5LMcjRFNWk8AN+9vHMsYurXPNOCnd8n2Z4MbT2U
AhpoAD/+8HXp0InBJ/sclITVAc6tPb2CbJW6mrFezH8Ri+/6u+zSF84JDd9ZrCOz
oIshiGZmhP5mIuspVrxgKlm78a56vQrygpqzvuSSYk3zIJxmhEkZhw09/ga+rhyB
pkKn7GRyZTfKjwt5nnvW5/bmQndTa13j+7RhkRgBSvU
-> piv-p256 vRzPNw Awpc8paUfKnP6r0bYsaoeDE9GVSnads4/a3jCVScgS4V
YydKOS09kyZDYN843SHIsYUimtSQKvGhIuycPWOFojc
-> piv-p256 zqq/iw A54xbcufPkLpTD+N47AiIe/xZ/0vA5kDJ4p3rIZw0a4A
1WFP2K3tfUxtdKDBEmT3cx/u1i5nCzFR7cK4kN3WjC4
-> ssh-ed25519 YFSOsg L0lPSkoPVRKGlJ9MzkJx+cQvnZw/5m/j/JO4aRzd52Q
o/N7zQkvbGGoadiJSvL6lfuP63uqzxEIxDtIg4tgKIo
-> ssh-ed25519 iHV63A qfLWZhbDisCSJ4vFFTR+XpRUR0WViuAqarf56M0ekT4
ZSWW34pFRr0M2jFhnphIPJ5ch37ASM6OgTzyHSo0KAs
-> ssh-ed25519 BVsyTA JcFezSIfTF+AP8LYfFqz+wIpUrE0aoc1usiLtWxAPQE
F9uhFyCPK46kIy+ud4V5/ESacQgc9R0JV+JTEZO6nBI
-> ssh-ed25519 +3V2lQ G4yT1e7B5O2Gy6tusRMxuWOFScynWfFY5AjrJvxMK1o
n1OVFRqzijWlc+B93cBNdFPz+8CBYOsI5hpF1wz7xr0
--- 61u55uUc7z59iHF1IeyBLmcR6u7STUhpOPb/ODf75Vc
<$kxpû´Ú H:}ò*ä/Tâ®Ñ$ÕbÀJ \F*ðòWîzÉ6 Ý ± Âì<î̹>e?ñ¼<C3B1>Ÿ6ÚµÌ~Ô!
X1vrBlpHkWOVyhBokgO0yNDQk57S92xADIi88w2UU+nTYFgo/RsyTCCFAFMaDvR3
kQdtorCowxQpKLnTzER8i2ABZAgAmUzGQuRPDKcqZuZH9oypNkBs6qeVI3TA5GKu
V/IfKLeR57K3cpZT+TcOzKUqm/AAZO+rwdnrfW9qVAb7vlo3TWawfBHb+Fl7y9JL
pEjhDMhnA7na67Ktz1MFm80XRneMTW+0NGtcTd1iQfjfHe0WfFuYU4H6aZ8ZpZYw
2rLa+EmFqUpv0ELwdGViqmjUNwJunsJ6rhJZlMn43v5/XPLpapQr0zwtXzzfzZHd
HnI6/X97zPYUFDsUeI6x2CiVKHVWMGjJ9VPAexpJepZSkgI6On2/mfs4++XnDWLv
qsvsJqVzM075eH0LUyXq4WGu7oJc4OdfMm1CrEBKAaqdKRl0HnBZGSER3C/qAhLK
Ihbk+kti5C7GTzRyUlzkwINVFV0pePClLP7AC5vdKMhXysGQlxNJsTeUTdAOhrAm
UeWnd0Xp+K8OBsUgyGktKBMofNAJ+MilSKt3x7tJk3QuQIGjqHCshpkMf0ckixrh
aDN9Rj+s0A8C3hrVv8z602jBrM5tfYOZv+q1/yFQo+ieic6Y9WEzzrTMJEHxFSzX
KadqfZii8HCGQODcXh8VRpWDVjzt/pDVR/zu/0YCP+0
-> piv-p256 vRzPNw A4KCXAKoTYy8euaKXot9+c5N21WG9/9uLPomiiI6rZ5W
vbTcLpDNM1qVdTBCUPMrlX2GpyeMUsKaKLFl5GVVdYY
-> piv-p256 zqq/iw ArX1s306JaaWVPiTA7XyzyTKcsBDHjeIiSoOg+5PhsBj
zzmU1T5q5ff6TzIXhWqiVM0Oxxo/ln3uExBXBlLFcME
-> ssh-ed25519 YFSOsg tgHAr/emB3i+9Hd+q9oYCjkPO+RuXv22kimdXz06Zys
p8sYz3j5I95ZBJroWxUSzWljcj8E3Ic9uwwyrUWm1+E
-> ssh-ed25519 iHV63A 9UXBAcuwIfuoTHcWYhLVa9qtJ7UsLsIQsH2Bn0T/Wy8
OvfX4cOKJYv9pwaQp3yD/QPZdDnGSC6f1qemtKENtpE
-> ssh-ed25519 BVsyTA nC+YMVK5YyCM79iNijTaBgIZDPi7Bvlunuzl2s9SrRw
xVUpZwdIcszqsRdZw74fJrSduzxqrO25EMfuypipys0
-> ssh-ed25519 +3V2lQ 4n/lkQ1nwcXD7mNc3DzIfC5xGF2mn27AoO36Chei8AA
vDe0RU8Xm3L+/nFM0lKK3jv6hqiUE/YxZUFyHUsqAfI
--- D4n9aVPWABXpzO9DI20yHf11MRJ5ACWVhT16bDls5pA
iR ÅÏÿ%µÙØY^Ï Ýñý’µ¶{“²°Ý”#®Z0´P6 šÿ+ÛÄR!iJ-\ul°9!å¬`Z÷¿Nh²

View file

@ -0,0 +1,43 @@
age-encryption.org/v1
-> ssh-ed25519 eP5MMw 3H1XEr/Vt2TOQUvGu3K54CxbigkVpaC6hofMOfFR60U
hqFTOoMhyhb/Fsywzu4nYXmEACOunenO/4NwPaVdrZs
-> ssh-ed25519 uYcDNw raghSMdCaiQrfGviMlc9Pwh8cx33IWh+mnsxL8jgTQM
aOMrh/746UulH7hkOV6XRiwEszgJtrI33mmzY5S2Ipg
-> ssh-rsa f5THog
Hm/2fpGDwqKG9K6zLYXuSDwOppDtDfw665ppaVzRvnNppizkilCohBzCrwXTMyeH
KKZKqaEt+n35wrurfMfqQf1AkamEimjlXCMmr9IwrBHbJeIJuHn6vGSOssQ0Sq4R
dr002QrKsGDzlL8dCLmaKU6VPTXcSbCOgDnBW/AyU7bvN51jtgm+jOIey7jH9Bm4
0nU0UNcPiShgSbXLPp0V6O/1zQBOVeFGyGenblAKlqLILPvc04f4703alqSbKwXF
q6GoS0Dipzr4N8X4Thzgc8H/YQ6cBVGQTebVGHqFEngLQ2C0yZWlDfJsKnKOGUce
xSxSskfzEv2s9VHDrXeiTAzSYaLoZI0JEDHOSICmZT2wqT1voFokIQV8twORGpOo
RAlNX0BULPEg5Mi2k3V4ZBcG5EwUjEcHAg+0cQ82D0f4OJEqMVIa3dse/lBbrFzC
/Gkr8+LPWVv7f+mRr3sdKtZ1nBwz1uTP5qIA9m92UeLVdVjmp20hixmlgftAbTBm
MtIH2xqkitpb6bhImGIbnxpg7U8IqQZNfavvOM9yqj0uud/Nh8ruUuwxci4RS7yP
YlIcompHudeirCLPvYx1T6nYRB2GB1tpTcyQN60pb6YC7lH9w/tLhZf8GFcMdIY8
eLx7FoWfNj2dIp8EpBrRUEaQlea6Eb1r2DYTjmNunnI
-> ssh-rsa kFDS0A
SPaIIABa0Wja26CIyeUvrlt+LWJY+Iw2+OouRZkMfi5YxDflb6SATesWh3zMD5+A
SOiA/oUiRfGRVMmqiEznd2BLyUO7FQDv8tIT38R3m8Nj2Lb/kWtuhPKqrk0PPvr+
kYR3iyM4klqccCzwOYwWfpO4ZkFACBApTOFYbU4WX50WDRQRco7M8funj10BAIsL
H7hOKtigx2RJaJDcU3MPHV4beECpKbeH9scICEDmi098UP3850g1lN5AR7NjWvLi
zr3Z8Up4UjEwH2mvuNnAbvA+0HOu5geIae+VUqy3EN7XFC5HnMHB6eK12Q1VAmF5
MbgkppMeoqLnxIdLT9xxRNhD50B3QR8MNHgaNWuBqfl86XPfXjxYP5kRaCAraego
nbE1gItlgIPESpf0ocfIEyXb0tSup8c+99ezgxBMrzNP6UtVGRhZvwLTpBZmrLoc
5P/hTr0WQE7d/6lmY9VyDsXasPU758tUhM/cJxmmUyZcCOhjAiJdWSYHe7AUjSQy
rUSKUSYwqM/epFNqdnanj4pmmRkSk/0AiEKikvb5DvWpHrnsL/EuQqtT382IGv6P
VA6ORv3BmL8IjNnTppZsG8k91WWHLEqxoDKUHg6WHfJ5XqnEM4maFsRZs53QLqLB
vjAxAeJHjFg13wkfJmo9mZNbw/0WXS/K+xmeOTYuH/8
-> piv-p256 vRzPNw AwPYD0NiFDZ3/0L0+BEUS0hm7RddL3sPXUshz7XtIQVi
7rzoQuAQQHxkuYFx5TrLEXZbGsERg78mAXcgQySwHGw
-> piv-p256 zqq/iw A0Ec624/7FOTPVAbZDjhsBy0i5L1Tw9LwYfH/7DeKHi9
djfKQINL2LVAAueovp/V1IGyhuy5LGQtOws5Dtih9sw
-> ssh-ed25519 YFSOsg 6EeEfNtlQ7/a5Rc5iShfSa2ZjIoN6QcLDI0hJgpF8AY
Tcp4iqFjBTTzSUAZrxRWe8QkvuEoPWVagNL4EiZLMIA
-> ssh-ed25519 iHV63A P8IDXAspyflmLqtPOqPWE+J9s9e3OccKc5+8s/Wi9H8
iRZba5723Ux5oo8YA2TDyiaWyGzHlAcvEiD7I99vq4o
-> ssh-ed25519 BVsyTA LB7gg2/eozH+f9BNC4Q1m6Pl7b6znkO5rPVgvKSjen4
AjNzM/44dMy7JyUcAT7c4pAFTtOuapiGtiqLdBPGrKA
-> ssh-ed25519 +3V2lQ NHbovTrC4cTSsqb3AfmVOJ/pL0QQbK9GpMUpQMAW7w8
iwAoDSQnucAzQPOgZZtl2bnJQ1mU19aoruItkQqJuZ8
--- itqKtiBSCvkVJ5boq7PeY3uRMemElImzWvSeTwbz3y4
×ZP38†¶0¿Òe¯8WjŽ÷[ªø#;ñHjÀëÏwïYÂœp¨µ“6W`ôhŒ²ªs§õvbÈ·èÓWu·ÔœxZ5f5½

View file

@ -1,44 +1,43 @@
age-encryption.org/v1
-> ssh-ed25519 iDKjwg ZUEOvf7JnWeFNohEAhloJ0+YL2SwHujjm2YG85NLHyU
HwrrqLMlNmfSlZVt/lCkIwqmCYLARbDOBhIm+AYmDEM
-> ssh-ed25519 uYcDNw Lrek6ru/vb2JIZyALem40oNZCf3ia/U6sb5hRyDaakA
N34LLq2+qJOlbyaYXUtNP17fDPjF+evgZ6kOs7mVhYI
-> ssh-ed25519 iDKjwg vLO2012STCeqJACpBNg5uKyWx/u0Yfvwxek3S+0Q1C4
6vPjunf0CQeWTwznZXPc5iVL/eiF7SrPqGeuvgcfizM
-> ssh-ed25519 uYcDNw QwGWHxl6dTO1HEfw7pEtdvb2ne0RiNMb8SkWRIrRJQg
ffdyTEltr6wlrnA9isU17orFvSRmicPvX+w2t0QBJIY
-> ssh-rsa f5THog
jmwJ+hV1/50cWemVUhPTkTFgnd7iJ0YLtjU4fEKXghWIlie/OR3AK++1f2UJxKT4
Z/32ALRBnmb7FlAPyYbxIns3IUJP+Z/Il5SCeDrtwaUxmtluwXwwO07WlztqZJlO
bvZ0ifDazxOFZO6QfXQE2SaPDOqcH2AAiiL50eXMgbdY5lARYW2Qbai/2a4t/PuT
Qn8WAwjyXOIdOnaYb/MZWyp0GQYsa3nEhYyOWvTSjSROEfR5qBtGNYkUBBTYF+YO
DGOYStbPSkIhnYYQmNajlcy9wMW5fH36ujGdnMH7C6DgcSCY2iTDTdE3cyCxAuaJ
bRThKyXYsvhMKgrFzbhlgt68taESb4KcKcNO5r7lqqID/I0b/fVltsKpkXrSCB53
Th/aXLXPUrYEkbdP6nqDBbUjeA8RDid1raIF1O29Ok72oU48q50QXqP8GF+honkg
HSdXmhPtlZyArlJNWogDaU9FkWp81E0JS8G0OnoNilCmiu7sF717GG4pkA6GTnaB
hlJSiVWBPhmhVURIOKkRl5bIWLUvJESPLVVog/vsW7OJETOb2u+AlwvaBNY8w1wE
An+m/qNO/H9Nksw0B4C9nLfasE/nDvbOT/Igc7k6jP0sw6/PAWnosJY5vDyIpR8k
7q3rBPnsZRXUr213ue8xs0G7SsbLheYNu3/D4YdB1tg
XjKRMzLPZlrTQEDJzgCwBbjZwIy6fMYGLuBR8TS15SAIbttLoikF/AV5zqJDaE9j
RaRJIIQV6LYCm1fHOsoua0XGxicvJkdithrDC4zsEEJ5n2luNj+sQd7h9ruOdkO5
l+Og+MphPM9naul+MJ/DluzS863DewkCNENEWe5H5MkHujOoqEsRsGdrRPXUbAPW
oNIr6h7FHCTFTkxfj1aAqDHdK8R4Yqo2K0vnHHfNS3PeN+CQJOrGNzokYybMRxqK
RXoJD0QKAUCV8cdXGr0XuS/ljv0lFODKhupy5ObYU71052nxo8j7KTq2NpZXqjul
PWyetcPtH5nLCs2L31XoBk7cEE8g/eSjPky3gSMdjGjdB7qskmuPcAHlHEwQzecG
D6J1LjrPa8OMVD4AdR0KAXSnSvzt/RhyymiZWtBeKg52rm4KK3PVbJqq05m+PEYA
a8wFT6fJOqmNr4gj4peIUHca0gYWhfzhLpXsj4/MKTPxzdUem/wbbMJrM7oQpwma
svN0vvqCUc2wfw2Apr3WwoAnNTIohZOngNkKNWNweXtPOee2qgZO3ko2wpFa+Yh+
IMonHHVhtdchTidx4RttgDIaW/+i//XGfqPdmanO5wUmm+SwgqkkQkRHzmtbmgsq
KlrAmjL5biH9f9sBItYMdKafgyQppMAQ3hXt5wgAgj8
-> ssh-rsa kFDS0A
BwaozSAR0Lcn3ZOHhC/OuOYRZqW0ayV4kL7CSLgaw6x9WqA7NLcsE+HDr7aDx/lP
K7TmFGYMrOiIk3siZ4Qc/JwZXPiayxGITcwoY82L+FrJKJmQd6c/3exggsHlc7B9
1ijXoQgjnorlopI70Cyt3QLQyMCPFb7tuZFEKR0NqBzcFTi5fKVYcMrfa1WVxzMO
0Ic+mhwMIAst6SQqOkqaVbtUYxATupQx+9FwThk+9NDety1vacb+lQ7hvCnImpTd
uENry/G68I7zWhNuCeE6wj8lCplFkW7dvrJyoxUVokWheFnUKjziA3ZybfMyAmI9
vJZnTvTc/7UxJCnuk/pB89q3ttm8LFT6AFAwZ1PY2ndWBMRlnOaB0JXSBKXZCYYV
bmJ/NSNdzyO9Q4MrKwYO+O8SOkVWM9EqKYv+FMO5CksU/N9EOUkpZeLpMYh1WXPX
BMKmXzRWp3YEsFH0g74ZBjFpTo+FK0bbRfYfTj7wtS9LpOFPr51qRDwv0zocM9cQ
MkpNtuSqpXboCLGytJE34pAsDY1BHJpdAOwlwavwK8N/yxlF89ktIAtHpOaV5QNF
r8oW2DLERj/s2yunrjZ5kQXaxbn2GBeml5gFyYWPnKVIa5x0PA6LgT2OMYd2x4vA
r7UGlMktJLosJGjJEUVLUHXarKkTz8Xwrw4vtaaLIyc
-> piv-p256 vRzPNw ApWXG3ayudUSrW8zw38cU6hYVeCVZhIQm/ZbjKpZqgnb
NqaQ7bjTAuMei08uNpVaK23uVmspjlkGyleF8phudVM
-> piv-p256 zqq/iw AxdOZ9zfYgKZJY9HhQokUHwSKbfKl7i7X+FPO30EADcr
qsniaELyEVrTeSaJG/lp3sCPCmbTUA7CWdMxA9tsBXc
-> ssh-ed25519 YFSOsg 64fhQVd3dvwHCBXa0QiK6E8rYA1jScm0UiBvJVuL6Eo
YAvXqNw6kQkTzBpDIboqa9gOoTgHE8hcaIMTg6UkODs
-> ssh-ed25519 iHV63A BlO/mSeyxTFBIa77g0Ce2CcaVf9SAiw9/OzkgnaHEV0
sjmnXCpwe5KTgIJ1ZaM8j1U4fYi2Y5/WpwpUfAe8Dbk
-> ssh-ed25519 BVsyTA gt6iV6mhL2G957w7IbJVzNFV8QMHOzP5uOkgSp5QgzM
Vvz1jjLKA9qbqAE1g0UyHySrrnG16ENdz9TxwyoML+g
-> ssh-ed25519 +3V2lQ g453jshh1sgCdUyhg3jlU0A0X+byL5jobpu2toWTYRU
S2k6Nk+UBv8gcJZoIdZUc2Kd+Rv4jzzcEyGm+eb+KUg
--- 8ahetWGfwjnJYRnkeSS15sLjDBBtN28biMlYCPSvObQ
icü'ióë4Aî6$}ß!IÚ3ó¨ÍÄ™ Ù3yŒ<79>ç¶;¶ƒ
O<EFBFBD>.<2E>œ[„Íf%jTà4ŸG¶÷ãÙ¸W#iÐzuä`'Á*zmû‡òèE‡6ÓضÑúéª[ê€
XAY8GSsx8B5q039L14C/t4cGK2sAm9eqO33r//YgpI5nkvw+pZrbJegdCItfHXHd
9BwBGOowTe5Qmj6RVfz4rwsj57HJbt6ivoIrU3vH+GLsNs4JIg5lwz1/WCsotw6W
8jQXiiZbA4nvzQzyZjJVKavTCfvbRXdzc+CUZiWgQDXsSFejp3ODeOvUds8YKWiz
jYILyzUzyAf05HDC2SIUhfA/UoXokfpo6uZuryWXjRBgaRENa9csDnktc8V+61W7
gUnu6yt/rN6oiBesnUZQK4sPd5YE6EcOT2gtLp1qKxtRuF9TEX25oLHi52kPBu8j
TNGbCU2ImGW3Z6TkAj+/XQzwEIrbLgb7APMkI3DtWyIIxZn5QJdDOOCseKMKt2Lu
VH1RF9C26mqcx7+WGCJKylARX8sbT1/ZsCWSUnmenYuGNQQppMwcQGSICs0YmFkH
XnV19+pt93i5rVFs9IUxFCqFKKjElCiPgIHe0QlGuxifeiMXYuNi8g4ObN5X6GEL
MPm0+sr19dheOZicyxqJ/jSlEOP8bHgN/VDHjKtsMWQD9r3NfLH7btNjA8HTITDI
YvLLVCP6OR3ZlMz2HUXDpbaPYSSZvrEtwkqCIe3ij6066Y5cTsYHWEwOvXaKYh9P
OJtPgLQDV9VfU9hK60E+C5qGQAvHhBgPUfXS8JMJkyw
-> piv-p256 vRzPNw A2vUnNzWtQNNOU//b3muMZeM1qdO3GyREn73VgdxMX4Q
6AzSUdoPB4zMbFsf0fr6sxbCsg+5/qmBtkCo3ry88Gc
-> piv-p256 zqq/iw AwVuYkScYFB1OzvBz9255ebDwPO4o8szD79gPnzgK/t9
UCm3jzlAPdfGvxO2VrE2DBvcGlaJpMTINJl2qcq+4oA
-> ssh-ed25519 YFSOsg wUzSRyoZOde45Uv+KaN/ARAxIRt1bPAqN30P6nM9b1o
pmufkyRBD4BoL4a+dbS321KSdjPRrB09MssNU6N0dtE
-> ssh-ed25519 iHV63A qyqt+LHR4YGE+P2D2mq7qOS959vLZ9K2yalLvGg3riw
1oDuGVg7Jn+8MIlsHb8KCDImManVGnlIMoqFt9w9Wjg
-> ssh-ed25519 BVsyTA skF/Np1FrFUSWJgCw5PN9uSy+bMezPHV7lH4jm67TCc
QrtBW86S8cB6GLsw6LVGK5jhFQS56MvATcPspGJwmAE
-> ssh-ed25519 +3V2lQ DPCBFzgin6QTJx0QZ0+52qW+6xXmGA4M+hFEIFAvpC4
QuuoukU5PC4BW2ieS52rkGcPRPuvrROE37gZpd7cudw
--- fVPm/8JI93qQmr6bEdb8JEtRpKtsBHnK88A1tptYLIs
|9Á:\ÙŒèHÐ(„•a-[çf„-Bpýu[€,¤bz¿ö'jA¸á yp`4üð“ï<E2809C>lÆ•|—Nj3ç ;”˜¾¾)“±ëGȾb÷ÿ¦&ÓWãF/ý±yõ¹

View file

@ -0,0 +1,43 @@
age-encryption.org/v1
-> ssh-ed25519 9RQHxg dVdaiC3H/M+tA/xIW3NdwQax68lkydLDLm6OxTx1lSc
HRLezYbdAPHNbQm/2WXT16wVX+ZC7GKlVp48aIECsdw
-> ssh-ed25519 uYcDNw SqHkg361mGpjrcynYld45CU/jfnPp55bt75apCWlADE
Z55QoOPVt2u1d5Q/96PHfA0MFAaO4y3CWuJNBnVy2IU
-> ssh-rsa f5THog
yKfwc4z4mIVfDJW5aEk7O9ddRL0YKOZFV+xKE6OyMGv6luJ+yM3QcPxu9yppCfMA
AIreVH2/4Tn+WhYv0dQuVeTR7SLqfn+TynkfK6ZZ8NbjSZXnakPqNLtOWi6C8VIH
MAfTTg1NGOG7E3TGmMqFrQnxYdpIvtfeGaBfiMhGLoWnCzJOzVkZSf1Qx+ibor1T
ZtJGsAVoAqGlFoWNDNrlemx9/5qxARe/GSSUyKtEb8VtbvN2hgJeg3YAKBANYkUS
C2Py72R662WBKPSd8vZRaQEJzP78b+LjBPmF98E8EZcHD/L6I6QRirpD8E89nN8b
/vp/Ze2q5R+9ot2TIO4Q9TJKLs8uMYUNUImrWQM9eBG444dmuTNDDfBFeI0Xwwug
FrHxS5pE8QzRdla/fIt/Py02F/734pb1LRCBPaLr5F7gFTBtIXe1TCvwfigiYrZ8
3zD4mpasIz1a7MlOIBIUuNAvAvJIwemenzxoCPTJUIPR9Ja06JUJe0qe/qOOaUAE
iio/a7XLYAUnTqHQ8efufS7RF8HB61Q5/CEtjE4NnpaiZkG+KQ57xjTwrfKSALxK
FN5ydIMY2aNg6Hh+n0MlCfpV2N8XYqOF4YWWRKY39516i8QCvvL21k+lt3P0Lpad
E5fn9FWoLqJw+evJsF/PyTrLT68tQbcY90mIGC6n/Ww
-> ssh-rsa kFDS0A
dTkAwE1+eD5KvpKvI0Wja9vV3wgKogv9ADKyf/u6meetXQ0isUnqxhqBbQZKhVqU
StNE4dSwg9gBwsPmNXJ2Avc9LMIBuhDomPOp8bqdO/r0IyDvJ+TngnJsroK7dfL5
foIDtakdAOVZM12ytm5hZlUNfXppAJUF1T9w5LIBWAMQQYJs39u+RrLfHoIvXTor
OvTikrdYfGiWdX3XIGQAfoPct3ZEKmD76ypH8ESw8kKF7ZfRQNDDP3LMbakoFs8K
Jrh5S9e3b5hdiDsv0DFtMISm8l6ec2mhhkVhSPgJ0mZYimMUg2QW1b61aTbE+LEI
K9O27ci1UKhxvLnxA3UWrYcm9SX3dvFgH8c+hJDdydHRGtMA3OU6Ut2HuGKaLfys
P7F7gffBTEeW2na2I00k3/oq9CCT4AP1d/CKlGd8ZtRvv5Axv6ThehCFZ/FLYGCg
kLBTHCX9qfvltdkKHIZwgxQ7JSGvNf/4bBzUz47o4gBhtnADaPondeLkqRS8sMwF
gq4UtG13Y2NfVYLtydrZCpUSMXekibZ8Rj2ER1uy1PD32clevgmgbTSyniSbJDa9
NFAeQS8KiyfvnxtLNNoMflR5yL2O4bX8Eo5ooaxILxga4M7ckcuKz2SMjDjpSBbK
ndwen9EsZuQwK9Av09h3gZeRy/t1ne6MtZrsTY5W7+Q
-> piv-p256 vRzPNw AyZQpsc9MqXbooqG+eK5gQQbfe4ka6pG7uixb8ONVGQz
FWuy/qAQidT6C8YMb3674epUzZw0Rb2NMCK5t9wdnT0
-> piv-p256 zqq/iw ApTqG55jHkxwd3cT2Hvw84V2DcoHo1M+q9eP2eLxSE2t
+27Dzy6pzGpOwTqUG17QaDC93O3PSJIfy/d4eBnuLw0
-> ssh-ed25519 YFSOsg mRmdt4AzDKbzKvMPOEHg+jQSRs2RF7f7ev/jzP7SuFE
VmNGaudQF6R8xDWBz6bFfmk2J8twCUEzcXj2AG5teKI
-> ssh-ed25519 iHV63A pXrKk8kpTBDxhiio5ZY7krRJIDkxYJZOMqCaW9Q7OGQ
9/xgfjzsd2JT6FQ2YWELl9jqph3+HTF8jChvbiHceJo
-> ssh-ed25519 BVsyTA z8nXuz2JOAn8t8OW+AzFRAXb5ulAuderatBFDrb6klY
Z+7S5aGCCV7f9WwHWr5LrsKW7rnpidImwoiP2dXcxew
-> ssh-ed25519 +3V2lQ p99nuu5l75p1y3Ea1yRdFBQSxvYRVRJzX1undANyFVk
QHzKD4WvtnRI0wgiaIYKWwXrG5Qg0vQ+V6eTJUk+A8k
--- od3JqYVYOFEDzaNHY5oDbfOjhUBsiQFd9pNGSkAw8Dk
øFJÒMmáž—>¿|ÉÏü‹µ ï¾ê0½µ:+‡¬¥U^ØÑÚYؼ÷æ/‰ŠwÊ X+8gtRNPÍ^\€N}«ü£

View file

@ -1,43 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 Y0ZZaw 5slOxDM4xGALMpYxFm1WBX4Sds7itgPBMIiY97d7Egk
mZNzn4I6obUHAdox6eVR4H82EZagZ1IrCcq0CDtK44Y
-> ssh-ed25519 uYcDNw w5lzhmA8wIMXihKF25d5jx4/Cc5BFE3Lw6ad60b0wBg
v9z03cpts6oVlcTQ48hMw8rjWHp1JUOov2qCUjFN4bs
-> ssh-rsa f5THog
A93Usdjf6yJFLFqDiy6UUIJ4faBgQXIvk0pZlABlj9M5n7fSf9uzR6sSih4HNCvm
sMkZ4wKyQHJnUB4Uc2jGrdcWqpmP5MLYHhj74Rxsi6heZuCRf94KH7sE/03A958w
jAV4v9z4EqmkvWLNQi/hxMVMs5A61Vs63WIX/TA6vhL8Yrn0FeIKlRZYUVIeMu42
pbEuLWeIzbUioAuEA1ZKV5VDx+6ack8TS/Dj5bTNEnzFWpjnHjO0/GeQU+aaQZTe
Zy325TcRosT0V7PIh0tDQZKKRpOH/e9LnDkd8NIjyfEsGdDYaP1EVOYVxPCqUDAh
A0kV1kkTiBzaXDkuakc+HDCIxtYXLWthsmbD+vI3D7FlTl0CY4fOP0wwO/0rS5Yp
KDuxjz89II1H4+ZvlcPUihyW7OEj4d+NwFQy+7Qq0Y9Ii0NONXNsnx17FKXJwOMo
NKyLo097FvHV7k8F9wv9mmZboRulDAoRyDngeO0+SJA90uJass04DuiZvK+g3Hry
xVzbkk59j9EQqUogopW/oSeSbUP0pvcKOahGcSIW8vmadDTgnN7zzqf3fq+dJ2TM
QD2IXAwvoTFBE+9DnPOtptk1X1D2umZuAWTzGAseXOImrPFZ+bEr5MV3qLGlg7sL
yA7Mvbp4diVdH5aePzeBefhxrYphz+yfCbELFTYam9g
-> ssh-rsa kFDS0A
Ng0FhTDjASWJkrlNh+UZxU/dU/wfmoV1/fwTv6Xg69k/2qU9lk0oR6e5xAimvX6u
h7rKAYt3zSRIFveGczPCflC1nycG9wLSpaoJghav+q+muoDQ/fbSKSgHFXITC7Me
f/wblyWvJsUQbjxSW3g6/8EGz6FvpTnycPtD2vbRj+Ctq72GPA2ZWg/OC4jAUlDs
r6X0Ql2jwWzy3Y12v0mPknlBezN8cIfjBmoNOWokUeGJIBjujlS7loA1yif09BLg
PTSLCY1YH3QYcm6lCXK0HaNcMjSSk/ZK9D0wROriF9PBbkpWgg5NlIrqGaeqPN9z
QwRR2DvhuCa1br57F36Y2LKGphYjmhWAtzCyQ0h9YQ+AzEy9uFCbK0IFyyeVl/fN
+HBGgxacJBcEGsNV3mbJvh6dn1348eex0GgaQEf1B/lu/y66WHbmSqVyUDfWkqEz
IytAC43VT2rKgg+B5u0d/JhLDLwXTp7iVDy52ul1n7keJHk8t1GDaufAXbWqalQ4
vuyxs6ghSIXUi27IZrYblg/OEPFTBfcoMXkmCgyx5a+eK+DhnBazWjy5j+vgp2so
ZQRQurbG02qpZasTwBM3iy4ZklX/uFjsKnk0c/YcmK4YcMviHcQQjdjKruEE93u+
Za1KE+qZGLkhFCd9O3ZPMtEjRjpN10XIs5ylKQ9MKU4
-> piv-p256 vRzPNw AiNjNIR0OGHBu5Qn+bvn+Lk5VnpI2BQ3eJ3+2/FTJfZC
elT3acRVdmtBl0qC5YbvfntxkJrsZwEJqlF6aN5hhWw
-> piv-p256 zqq/iw AjIzSibkqG+YcP894QekM61Wsty6MaKBghlWapHfU0Jn
HyXBp8DxtnNsfuzZq13bwgma5CzLTf3UB5Eht6XUwe8
-> ssh-ed25519 YFSOsg WRBQZZYM+X26hfoH4zvNWQulZvVWP/Ha5OgkUmGK/Q4
5Hw4ZDNawn5YRC673Op/sbpexOKeL3gez2B7oZxUKhA
-> ssh-ed25519 iHV63A wyr8R4DlqLAu0XypddVoFimK2ZMncWaa+KWV7vMEQm8
puV3g1t5AbnEgC0S1U4ft1evB7KuNppEi1g/AtxHgWE
-> ssh-ed25519 BVsyTA 0N3iyyGqTCRAHHcK7QfN5xRttorc2E2GL0RDTIVIBU4
Bph0OujqmXzi9IswduX9Mbh+yRdPKOwCf3fBv2zUzqI
-> ssh-ed25519 +3V2lQ 0p90VtsxWyGFaeeoTISIxQRyeKVk0HoGGq71tjpIPjg
sRf73Tp3BJ0DsTnJO2xVGyCKjaX7C7oydXj+39dKMUg
--- +/HCG0s/x+c03NG5qrgliJ+5EXXI6UnuJz5XDv2aphY
ÞšÂ<>™Ý@»=£L¬“7*®„ÐFq<46>UÒ*ûU꿉»È$e=þLgJ|*1ϽE ZG—_Ü5ê²ð—²ŽíÂ,òöÛi<C39B>_'¸d7 Ý3Ú“Nä3ãç¡*»ðªê<C2AA>£ŽáŽòqýŸ‰Oy#¶([l³†pÄf¼õ¾¥ö

Binary file not shown.

Binary file not shown.

View file

@ -1,43 +0,0 @@
age-encryption.org/v1
-> ssh-ed25519 Y0ZZaw tm4AmC8yXPgR82lgsQR4VZn4xfGiK8o6fIn8pKPY6XQ
IDnsYVD8noh2HdPNvjY/M5G+meR5rwvVI5SVN/cHEVM
-> ssh-ed25519 uYcDNw ZB7GyOvD8S8XLqE1AeMXWTPcJnvEntWbZ7TGg8CJVxc
Bfb/+P2DEiKI9ZWH105rLAYQXTUwWftWtudUGnVtjSU
-> ssh-rsa f5THog
Q3Hqks6BMGmP8TXnUkbblO8btrVdls7AUdxDW8e/w5biis/4awZVBHuZCLpiasM7
7RWXcUep2VVyfCMb+8tedaf5a1MpGPDkZvdbxhfDVWZakh7vsEnth+gK2QsV0h8e
eIgfDMA9J6DHXNCr4EYSf22PxY12KPqGqsMpVBhOZQuXoJwJy0ob3jbJEOYfPlu6
V+TLYQNGQ2UQ+A7zjpUrGz1L+u7rUejY4Rv1BmCakg1bLEs8oSDmIVmsuVmFPqOI
wqQJvnYlRAdioVQZwYCiqJech2QJ0ZhtC/ZeVp4c6TgFwB1ottxiAI8l7Bz1nFzW
/E85qU3Jkh1tcNcLsVHj8+tnxwn1SSQ3xQxcOT9l1Po98sNapK7mwd/xx3pJ1hH8
5YUQAtG80e5YmOBxkabVI4s612wACfK9JrIdL+uyIIzGeNHgoimjx7GuOCQ2ut6L
gj/+Rcv3e0ERkNaXTXGkcdrsMTt45lGmyxUgxz6lbHgtqq+r+BHogiQ9cdPKwXuK
wom4AvaMOBKCxtB4qVsuNHRd0I8OaA9Ab9SUvHCRvzCkJRHP4qc0zRJif7Rk4qRl
rAGYwVxq3DRk2HHCQCYC26VqLU6B5LuAAqOipVhOeTfbgaSGD6Wfrt+XBBPmWB7o
i9zDrk5GKehsPeDKgjh9uVd1y+IBHcWoYBxR5WPTYnA
-> ssh-rsa kFDS0A
HS3y8/5wAej0jv0sQqhdGwWd79vUwkrLkoKKPmqo9HlJaO70Cr1bnAIdyA8PBphs
NIRjIcdClbUBuelZudzuhHuEzH8/JMAVwgHoIiUxviEIr6JpJVBagtvSHp1nfDdn
x/hkpt2isSYb6fVzYgewqkdD3tv9XEm/WR2JmzlfaNTV9N9x/HNJYy5iYoTWRxKr
e8R7txdmgRaDDxpbkJdWBcoV9HVgytTMtvBkqGViWzaFDopb9nDlfN/C7/BkCp6H
9b65JqznpIChoJV7+sK5SEw8VcFj7ikIHzREWscEn8XBb7Kth2iVukaEPM+BgGZz
Irk0IdkSb/XmQFwsOLnQViwUjkFXGXwHyMdHIcU2qEzZ4PN0PgEengILt9vqWJs0
qHxrA7sKiC1D8S0i1+Dn+DiI//1s5Bbmp1jk626tH6fNKqSOlpwM47IGArTxCAFd
NMinIBnR47DUCXWheirsWF6yP7kwX7vOW1dR4UVJJnVPKkgjklwCZvJiNAo0Soo+
95zuugaeobsJ+qz2Pv+l8BGYriOFpRIAu7YTy9yY7mqHwC5MoeY0G8eNg5UmEzFz
JsEbKPsZcsMg4WdywzLU2aufK4M/Cd7lVPGZzuZ8hJHBF/EvTFov7L/HK5VnhZar
CYtILdyiVvmMZ7dhEARG1GG988W9wMendikmKpM4dTA
-> piv-p256 vRzPNw AuCJRxHGmvv25VTHpnbfMLyLIj8K+daFD97wwHvFAqHl
m4lPR+5h3+xmdL0OBfmNoxSM/O5Ca+2lVRLwITUtVmQ
-> piv-p256 zqq/iw ApNbp/6seWw6gCj/QWKLYlmuHaqdaSKVI+Hup1fKAO2O
xpNXgDXMVFe15eS+L9lGaI0Ip2F13SuhjCTQLDtBIr0
-> ssh-ed25519 YFSOsg v9BtvUZh5HIvN7nsnErVrHbWTwRhWpj/SlHoiiJSIR0
ol9z9juHfOCuZsSpuRl/zGFuJg5RzpKK1YnX+VDLDTA
-> ssh-ed25519 iHV63A yfa9P22C7+wCMqtRRSyiOhcFnLWPI50jMWxWpLarMT8
VpU+Uv/20JJGkTWTATiF5JImMsDKwyHMj+Wp0mMC/MQ
-> ssh-ed25519 BVsyTA dUj/mHSyOm61h2ETa4tSX7Cyf+KRN8AMXCVKwMbJTE0
E1EEPqVQSqlxSAi7DaMlaS1Az1D5XsasrPrIdwylSAE
-> ssh-ed25519 +3V2lQ AWBlXeuJq76UgQR0xQVPMN0NUq/mqa2iDlIDBBp/Wjo
XiliN4FB5YQ7qmTyV3AIbvoCY8UoGS6Vi5LpVWrH9kg
--- V4Tp84/WJUM+/l+eEjlypE4Lx47BtkGFpEnNIdIB35E
ô¡qzîL¡çzYNŽv×0[¿AöKN<ÛÀ<C39B>ö¦÷:,D<>¢S¹:!$`Õw©^‡àŽhi†O'(ž7!=ÿC(ÿï>´ûDоÙFÐ=J

View file

@ -1,43 +1,43 @@
age-encryption.org/v1
-> ssh-ed25519 iDKjwg t2wVQkkmL35JIXb3x9xxWmRECF7yet7c4+EdoFhCaAs
GJxaYARfYJdNDq6Ay81r4+TsTAMmPd7AxZMTq/GzuIY
-> ssh-ed25519 uYcDNw LeXqaLu9EylzTOle7lma4la5S3NDPjALTybvV2ppd3c
JCdLMyK1c+Sldqla8dVUDK28Zl+nLXnsh/MXQ4d/yJw
-> ssh-ed25519 iDKjwg vmr542fc5ndYRiW5ukHanhTMBV4TgSduloYjuWwmpw8
ACSBzerGx8Rd17zNfgO3qSqwBuQio9oyYaa5ypUbBxk
-> ssh-ed25519 uYcDNw fjP84i8BsNOfBoVDpH25MBC6D3xPXwbbO9ghLKr+mE4
TRKHWqVvzLP/AOJ5SJ5qeKj6UdYp2+tsxO/GVRy+qt0
-> ssh-rsa f5THog
ePz4dSiyFwtX5HmwF7/vyXKAwH52aVfjwQcyovl8r9srFt2o19MLkMvPM+CVXXo+
v0Dc6dNdfp6Oyn4rNvGMNtsL7Zb4B32OVck/uGn4pI9aC3wsOvr1JvetolaepATG
vnxB+TYjM/S/iYpxaKbrhKBOM466dUygI4bS/GPT749+R9610mZ+jle1yylyvRTM
WiTJaNbOEKOnwPPgZdBbZEcisbz5BFJhVHBxxd/1DXZPRBeg9Xn7514IwbtRgRS2
x6gzSDFZBcpvXQ/g86JveORI9eoS97w1Fgv1bJnwhoZ3yebDThPnP0xU6I64nCwJ
H0W+Rrutq4UgMkYghElCoFyunPz73M7PArzW44PPCOeGUrVDsqbTgf9YD5s3HDsc
TZqrcgzY6/cLzulgM2Is5b4ZEecWLNGoe84sjHR5OXneGf9BXcB5GpgWIC//ZFym
Sr/UOlfI0YtZpY5ph/10uWqi838idwMTjOZGuope5T5m8+rsbxlwAKRf2E31nx5e
rjW4hdV4tm2yZm+E75FEIo1yhu4JKm+MCv8ri8217c2Ex/qqDQ5pi/meOrjKGFgc
7FKkg2h6ir1rh0bMYTpZAelpKVicTQpY4HyphiFuk5cCt6cXiEMiwRBm3QrwmSvl
KcmXweuoYiunkb5q2GG6sE0d3yZluG7g5mPWE7WFngM
IMiwRGW5B09oJDDJamyQBOwtFu+KhxUQQ1w0RJEnpITZZzyfHOuhAuwsjLy+us9v
znzSA7bo1YusdFjzfW4RZeueuW8vvWdsv9Cjadlg6Bb2uP7sWeh7qH+IoyB2Z9Kt
fZ0O6O+65pOybsCKZ9cUuZ+E9E5nG2KRjzdV+csEKAshGLqeo2RILKZB8oSx9tZr
sjPXRFLchj/6zbY1yBs+q0+qC7ldUBdJLDtl5Yj6hzB4fk1JuPTSDWtKSHBYDz60
Ri3CO1Z0z+8/IJWZqaa0a7jCYH6v4ZzboGrdE7MJq6Tyorl26bitSSevXHJmCrJq
ZpcpZfs/kVFu05ftaVul6vyPM09QOIQx+ia9tIKmCgWNcrM5mSy63C9klutXOW6j
GZ60YUnOvVDz+i0wmaZvMs3C4THhdtOsln/dVrqOKFKf704mAsO4cSEwqNyoXy7n
/WbxDQcTU62pKEkwlU//CjuA0rHwmX8m/tweNuokh8fPJ6SLE9dLqxPzmeq9JX7q
RNO+eZZ2NnjpkrI46stVS3p3FUHPbk9mhIiyfr4LgSBCoNWv1TkLS8DOqWOeNKfy
8wLAjgvpNIk8Vgbhoe4/G8wB5Qvr0vfGmdjzA5miu28YZ8PXHN6DlkaT9T0iROuZ
HM8j2FND2EYLB/Je19ctYNDjCmEYFhsvH/H448QMODw
-> ssh-rsa kFDS0A
jvdXdLAU/L/dD6bmuXIXEaZIGAEOFTujxuVy7oFHSeAZk4AyT2ZBLfuDa1KI3iSR
19hImXIZyaQJh5RSTkEHpwdsxexbzcQV8y77XdF2neNj6OYjMfpP8a5foGcu9Rnd
/DRSkRNumkTfpet/gSiRIPz0Sj++HA8/X3GwRlwqPKE12As06ebL76003NX/u7ep
6jJR/sOlLJV2VtqU1tvgQ5VV7KIyMTlP2a38MDCtOHTVmK8inVNqL28H0ptYJ1IZ
KId96pKqR0v+h/qhHHQoYBJxCBUHc3Rp8eZdssLpLfRHGLQ1ccpV7KUr4ihKFh+9
wu5/YD9qrQls1EjXi1mj/kCvT2FplUJEZqgBBRY1/mHjpWmx999E5QijjhWchBL/
PgF0oF25MABESrm/edvThwp7MVTA8ZSY8xj40D9bfsBGrpVBlf5hKsSulpiaMQGK
6ScH4sRFXDhwC7j8OOMZWcqNvEc3KjgjJwl+qFTXDdBe+zd5sF+orjORjIge1z3c
v2wngm6vTX4GobrtqiC2ZmolWbRxz7a4IwWNPrmEql8Bnmf1bfRy4X5/EOuIy1zN
s/3Qu0KjjVBikU60RyXAdRI2M+aCKSKushp7bThT2j+VJTGIsmEbG190VjChTkmb
meF98Mt2uJoJjzCYdyaGCQRWAr/f8ER0GZgLXS4Apt8
-> piv-p256 vRzPNw Am/95gSJXOtEBedzoMQBFwWC4E30vZcMINW5JjeM7ot4
TzGZSlKt50OxQryrIQHSqMj+dnIDV5+adfohG9heDTs
-> piv-p256 zqq/iw A5R9tfUoQmodbn9rt0M0x3lnJUMz02u66HR4+RTIcU6/
D9JRgjM280CDu/ds6j4lequ3VGEwz2aEYf6Pu4e8Hf8
-> ssh-ed25519 YFSOsg 8YXBlEpaC0Vkewf7awp/RuHxaV92jp8Lnf391jd8UDc
9bzGios7kSFpAKJbmjupcpf7/BCn6XwQMDfh1uRb1qs
-> ssh-ed25519 iHV63A 2WrmaliPbgh0rJLJJkgy1sUI4S0H07PwZ9oJNk5R+z4
SdjvYKOlZLClUKs+KUQ2ek4X7amZn56Fcfo0TnAeTO4
-> ssh-ed25519 BVsyTA +RlXlmh3g6GLA7W26NmDEd4fRSVrJ8lzY1ZZ8OuuT2U
+quL6DjgTibaE878QG9w281ArQ/9LS5467Nfm5TiADg
-> ssh-ed25519 +3V2lQ 4B1XgSPLOVjzzNlxNYmLeIxABUnXcvETOOWlaXnmgRU
bgdGjPihq6SnGVWsntPhajgy4sLD8c6VWSYeSlllUx4
--- LEtvqKl5+C4uRIigcNFI3hVXkxov9Wt1CasYuMvEpvU
¦V †ãCC{ËË©u%ŒÒr¤37ÓSG6 ¤(Eëê1¡ çìàmP©Fwï¸
nSuC6Kgnp3+r41SXWEqIkryUlhWQTl5Qr0muXhnsBmuN+2iVBGYFqxqJSDpdnvbM
SIIy5c5rLfGSNRejRebgvyCntEvrOiGtmgubpURMEaXwJiEI+Hqfju1V8yi2RUto
KTR/YhYv0i50pLMV4JD7MWPga/zeYUVhE8eISUNFbiJS+ve3BP/3Tg2E9tUvTsCG
j7MxM4Td1jH2jCa7ueYOJ0R/qr0BKIEOGP4e+7YCByujYWKTV1JHOZehzIYA5wFs
Bqq7GZnTTiP5n/kh7CgNyWORdBW4gaBslyhjAJI3hCbBvZer547K4moP6aPKog32
yTZQVVu/kZzCIgA/4TzWr/g11fKD0dUnPCmXbctQVgeOtYAbnWJBFwMmXvQdRU2P
jt5Ce0WqwhExaE8fAx7v3AYXhYgAOBem4uIe34PAuj672Tc1U61hztSCynE2cXI/
2ZyCoWZZC/4fjUTFXC8urATfjgGV5PrhRcU4JtnQwytjd0Ru4pm56zZCpzmHxWMi
bbyVSF5NisCvjF5rxyS4XXNfg52fkV01gJsJ48B9dnSs5HYTBaWQWJ00sO5ssGRm
9H+T/Bsi42X6lnlt8ybzYD7aDIJbfz56vHf18/tfRhOzYbIBE7Rnkvs0vsNwT05K
OGOb3iLFtxGGIpSC5Ba1T8h1TuEAawhmrHkF/Lfdr8g
-> piv-p256 vRzPNw AquhJELiSYcW1KeKiied88TcDZYgtjdZm46FlV7CRsmt
ikxq4EIkI3UXqjns1QJdAe0N3mEh7sbzYPu9H0IvmCA
-> piv-p256 zqq/iw A94RUts75asVyQG7IZSfg7mDgcWI/hruOfRqD8Pdn4Ff
17kI8IKl98f5lMqdcvqpTO8EN7pr9HP0SJJxFlIMcrw
-> ssh-ed25519 YFSOsg gvcjFcWsCaBjYXvab/eyIhDhfw2bjc3u+nOenGiebTc
hi30KYU9aYxWG/ZWFZQ4qW/P+hi+ms3140/9BTYNo7k
-> ssh-ed25519 iHV63A RVCt2pceoQfdaBWd5qXcT0x/0dQgLP3jKpa6xeDdnyY
Q1arCu2nmcl3Qt/uqV6UeXUf/OffvNl7ZWtqbWjrw4k
-> ssh-ed25519 BVsyTA DX/5O7PCLEBoraM0qFy821i8GZysh2+XhR1fGV50SCw
hN/a4NwiX9oySM7Uyt6vS9hjOTHNbN3tF9DAHF0vDiI
-> ssh-ed25519 +3V2lQ uXmSWC+gV5JsARpa8cDv6faykEoYJHH0TqnWc8yzhQM
/y/94BU9Mwqcez6y2tJoCEkg8c5x9p8FkUbbhUpKh9M
--- SA5BB1izTywLQB/5ghs3XqlOzr0ag2gI2/09M3eVtjY
±µ¦ýE¨Õ8SLJðZ½Ð°s\4Â#ÏRB rç|eÉY/ü|/ .B¹ <0A>ÖÑ

Binary file not shown.

Binary file not shown.

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