Compare commits

...

85 commits

Author SHA1 Message Date
Simon Bruder 758502f606
librewolf: Fix browserpass
Thanks to snd for showing me this.
2024-11-09 23:27:58 +01:00
Simon Bruder dacfba1921
koyomi/haproxy: Add missing vhosts 2024-11-09 12:35:47 +01:00
Simon Bruder 972b1db287
programs: Add signal desktop 2024-11-09 12:29:29 +01:00
Simon Bruder b38ff867bd
vueko/mail: Add alias 2024-11-03 17:33:35 +01:00
Simon Bruder 3e48cf2027
vueko/mail: Add alias 2024-11-02 11:03:42 +01:00
Simon Bruder fe4a9df4dd
vueko/mail: Add alias 2024-10-27 10:19:47 +01:00
Simon Bruder b8dd3a3d2f
vueko/mail: Add alias 2024-10-24 19:47:24 +02:00
Simon Bruder 7153722d5a
vueko/mail: Add alias 2024-10-23 18:27:41 +02:00
Simon Bruder 7c2491ecb4
vueko/mail: Add alias 2024-10-15 21:34:18 +02:00
Simon Bruder 69223a4aac
vueko/mail: Add alias 2024-10-13 20:09:35 +02:00
Simon Bruder 02e74f1915
sbruder.xyz: Remove transparency location
Its service is no longer public and therefore no longer applying the
blocks.
2024-10-12 12:34:49 +02:00
Simon Bruder 915d2ed7da
renge/schabernack: Simplify and migrate to yuzuru 2024-10-12 12:32:56 +02:00
Simon Bruder 83b12e1977
nginx: Lower default error log severity 2024-10-12 12:32:37 +02:00
Simon Bruder 70bd878298
Migrate phss to hiroshi 2024-10-12 12:31:45 +02:00
Simon Bruder 5975cfd348
fuuko/paperless: Add manual scan endpoint 2024-10-12 12:13:18 +02:00
Simon Bruder 718e647cbd
renge: Permit insecure olm 2024-10-12 12:13:18 +02:00
Simon Bruder f90ff9690b
flake.lock: Update
Flake lock file updates:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a' (2024-03-11)
  → 'github:numtide/flake-utils/c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a' (2024-09-17)
• Updated input 'home-manager':
    'github:nix-community/home-manager/e1391fb22e18a36f57e6999c7a9f966dc80ac073' (2024-07-03)
  → 'github:nix-community/home-manager/2f23fa308a7c067e52dfcc30a0758f47043ec176' (2024-09-22)
• Updated input 'home-manager-unstable':
    'github:nix-community/home-manager/c2cd2a52e02f1dfa1c88f95abeb89298d46023be' (2024-08-23)
  → 'github:nix-community/home-manager/038630363e7de57c36c417fd2f5d7c14773403e4' (2024-10-07)
• Updated input 'nix-pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/1cd12de659fab215624c630c37d1c62aa2b7824e' (2024-08-27)
  → 'github:cachix/pre-commit-hooks.nix/1211305a5b237771e13fcca0c51e60ad47326a9a' (2024-10-05)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/9fc19be21f0807d6be092d70bf0b1de0c00ac895' (2024-08-25)
  → 'github:nixos/nixos-hardware/ecfcd787f373f43307d764762e139a7cdeb9c22b' (2024-10-07)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/2527da1ef492c495d5391f3bcf9c1dd9f4514e32' (2024-08-24)
  → 'github:nixos/nixpkgs/1bfbbbe5bbf888d675397c66bfdb275d0b99361c' (2024-10-07)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/d0e1602ddde669d5beb01aec49d71a51937ed7be' (2024-08-24)
  → 'github:nixos/nixpkgs/c31898adf5a8ed202ce5bea9f347b1c6871f32d1' (2024-10-06)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/be0eec2d27563590194a9206f551a6f73d52fa34' (2024-08-12)
  → 'github:Mic92/sops-nix/06535d0e3d0201e6a8080dd32dbfde339b94f01b' (2024-10-08)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/556533a23879fc7e5f98dd2e0b31a6911a213171' (2024-07-21)
  → 'github:NixOS/nixpkgs/17ae88b569bb15590549ff478bab6494dde4a907' (2024-10-05)
2024-10-12 12:13:17 +02:00
Simon Bruder 7a0deb214c
vueko/mail: Add alias 2024-10-12 12:13:16 +02:00
Simon Bruder f73e7b4cbe
fuuko/paperless: Enable advanced options 2024-10-12 12:13:15 +02:00
Simon Bruder 4837424909
renge/mastodon: Drop
I didn’t use it much and it used quite a large amount of resources.
2024-10-08 22:45:01 +02:00
Simon Bruder ba8b4cb918
yuzuru: Remove salespoint typo domain 2024-10-08 22:32:42 +02:00
Simon Bruder 7b7b4fb0ee
cups: Statically add bro
Dynamic resolution often fails or at least takes a long time (for
reasons I can’t comprehend).
2024-10-08 22:31:55 +02:00
Simon Bruder 733188ec5f
vueko/mail: Add alias 2024-10-01 20:18:57 +02:00
Simon Bruder 2692e34fb1
yuzuru/static-sites: Use YouTube instead of Invidious 2024-09-29 18:16:35 +02:00
Simon Bruder 3ca5a57043
renge/invidious: Document as private 2024-09-29 18:15:56 +02:00
Simon Bruder da37f01af7
vueko/mail: Add alias 2024-09-28 12:09:20 +02:00
Simon Bruder cb75197cfb
hitagi: Document SSD change 2024-09-28 11:14:42 +02:00
Simon Bruder 7882d28bd1
programs: Add simple-scan 2024-09-23 21:24:23 +02:00
Simon Bruder c6a6a8a322
shinobu/router: Add avahi reflector 2024-09-23 20:27:28 +02:00
Simon Bruder f0a5cef516
fuuko/paperless: Disable TLS for FTP
For some reason, my brother DCP-L2660DW always fails uploading the file
(but can log in via TLS flawlessly).
2024-09-23 20:26:49 +02:00
Simon Bruder a9dab10975
fuuko/paperless: Allow larger file uploads 2024-09-22 19:02:39 +02:00
Simon Bruder 1f7885ebd8
fuuko/paperless: Allow invalidating signatures 2024-09-22 19:02:28 +02:00
Simon Bruder 0cbdc22d4e
shinobu/router: Add printer vlan 2024-09-22 12:54:37 +02:00
Simon Bruder d678da8454
fuuko/paperless: Add FTP server 2024-09-22 12:54:23 +02:00
Simon Bruder b55cc2deaf
shinobu/router: Allow adding static hosts
This is required to have them available in nftables rules without too
much headache.
2024-09-22 11:27:52 +02:00
Simon Bruder f38e8d5217
yuzuru/static-sites: Add share 2024-09-21 23:33:15 +02:00
Simon Bruder 0272d67fb7
vueko/mail: Add alias 2024-09-20 17:10:50 +02:00
Simon Bruder cfdce40a92
fuuko: Add paperless 2024-09-19 23:00:16 +02:00
Simon Bruder 29f1052795
vueko/mail: Add alias 2024-09-18 21:37:48 +02:00
Simon Bruder 89253b251c
vueko/mail: Add alias 2024-09-14 10:03:38 +02:00
Simon Bruder c4ff8674ac
vueko/mail: Add alias 2024-09-10 20:12:25 +02:00
Simon Bruder 99f0aad1eb
vueko/mail: Add alias 2024-09-08 13:30:27 +02:00
Simon Bruder 33436773a4
restic: Lower backblaze mirror interval 2024-09-08 13:30:27 +02:00
Simon Bruder 1137b7ba9a
hiroshi/li7y: Migrate from yuzuru 2024-09-08 13:30:26 +02:00
Simon Bruder c65077a15b
hiroshi: Add postgresql 2024-09-08 13:30:25 +02:00
Simon Bruder aa0d1752f6
Add local mail service 2024-09-08 13:30:24 +02:00
Simon Bruder 3e88ea9241
mailserver: Allow restricting users to local domains 2024-09-08 13:30:24 +02:00
Simon Bruder 729427f68e
renge/invidious: Require login 2024-09-08 13:30:23 +02:00
Simon Bruder cce1211048
restic: Add mirror to backblaze 2024-09-08 13:30:22 +02:00
Simon Bruder a8d170fd0e
shinobu/router/nft: Fix typo 2024-09-08 13:30:21 +02:00
Simon Bruder 799ccf2b8b
flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager-unstable':
    'github:nix-community/home-manager/afc892db74d65042031a093adb6010c4c3378422' (2024-08-02)
  → 'github:nix-community/home-manager/c2cd2a52e02f1dfa1c88f95abeb89298d46023be' (2024-08-23)
• Updated input 'nix-pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/f451c19376071a90d8c58ab1a953c6e9840527fd' (2024-07-15)
  → 'github:cachix/pre-commit-hooks.nix/1cd12de659fab215624c630c37d1c62aa2b7824e' (2024-08-27)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/14c333162ba53c02853add87a0000cbd7aa230c2' (2024-07-30)
  → 'github:nixos/nixos-hardware/9fc19be21f0807d6be092d70bf0b1de0c00ac895' (2024-08-25)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/05405724efa137a0b899cce5ab4dde463b4fd30b' (2024-08-01)
  → 'github:nixos/nixpkgs/2527da1ef492c495d5391f3bcf9c1dd9f4514e32' (2024-08-24)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/9f918d616c5321ad374ae6cb5ea89c9e04bf3e58' (2024-07-31)
  → 'github:nixos/nixpkgs/d0e1602ddde669d5beb01aec49d71a51937ed7be' (2024-08-24)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/eb34eb588132d653e4c4925d862f1e5a227cc2ab' (2024-07-27)
  → 'github:Mic92/sops-nix/be0eec2d27563590194a9206f551a6f73d52fa34' (2024-08-12)
2024-09-08 13:30:20 +02:00
Simon Bruder eea16ca276
shinobu/router: Add ability to bypass HE tunnel 2024-09-08 13:30:19 +02:00
Simon Bruder 4e84140d53
Remove fuuko proxy
It now is directly reachable (over IPv6).
2024-09-08 13:30:18 +02:00
Simon Bruder 959f7be3d0
Connect home network with IPv6 addresses
It adds a bit of latency (and is definitely not the best solution in
theory), but finally allows dropping IPv6 NAT and it works within the
constraits my home network has to live in.
2024-09-08 13:30:18 +02:00
Simon Bruder 771489a176
vueko/mail: Add alias 2024-08-27 01:38:52 +02:00
Simon Bruder cab22edf1c
hiroshi/languagetool: Restart automatically 2024-08-27 01:38:51 +02:00
Simon Bruder 5304fc78bc
koyomi/bang-evaluator: Move from renge 2024-08-27 01:38:50 +02:00
Simon Bruder 5693e6b75d
restic/vm-image: Init 2024-08-27 01:38:49 +02:00
Simon Bruder 0fa4e6d855
restic: Prune on koyomi 2024-08-27 01:38:48 +02:00
Simon Bruder 50823a746e
restic: Prepare for additional backups 2024-08-27 01:38:48 +02:00
Simon Bruder 7a72bf8b0d
renge/invidious: Deprecate 2024-08-27 01:38:47 +02:00
Simon Bruder d03e463a3a
restic/system: Fix QoS enabling logic 2024-08-27 01:38:46 +02:00
Simon Bruder b0898643fb
vueko: Remove outdated TODO/FIXME comments 2024-08-27 01:38:45 +02:00
Simon Bruder ac3fa39d2b
koyomi: Enable backups 2024-08-27 01:38:45 +02:00
Simon Bruder 300327d3b5
koyomi: Reinstall on AX41-NVMe 2024-08-27 01:38:44 +02:00
Simon Bruder aa8afd4d5d
Add kexec-bundle package to flake 2024-08-21 01:30:25 +02:00
Simon Bruder e9fce22b71
hiroshi/languagetool: Migrate from fuuko 2024-08-21 01:30:24 +02:00
Simon Bruder 79707438c2
pubkeys: Remove legacy keys 2024-08-21 01:30:23 +02:00
Simon Bruder f97c81ce2c
ssh: Add ci-runner 2024-08-21 01:30:22 +02:00
Simon Bruder 134d58a3c7
hiroshi: Init 2024-08-21 01:30:21 +02:00
Simon Bruder 69c4138459
renge/prometheus: Use common relabel config for VPN 2024-08-20 18:37:41 +02:00
Simon Bruder 5245fa82d4
koyomi: Use LVM thin pool for VMs 2024-08-20 18:37:39 +02:00
Simon Bruder b418a56e09
koyomi/haproxy: Init 2024-08-20 12:08:22 +02:00
Simon Bruder 11462ce843
koyomi: Add TODO comment for mdcheck 2024-08-20 12:02:49 +02:00
Simon Bruder 7a39ce50d2
vueko/mail: Add alias 2024-08-17 08:53:33 +02:00
Simon Bruder 0345000e05
Add cargo credentials provider via pass 2024-08-08 23:37:40 +02:00
Simon Bruder 391234776a
renge/element-web: Fix frame-ancestors CSP
Something changed in how Firefox interprets the CSP, which made loading
element web fail.
2024-08-08 21:26:14 +02:00
Simon Bruder 08e30e01cf
Remove youtube-dl
It is marked as insecure, and was unused anyway.
2024-08-03 13:53:07 +02:00
Simon Bruder e91ca8e267
flake.lock: Update
Flake lock file updates:

• Updated input 'home-manager':
    'github:nix-community/home-manager/391ca6e950c2525b4f853cbe29922452c14eda82' (2024-07-01)
  → 'github:nix-community/home-manager/e1391fb22e18a36f57e6999c7a9f966dc80ac073' (2024-07-03)
• Updated input 'home-manager-unstable':
    'github:nix-community/home-manager/59ce796b2563e19821361abbe2067c3bb4143a7d' (2024-07-01)
  → 'github:nix-community/home-manager/afc892db74d65042031a093adb6010c4c3378422' (2024-08-02)
• Updated input 'nix-pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07' (2024-06-24)
  → 'github:cachix/pre-commit-hooks.nix/f451c19376071a90d8c58ab1a953c6e9840527fd' (2024-07-15)
• Updated input 'nix-pre-commit-hooks/nixpkgs-stable':
    'github:NixOS/nixpkgs/03d771e513ce90147b65fe922d87d3a0356fc125' (2024-06-19)
  → 'github:NixOS/nixpkgs/194846768975b7ad2c4988bdb82572c00222c0d7' (2024-07-07)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/6e253f12b1009053eff5344be5e835f604bb64cd' (2024-07-02)
  → 'github:nixos/nixos-hardware/14c333162ba53c02853add87a0000cbd7aa230c2' (2024-07-30)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/d032c1a6dfad4eedec7e35e91986becc699d7d69' (2024-07-01)
  → 'github:nixos/nixpkgs/05405724efa137a0b899cce5ab4dde463b4fd30b' (2024-08-01)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/00d80d13810dbfea8ab4ed1009b09100cca86ba8' (2024-07-01)
  → 'github:nixos/nixpkgs/9f918d616c5321ad374ae6cb5ea89c9e04bf3e58' (2024-07-31)
• Updated input 'password-hash-self-service':
    'git+https://git.sbruder.de/simon/password-hash-self-service?ref=refs/heads/master&rev=df4244f6c960f041d5b4373d4c3b093bba4caef7' (2024-06-02)
  → 'git+https://git.sbruder.de/simon/password-hash-self-service?ref=refs/heads/master&rev=a09c08847b2539a069833d9ef72d74224c170a54' (2024-07-19)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/a11224af8d824935f363928074b4717ca2e280db' (2024-07-01)
  → 'github:Mic92/sops-nix/eb34eb588132d653e4c4925d862f1e5a227cc2ab' (2024-07-27)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/4a1e673523344f6ccc84b37f4413ad74ea19a119' (2024-06-29)
  → 'github:NixOS/nixpkgs/556533a23879fc7e5f98dd2e0b31a6911a213171' (2024-07-21)
2024-08-03 12:26:36 +02:00
Simon Bruder 8e6ca13338
ci-runner: Add codeberg 2024-08-03 11:06:41 +02:00
Simon Bruder 216074e457
vueko/mail: Add alias 2024-07-30 17:25:00 +02:00
Simon Bruder 528d94aeaf
vueko/mail: Add alias 2024-07-29 23:31:44 +02:00
Simon Bruder a8565438e3
vueko/mail: Add alias 2024-07-28 11:18:04 +02:00
Simon Bruder 9a3290b259
ci-runner: Init 2024-07-28 11:17:57 +02:00
Simon Bruder d7600be2e3
smartctl_exporter: Fix guard 2024-07-19 15:32:21 +02:00
84 changed files with 1935 additions and 681 deletions

View file

@ -7,6 +7,7 @@ Source: https://git.sbruder.de/simon/nixos-config
Files: Files:
.git-crypt/keys/default/0/*.gpg .git-crypt/keys/default/0/*.gpg
secrets.yaml secrets.yaml
secrets/*.yaml
**/secrets.yaml **/secrets.yaml
keys/*/*.asc keys/*/*.asc
machines/*/secrets/*.nix machines/*/secrets/*.nix

View file

@ -2,7 +2,7 @@
# #
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
keys: keys: &all-keys
# sops does not (yet) support ADSKs, # sops does not (yet) support ADSKs,
# so all encryption subkeys have to be added manually # so all encryption subkeys have to be added manually
- &simon 6CD375BD0741F67E5A289BC333A01CBE0554C763 # offline - &simon 6CD375BD0741F67E5A289BC333A01CBE0554C763 # offline
@ -19,7 +19,9 @@ keys:
- &shinobu 28677f2e3584b39f528a779caf445ebb39c882b7 - &shinobu 28677f2e3584b39f528a779caf445ebb39c882b7
- &nazuna 0b8be5d87a10a0e68dda97212c4befad1f9e915c - &nazuna 0b8be5d87a10a0e68dda97212c4befad1f9e915c
- &yuzuru a1ee5bc0249163a047440ef2649e770ec6ea16e4 - &yuzuru a1ee5bc0249163a047440ef2649e770ec6ea16e4
- &koyomi a53d4ca8d2cf54613822c81d660e69babee42643 - &koyomi 1f18a57e1d4e6716aed0e0cd71586b7a4c0c1a65
- &ci-runner 20e376b89b30327fb82f12e8e8b72d52c3aa39ee
- &hiroshi 2b9be9660662c6c979ca1149c982bdfd82863d09
creation_rules: creation_rules:
- path_regex: machines/nunotaba/secrets\.yaml$ - path_regex: machines/nunotaba/secrets\.yaml$
key_groups: key_groups:
@ -105,6 +107,20 @@ creation_rules:
- *simon-alpha - *simon-alpha
- *simon-beta - *simon-beta
- *koyomi - *koyomi
- path_regex: machines/ci-runner/secrets\.yaml$
key_groups:
- pgp:
- *simon
- *simon-alpha
- *simon-beta
- *ci-runner
- path_regex: machines/hiroshi/secrets\.yaml$
key_groups:
- pgp:
- *simon
- *simon-alpha
- *simon-beta
- *hiroshi
- path_regex: secrets\.yaml$ - path_regex: secrets\.yaml$
key_groups: key_groups:
- pgp: - pgp:
@ -118,3 +134,7 @@ creation_rules:
- *mayushii - *mayushii
- *renge - *renge
- *koyomi - *koyomi
- *hiroshi
- path_regex: secrets/local-mail\.yaml$
key_groups:
- pgp: *all-keys

View file

@ -44,11 +44,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1710146030, "lastModified": 1726560853,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -85,11 +85,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1719827385, "lastModified": 1726989464,
"narHash": "sha256-qs+nU20Sm8czHg3bhGCqiH+8e13BJyRrKONW34g3i50=", "narHash": "sha256-Vl+WVTJwutXkimwGprnEtXc/s/s8sMuXzqXaspIGlwM=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "391ca6e950c2525b4f853cbe29922452c14eda82", "rev": "2f23fa308a7c067e52dfcc30a0758f47043ec176",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -106,11 +106,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1719827439, "lastModified": 1728337164,
"narHash": "sha256-tneHOIv1lEavZ0vQ+rgz67LPNCgOZVByYki3OkSshFU=", "narHash": "sha256-VdRTjJFyq4Q9U7Z/UoC2Q5jK8vSo6E86lHc2OanXtvc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "59ce796b2563e19821361abbe2067c3bb4143a7d", "rev": "038630363e7de57c36c417fd2f5d7c14773403e4",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -212,11 +212,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1719259945, "lastModified": 1728092656,
"narHash": "sha256-F1h+XIsGKT9TkGO3omxDLEb/9jOOsI6NnzsXFsZhry4=", "narHash": "sha256-eMeCTJZ5xBeQ0f9Os7K8DThNVSo9gy4umZLDfF5q6OM=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "0ff4381bbb8f7a52ca4a851660fc7a437a4c6e07", "rev": "1211305a5b237771e13fcca0c51e60ad47326a9a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -228,11 +228,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1719895800, "lastModified": 1728269138,
"narHash": "sha256-xNbjISJTFailxass4LmdWeV4jNhAlmJPwj46a/GxE6M=", "narHash": "sha256-oKxDImsOvgUZMY4NwXVyUc/c1HiU2qInX+b5BU0yXls=",
"owner": "nixos", "owner": "nixos",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "6e253f12b1009053eff5344be5e835f604bb64cd", "rev": "ecfcd787f373f43307d764762e139a7cdeb9c22b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -244,11 +244,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1719838683, "lastModified": 1728328465,
"narHash": "sha256-Zw9rQjHz1ilNIimEXFeVa1ERNRBF8DoXDhLAZq5B4pE=", "narHash": "sha256-a0a0M1TmXMK34y3M0cugsmpJ4FJPT/xsblhpiiX1CXo=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "d032c1a6dfad4eedec7e35e91986becc699d7d69", "rev": "1bfbbbe5bbf888d675397c66bfdb275d0b99361c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -287,43 +287,43 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1718811006, "lastModified": 1720386169,
"narHash": "sha256-0Y8IrGhRmBmT7HHXlxxepg2t8j1X90++qRN3lukGaIk=", "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "03d771e513ce90147b65fe922d87d3a0356fc125", "rev": "194846768975b7ad2c4988bdb82572c00222c0d7",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-23.11", "ref": "nixos-24.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-stable_2": { "nixpkgs-stable_2": {
"locked": { "locked": {
"lastModified": 1719663039, "lastModified": 1728156290,
"narHash": "sha256-tXlrgAQygNIy49LDVFuPXlWD2zTQV9/F8pfoqwwPJyo=", "narHash": "sha256-uogSvuAp+1BYtdu6UWuObjHqSbBohpyARXDWqgI12Ss=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "4a1e673523344f6ccc84b37f4413ad74ea19a119", "rev": "17ae88b569bb15590549ff478bab6494dde4a907",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "release-23.11", "ref": "release-24.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1719848872, "lastModified": 1728241625,
"narHash": "sha256-H3+EC5cYuq+gQW8y0lSrrDZfH71LB4DAf+TDFyvwCNA=", "narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "00d80d13810dbfea8ab4ed1009b09100cca86ba8", "rev": "c31898adf5a8ed202ce5bea9f347b1c6871f32d1",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -359,11 +359,11 @@
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1717344074, "lastModified": 1721396844,
"narHash": "sha256-9VqYmUqXJdyHdHB7s+IgNZit/Xu+7EqQ1lIyYUp5S2k=", "narHash": "sha256-VduymKyeovo7JzcJ3ar4fryebNu36RnKlI+/TOMWN8w=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "df4244f6c960f041d5b4373d4c3b093bba4caef7", "rev": "a09c08847b2539a069833d9ef72d74224c170a54",
"revCount": 18, "revCount": 19,
"type": "git", "type": "git",
"url": "https://git.sbruder.de/simon/password-hash-self-service" "url": "https://git.sbruder.de/simon/password-hash-self-service"
}, },
@ -450,11 +450,11 @@
"nixpkgs-stable": "nixpkgs-stable_2" "nixpkgs-stable": "nixpkgs-stable_2"
}, },
"locked": { "locked": {
"lastModified": 1719873517, "lastModified": 1728345710,
"narHash": "sha256-D1dxZmXf6M2h5lNE1m6orojuUawVPjogbGRsqSBX+1g=", "narHash": "sha256-lpunY1+bf90ts+sA2/FgxVNIegPDKCpEoWwOPu4ITTQ=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "a11224af8d824935f363928074b4717ca2e280db", "rev": "06535d0e3d0201e6a8080dd32dbfde339b94f01b",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -169,6 +169,23 @@
}); });
packages = {
kexec-bundle = (nixpkgs.lib.nixosSystem {
inherit system;
modules = [
./modules/pubkeys.nix
./modules/ssh.nix
({ modulesPath, ... }: {
imports = [
(modulesPath + "/installer/netboot/netboot-minimal.nix")
];
})
];
}).config.system.build.kexecTree;
};
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
buildInputs = (with pkgs; [ buildInputs = (with pkgs; [
black black

View file

@ -0,0 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEADCLQ+QHuf+tfp88c7rUzPPLLsfSNvH4lPw57cIz0hCADDIyBfs
xZH+uSfBDX7EJyCdpRulpKeI+ixoMtpTo1sgLLnXTaiVY024+ZNtbHUtN28CuS5P
O1uBfWn8ska524DobfHsiIfWRlHrrOdQpgoFfNLIalgbDJv84ktkV92e4NXwp9fg
6/KzcR/LOwUr/ps/OV0+nXgWir9Kz7FepDBIu60UnMeqmqrpptFfxyhB9drps9m0
8wQwaqX+1H4MRNnDVcZEQSdyCHrb3ia7Nc/ysUtguRlhmCuUxRAg1iGoQ4CwDadQ
SgS8eofAmueoV0D0AM6zptFtHydX4U7ZYUeaVdEoKqAcl2IOEydSDg71bDrHDonc
II71WezXY8B76M9W7vvphYjql97x8Eb7HMiDecrqxpaOcnPDeGSy2J9+ENXUhVbk
tak2itzD7FXXpDy15Oam3zNAZV718TfyvsxjOq8xNIDUh1x5iDlR/YAOErro3qF/
fQWIGaKZDDllOpP6BxTR87x85w56i9yPRJ1jl5UvUYKkU30HrnIo/sScy4s1NeSH
XyIGHemm+8e1S2LYEQ/w2bnwKHHNS5kdfARMnaSpMurD+Pd9UBOHPn+M+ZVjX7hT
wCn8QJSJZiUA0b1lJ8YgbXRodHn9jdpZugQ8frtImcDE3Lq+H/VqzJm0tQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQ6LctUsOqOe4CGw8CGQEAAC2dEAABcy5TinEg/yr40qtrPmdR
+qw+B3CezIZOhkFVXJ5SnKSD6kNmijgJjloSJgpQf9qqDsZ8asWzZN79h5s9fqNa
GBn5jBBqoSLPtnNAvxiLk62iRyCbb7y645I1u5Cmg5eBPLjGpVrxI3rPcGojkBz7
1LjtxCY94JI7lRYMpN6qOvyQlrTOxlFDE+C/x60UeliNzL3Ld17O9iuqlSGiYpz4
kellyHF4zHvOcSmURmGmHDzPQvkLop81rCogMZkVoA0tg446U1sPdIo8HJZD+cLt
LXCNlyLU/MK7RCAG25+Z2KE43Z0xuXyNmHc0tpYOWs6oob7+ZmsWFObpyN6v69G/
rTnZbQCp/H/Rr19UbJhoEhDpB6J+6O1OlJXe5hUDiiIYpC6vtzJV8B0ERQ9Vr1TC
nCo+RaBJoPbkJySSO500G3/psQugsxBcxRtCy78cHV1B4fKEJM4e1Hi3VP2uhCju
gRaiLGikDy4rpQQxasszOO2Yt57OGV5qySnZ9hfDLhtmhmNjL2HazZlVT1um28j4
+DZQ7JUmjvlmzZPPt2fWG4k2zv6Xy1p2aLiuL+6TrQLjEyIMa41Lxf6bB7hlYo1Y
3Xl5yE94wvBx2+gKEArlqdrn/P8cdktHuGrELBwVaVgvHHtBM3qfzBik2lIRJMIx
haEIuBv/ZtSMbM/ItaAnJA==
=eW+j
-----END PGP PUBLIC KEY BLOCK-----

28
keys/machines/hiroshi.asc Normal file
View file

@ -0,0 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEADAxevBnQowaGvnY324OIQZeS/EwndRQg2kH4hMHagw8GYVE11x
lZUiVApqAaZcA9sy3ckRhsq1wKX42lkzzgKsXLYozq+SHO/ANtwL8U3M5ojY3IZ+
RAA2LhYlhQInPEhX4IVSh2wXjG7GqkCvPmlS3vBSqrxdLnqfdatW4gqVHrwiLwjQ
VZRyE3T4Tk921CYQTjP1VY+lojImUKPXX/y8e1qp2TP9GMofJ5LP7XtF71Kn15fH
pYqLWvc70qt+FvwesifuKQ22ibrce5yVgX03qXNOn4hlOgNiwd8LVv3gV5rxQ32M
HAlCVMsjDvOxT9/L5vBGTtIUf5nuCNErxAc+5zV/uZ/v4M5iiQxhVWFog8rNWAr7
xu5StUBLaQeeAq4g99Jh0lVLzk5BpA5IOHJjUgKgJ0lx7vPnjphf5gfei0ukXOWF
3QlB6vwsjDgiRh5HuKRdVsVDI2joPksbIXyQ4zJZXjTkrwkXrgUvdPGC+fR7RZDH
0f+Z6lO1ZSbNrfhH1DzNUZvRojJh8WSGxdarx9kS6PK8diIXy8/TK/VnfTyY1j5+
gPmpdAjg6Z2PsJnNuUxTYfa7SADt1q1jmB0krMvZfL/0QV439kIN2VXzQ28Gl5wj
XguSdlIvH/s2XLRcLi3viJ4WIADrw+RG6+moywHBQsOo5LhLDMonj5bYQQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQyYK9/YKGPQkCGw8CGQEAAKdXEAAL7NLAFK+d06Gwh3PrC0Qk
Gj+suQgajJu87OEghR4/szrAtTU5gbOLduiBJ6IN/5NgKrLxbum1NFly6808JZ85
Uit0H2r1RvG1OWYWyCtZA0V/J6IhChUbGVdTU3qvYzosWer/Eg7k2KvrjnkhTsDt
GHaS5tNEZpDLdxjCGTqV5/MqShmWLTVBph4y+VWokHmK/5EK0gK94w7Zf5jNcLzH
9SjbpAGekgJtSagcR6opk3ptld9Hb7Tm8nfHCbdMTjWzO66Vspjg3FoatRL/1vyu
IFkgOnmLt4ns8QWsLXUWSnaWyTCq3YDUwjnh03yEX1MRzDx7iEs6xduYSzKWM8YL
7aUv5HctXO/+rVHrewpKkbCDoIw8yX7mqFkute7R/T2VIn+ISkn5mpwae0vgP53C
14ApyF3NbSzO8shuHzcKwMvLgWn//J20ptQhOE2/49Z/Br2dtka72sg9HP5MAp0p
aL4Q/uvKXCTdbLk290iyt1Y1k9FnpJWjg/u6IliavjAL9LMqz7nakpxRczhvkr7I
3kXc9cQYWcHig0WvuwvzmURVy70oWC2T3tmLShq5lgM8BDnuUlbn8karvDkR1MnS
jTXjf3FaM9DTPDAWykID+doARPeJxzGXz1HHj85Uzu7Rx20m7QU3uvyLgueQb5mG
C3mCrd1nCPcmqDI/UsNf2w==
=xlca
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -1,28 +1,28 @@
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEACxLvouloEvO6hjBfydEMJIEVzJLBqZJBmBvHmJKRbhWSldCWLi xsFNBAAAAAABEACxOC3MelTJWQ+eZDunjDfvYC2bPFP/jZRlgxBp0NOzh4Oql6D+
bdL7L3Ld1K4uQKSEPNRk6LcVVCAPaXuhyeza57U8PNMBJrDESZ+SdAjuNw5/mDTa 0CjuQPbqEaqEGJ3xqT4u/E0jovSqFKsxGGimeu4F0CkobzBhVZhEhw3oQRG5uSFS
VF4jgPzrPmQ1ufRiaOgxOj7OAwOqFEZBMeHXPrauY83dHgKJBcRuw5567YTJ0zoJ x/S1QMO9v3RcjIVM8iBSrsrCx8EJDrfveJQor7ullhaGA6XMnxPB2In8MwnjtBFH
bi3mtetgAeVwgPgQBgihDQhvxgxiOQ0kLbRRDFm8sVsp8o/zJbVy3zop4sJppOSg G4njMJj5jFtpWxHs8fAum9kBNgtxkahbjOiTXq0nWfIPr65X5Pz0pxSH9fnWsbr5
JYzjFyt40wqPQ0TospxvwiYiJhg339hduZZ+J7+4XcdKnTVUNM8Ws7notVFRkWYG +QARbL6bWVy5hkS1UItS3KEnJyotLep4JkFEN7UySPjX25z85kAw4eLMn0pRNCLz
8jWTUuld815WZUA/2rkjx7GsZ9sLChaXVmXRfUGO3G01zaEZ84PA/XrpemWVMs+I b+b76IX04T5r1PGUisu6wNyITJz8yQWyB7fba8NJf1nMPtbY9CNwWtXbl47mp8jJ
y/1UznrSFy3bPh9/Jdpr4D5/gxsJaNs8ioSjb/3fXfZ4+kZySmQiWpagwsLXmPU3 qEEBjv8mQor3V5QzjQkMLb30m8w5QTbNaupxFsjeLiUAq+LRm4wxO7Yzu032sbit
eno5YjvuU8qCh37zWF7uhsUsIDXw1FWqgy7HoU7HLYHDpRoerEABQpIf3378eZJ1 HWpcceAho7VJUqwSqgqE8KGANVldgxgG/w8l19c/iD4nVvwlTTCiS12yCMmkKgj9
+VK/Em2NLyapgBGx+hv+qrUGKAv+/bdTt5XQtQypHI5ihI2H/Rr/ZfTzIWcJIomR JN2WSzmdrpPOyWbYZzRbQsNlxbndkWP9iusnP9cceE6diUZCYTwdZZIwYY1anxy2
KwCsjZDuiRWsQWa/WEqthPX/ckNKJuB25tkCFM4owMtgJEMSymRZ6Fd/zdI+WBS2 NXoXM+r+EYCj4urHsTzj2o+04mitsZH+7wUWLtSIuI0upqpq9DYDN1kZE0c0sfxY
1QSECOHFyr8ha0OfpZF6qy8YYqV82EHeTQdqvAY18po8/Y5WGvm4Q0QCQwARAQAB VCu3dRL0wtNWokoYwWV+l8nMFhQgnhlMf21DgUlA0BNi9BhESKWIpSvDBQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQZg5pur7kJkMCGw8CGQEAANR9EABfKws/H9UX31pJbdWzSotN AQgAFgUCAAAAAAkQcVhrekwMGmUCGw8CGQEAAOOdEAAL1r+OcspofLYAnefX52uU
/1OkQxCNQvTmzxByP+JDBZQoplKbhjwVi/seshwxCMGuvBklmFSdpzGXip68QR4Q CMnBOIK00CuOi+Bg+4gRNTEeed7tOKf9RqU2AArzkRrJindflSnkCe088/Qfw/ui
CYQsFg02URFKA8vggnIbpkNMB3/ckM6m6wQlMshTl1DPpZcZflppi/O68hIqtrSN HXs0hGewcp3i/v5SW0MJI5fZox5hSYTKkfUswgwNf8ZyzFdnxYyIXR2dfWiTo8Uv
/xXx5hIBFqe4NY6+ouHRy+4KPnWqndcHSRC2TaYYiiAo9dBj7VyQsL0zYYyTAl0U VcAe1n/rIe7W7T6uKsrdlgYs2iT7Gbo4Txned2nl8Zq2lE7qzpbksqOV1iy+I0RS
J6rolDz5VqWzkHklH/UMJ3u8ZwV2VHuyU5Drod8/1bDYtjGXxeUhcd25X4q0Gcqh CIyV7PRBQfOIC+rIRPeZD1tOxD2PH4CJPW9jwmM9E42/7gcu/cJBN/MP2vUJS8/l
gts0zoV/kYgnX3rGzqT4q6MGHWzlHtblMxtPpV8m/fd2KDvIKDdJPnYsbKDNlX7j sbvOT2pMqOqrJRXrmlJE2zNyQK1gJeYdhtNN+8INYoy29yeyvMnaSaUsXpjEb76E
QwVS8rE2T/FfU2KGoadNmSJACmCdShpCCd7CSHludcXLMDVuFijh4iCHkc3KvJJP jqvYeFEF6LR2RAQJ1HdCQCGianrFcqpDq7pW1fs+TB+YSFcXUEsNdIeIwROP0hyG
MrWqBTWzYB73O5WGAWDxL7trw80a5Qi2+5PRCQY0smOR4jC3d36PGjtD8ykCHlqt usACFHst2FfYVEd3uz98EHMrgVz3sw48BpK3s8aYVdaRAU/L6lljW3a+6+oAPjMJ
HVZ2CtNl+6loGJ9TTgMwzNOY2PQPP2bhzdB16ht5CDsadFXrFD8mRVcwnQ6F0UU0 6z6yfgTXX5m+ZwdBCPyF6KlRtZNZQTwqmsULcJcb/fLNynZULRSA3TW6rDhS4NXb
DROW+C7FdYkZiEM9r6QMkRX4Xkc4YTV7EL0kEwJkWvxTbL2X/r1lSOKE27iMk2D/ wRF1OSwMMTqX2svuqKlZQhOfaa7w9QL9A/Y4Fa3lZoQOGSdT2+/e0d+MD2T4JqZ6
kkNzVXEH89ryyJc4Pgro5aTjzkAfTOUc+LV34b2CE0NGLjZvOvTic5SSdsAZ+PVL 3fC4XIqUkhcgeOsfJ0WOQdxm/RRhz8pwQhzUAjYk2jG/JmaYUCVaMugJSLBjXN78
CxhNpGhTpzl96WA2WsNP9Q== JKqniA3Iyr5AP2yBxFt9Ag==
=slmv =yxFM
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,15 @@
<!--
SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
SPDX-License-Identifier: CC-BY-SA-4.0
-->
# ci-runner
## Hardware
QEMU/KVM virtual machine on [koyomi](../koyomi/README.md).
## Purpose
It will serve as a CI runner for Forgejo.

View file

@ -0,0 +1,79 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
instances = {
personal = {
url = "https://git.sbruder.de";
};
codeberg = {
url = "https://codeberg.org";
};
};
in
{
imports = [
./hardware-configuration.nix
../../modules
];
sbruder = {
full = false;
};
networking.hostName = "ci-runner";
system.stateVersion = "24.05";
sops.secrets = lib.mapAttrs'
(name: _: lib.nameValuePair "forgejo-runner-token-${name}" {
sopsFile = ./secrets.yaml;
})
instances;
services.gitea-actions-runner = {
package = pkgs.forgejo-runner;
instances = lib.mapAttrs
(name: cfg: {
inherit (cfg) url;
enable = true;
name = "koyomi-vm";
tokenFile = config.sops.secrets."forgejo-runner-token-${name}".path;
labels = [
"nix:host"
];
settings = {
log.level = "warn"; # seems to have little effect
runner = {
capacity = 4;
timeout = "1h";
};
};
hostPackages = with pkgs; [
bash
coreutils
git
git-lfs
nix
nodejs
podman
];
})
instances;
};
virtualisation = {
podman = {
enable = true;
defaultNetwork.settings = {
ipv6_enabled = true;
};
};
containers.containersConf.settings = {
engine.cgroup_manager = "cgroupfs"; # systemd does not work for system user
};
};
}

View file

@ -0,0 +1,58 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ modulesPath, ... }:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
sbruder.machine.isVm = true;
boot = {
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
kernelParams = [ "console=ttyS0" ];
initrd = {
availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sr_mod" "virtio_blk" ];
kernelModules = [ ];
};
loader = {
grub.enable = false;
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/e1a9b0bb-9f04-498c-ac2f-aad9da4639f3";
fsType = "btrfs";
options = [ "compress=zstd" "discard" "noatime" "ssd" ]; # for some reason, the kernel assumes rotational
};
"/boot" = {
device = "/dev/disk/by-uuid/7A51-7897";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
};
services.fstrim.enable = true;
networking = {
useDHCP = false;
usePredictableInterfaceNames = false;
};
systemd.network = {
enable = true;
networks = {
eth0 = {
name = "eth0";
DHCP = "yes";
domains = [ "sbruder.de" ];
};
};
};
}

View file

@ -0,0 +1,73 @@
forgejo-runner-token-codeberg: ENC[AES256_GCM,data:dOoTwNaXUDrkE5qUldDMI/SQt3mufCF4Aeua7jqvSFTXuB15rLgdbC99+7MlMTc=,iv:7jakhJ3gKWxN0ACG9MfkOeA/X2HnTKHXxMvLJ/b/9uM=,tag:i7uk5pjd5ALnQrH6F5WhZg==,type:str]
forgejo-runner-token-personal: ENC[AES256_GCM,data:U2VmQW3mO+3lNBczxU5MmKjseCICXcu1q9g4xctrJMl7Hcau0Hfy2IT8YzaEnTo=,iv:IRf+5sTyx20cMyUCg8jffDiSIuNgVRySD7eqOlzzAXY=,tag:vLEo/E2VUZ4Uu/vTFDomUw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2024-07-31T15:26:48Z"
mac: ENC[AES256_GCM,data:qS+MsheUb+zsG5VuNqPAQz4QHDutltBQoY/qWWxSHpp5ty9O477mpsAGwP2okQJfrfbr5zfy9fUMOB/9GV3VWwhNfzmLSbSHM9f/0a1sgv7q2qsX3Z9HTyYoYJD1i9vfIX+AYCgeP7IlbPH/DOi5R6zYO34ETk1UqgSAtWjpu44=,iv:/oe5jlyzDTPZlNB0ToZpsJr/nwGU3QoGerHd7N4TjDY=,tag:U1R8PwdeWvViEhHJ04Un2w==,type:str]
pgp:
- created_at: "2024-07-19T10:09:12Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdAV+XCpuYtwJAQ0tudjofCp9kLhagt3iFPOZxMVm7Wu38w
7h11CkDL2crHptPFundK0cVC1C149l8fpTRM3w6HzrqrYeSb2rVB3sTJnquWE6vc
hF4Dub78fMESoMASAQdAyxaxQvNwxAVVLs2zfhpaEVJMJTVb2X8Re28T5oyzBTsw
vfLrp2aF9f6aR0rKawCdWCtbkdT84RqjcmFeRFm80aKg/moUOsEGKrJIom8bvzgC
hF4DM6AcvgVUx2MSAQdAkmk2DPVyggHcMG98DGidvPx2lx6f1jUctmu4bgCOCXow
JmC3Navjws1ki32t3AYO18VLzTdJnnoUZsMgKIZjrmTYq1SYEbZF7YkHpFKyD2P/
1GgBCQIQznxhAwr2Y1EfOOIurUCAFioUkb00NYurpRtXkwlq6zXj+g3mqy4oIxwE
G8PWC0Gd5DDf3vgY8gu+yIPdQYVtPEmcgdVAuf2URXeZzOYkYdME9aHjmOkZZLgl
q+rcko9nXtgqfQ==
=a7Tl
-----END PGP MESSAGE-----
fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763
- created_at: "2024-07-19T10:09:12Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4Dub78fMESoMASAQdAn4gu062b6uphH7aptsB+qJsJvw5j1jeEijaiN3g3HCEw
7efyFGEXz5Jr3QBkvA86zzzw4uaj6s8jcpGkygPgVxkid+wNPNE7Od2GxwsQ7Rzs
1GgBCQIQznKTHLTufQbnTxtYWdZ7Vd7d90/hl9ZkGRXCq5llvppaYkuO+RO3HeW1
Z4hAPFKrvOjNctb/Puh9kbmQ2g02KFdzs1xUvq3+Ma6gI+WeefV/R/VewAVve8+2
G/CwY+iDECvL1A==
=QVmD
-----END PGP MESSAGE-----
fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0
- created_at: "2024-07-19T10:09:12Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdAwLuRB1t778hUtgsjaQisVwMhBudnSIOtrBFehLU5Smow
AA29mIR2539iMz/Qkdjoumj3IIKGu6a/fBeu0eLUcZqSt5PtpMKMDnF47HeRv/QQ
1GgBCQIQGjEJcIaQyjBPuHyxUNryt6M72ed5eKsnsHBhe+xmwc8AFliP2rt/kZOn
yJGjhMrFAib5i8rRDQiW+HlDHKZeGxsX3yLGdOSI9KfIFvawcYV8pxDFzIca/3X1
TcVFed7B2BUIow==
=6bPt
-----END PGP MESSAGE-----
fp: 403215E0F99D2582C7055C512C77841620B8F380
- created_at: "2024-07-19T10:09:12Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA+i3LVLDqjnuARAArF6aiDcKtyilbZXdBga+6nAqwBdpeYfXlnTMUztFLRYs
cSSe2HKu6J9G1oMqpZuNcGLUXgrdKk8PO3YmivWcPubQ0ruiorgzmSnXDhYvij7+
b9b3dSWXwe82sdCVlSQZRNeapeb1hW8wcrKSoFDUYyIl3HdlxFcB1Y7hKe3XpzAy
UMxgZ8B+Ne1JOHZw97YhZmr834F7/i4vCUv/US+dGd5Fl4a3bX/8ft43T0uj5JWW
PsbjZa2LIuV6dhXu8URraQHj24Z2xM/PSSmm277MzFiXVT/0jWHe38iXLxsp7/KV
hFYqbH49P7gTC7GWJ0xHJaICWXR9WJKSttc5ue8sMkf4rj3C/ULmxS7uKbUn4FgD
Po4XCOSanZZZos4Tz/KxExLjDioJbCBUSBVQUP07RRDyVjIEe4GlOG7QCVgqty6U
LJk7sQLgFOsCgaMGuA5u5hulWx7YDHqaZxKwWZ4ME8huoP2F7L4HzoWJGK33chCR
1t+p/cnflcz459bSGmDMjprZAtD2XFD08/GbDqS7rotPy0h+dnbT7TnvHrFFGjd2
Qw8SIytL0D0KcqKOIXztwtt30RqTMp3CnV22NasGJsbhshAV3zVheI/8dA6UuB4r
kltGrz+O+Z7HMwuYKKTUzz3C29VJYYhPlf4uq3kF+JJZC6ZQUNAoD5rgVDeZDyDS
WAEqbel5S7ImX3oAsIF21iI11jsbWHS1/PjHdsBQdSeBzVXooiRfVa/e4ixgk8S1
tbJl8GcvK4vdDxW689A86w7DoquocXRzJIYsKB/GVfsrTlTofAwPjHY=
=bQn7
-----END PGP MESSAGE-----
fp: 20e376b89b30327fb82f12e8e8b72d52c3aa39ee
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -79,10 +79,20 @@ in
koyomi = { koyomi = {
system = "x86_64-linux"; system = "x86_64-linux";
extraModules = [ extraModules = [
hardware.common-cpu-intel hardware.common-cpu-amd
hardware.common-pc-ssd hardware.common-pc-ssd
]; ];
targetHost = "koyomi.sbruder.de"; targetHost = "koyomi.sbruder.de";
}; };
ci-runner = {
system = "x86_64-linux";
targetHost = "ci-runner.sbruder.de";
};
hiroshi = {
system = "x86_64-linux";
targetHost = "hiroshi.sbruder.de";
};
} }

View file

@ -9,9 +9,9 @@
../../modules ../../modules
../../users/simon ../../users/simon
./services/languagetool.nix
./services/media-backup.nix ./services/media-backup.nix
./services/media.nix ./services/media.nix
./services/paperless.nix
./services/photoprism.nix ./services/photoprism.nix
./services/torrent.nix ./services/torrent.nix
]; ];
@ -20,7 +20,9 @@
wireguard.home.enable = true; wireguard.home.enable = true;
nginx.hardening.enable = true; nginx.hardening.enable = true;
printing.server.enable = true; printing.server.enable = true;
restic.system = { restic = {
enable = true;
backups.system = {
enable = true; enable = true;
qos = true; qos = true;
extraPaths = [ extraPaths = [
@ -35,6 +37,7 @@
"/data/torrent" "/data/torrent"
]; ];
}; };
};
unfree.allowSoftware = true; unfree.allowSoftware = true;
}; };
@ -51,4 +54,20 @@
networking.hostName = "fuuko"; networking.hostName = "fuuko";
system.stateVersion = "20.09"; system.stateVersion = "20.09";
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
};
services.postgresqlBackup = {
enable = true;
startAt = [ ]; # triggered by restic system backup
location = "/var/lib/postgresql-backup";
compression = "none";
};
systemd.services.restic-backups-system = {
after = [ "postgresqlBackup.service" ];
wants = [ "postgresqlBackup.service" ];
};
} }

View file

@ -8,6 +8,9 @@
sops.secrets.media-htpasswd.owner = "nginx"; sops.secrets.media-htpasswd.owner = "nginx";
services.nginx.virtualHosts."media.sbruder.de" = { services.nginx.virtualHosts."media.sbruder.de" = {
enableACME = true;
forceSSL = true;
basicAuthFile = config.sops.secrets.media-htpasswd.path; basicAuthFile = config.sops.secrets.media-htpasswd.path;
root = "/data/media/"; root = "/data/media/";

View file

@ -0,0 +1,119 @@
# SPDX-FileCopyrightText: 2021-2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, ... }:
{
services.postgresql = {
enable = true;
ensureDatabases = [ "paperless" ];
ensureUsers = lib.singleton {
name = "paperless";
ensureDBOwnership = true;
};
};
services.paperless = {
enable = true;
settings = {
PAPERLESS_DBHOST = "/run/postgresql";
PAPERLESS_URL = "https://paperless.sbruder.de";
PAPERLESS_OCR_LANGUAGE = "deu+eng";
PAPERLESS_TASK_WORKERS = 4;
PAPERLESS_TIME_ZONE = "Europe/Berlin";
PAPERLESS_FILENAME_FORMAT = "{correspondent}/{document_type}/{created}_{title}_{doc_pk}";
PAPERLESS_CONSUMER_RECURSIVE = true;
PAPERLESS_CONSUMER_ENABLE_BARCODES = true;
PAPERLESS_CONSUMER_ENABLE_ASN_BARCODE = true;
PAPERLESS_CONSUMER_ENABLE_COLLATE_DOUBLE_SIDED = true;
PAPERLESS_OCR_USER_ARGS = builtins.toJSON {
invalidate_digital_signatures = true;
};
};
};
systemd.services.paperless-task-queue.serviceConfig = {
ReadWritePaths = [ "/var/lib/scans/paperless" ];
};
services.nginx = {
enable = true;
virtualHosts."paperless.sbruder.de" = {
enableACME = true;
forceSSL = true;
locations = {
"/" = {
proxyPass = with config.services.paperless; "http://${address}:${toString port}";
proxyWebsockets = true;
extraConfig = ''
client_max_body_size 500M;
'';
};
"/static".root = "${config.services.paperless.package}/lib/paperless-ngx";
"/manual-scan/" = {
alias = "/var/lib/scans/manual/";
extraConfig = ''
autoindex on;
allow 10.80.1.0/24;
allow 2001:470:73b9:1::/64;
deny all;
'';
};
};
};
virtualHosts."fuuko.lan.shinonome-lab.de" = {
enableACME = true;
forceSSL = true;
};
};
users.users.scan = {
home = "/var/lib/scans";
isSystemUser = true;
group = "scan";
hashedPassword = "$y$jCT$5kP87kZLYQs4SRtB5oDYT0$TbcyiO.HuFZ.5e9LPu4vqGAjGXbmfOTJefPvTlsVzm3";
};
users.groups.scan = { };
systemd.tmpfiles.rules = [
"d /var/lib/scans 0555 scan root -"
"d /var/lib/scans/paperless 0770 scan paperless -"
"d /var/lib/scans/paperless/double-sided 0770 scan paperless -"
"d /var/lib/scans/manual 0750 scan nginx 7d"
"L /var/lib/paperless/consume/ftp - - - - /var/lib/scans/paperless"
];
sbruder.restic.backups.system.extraExcludes = [ "/var/lib/scans" ];
services.vsftpd = {
enable = true;
writeEnable = true;
localUsers = true;
chrootlocalUser = true;
userlist = [ "scan" ];
extraConfig = ''
listen_ipv6=YES
# users shell is nologin
check_shell=NO
# scans should be readable
local_umask=022
pasv_min_port=30000
pasv_max_port=30009
'';
};
networking.firewall = {
allowedTCPPorts = [ 21 ];
allowedTCPPortRanges = [{ from = 30000; to = 30009; }];
};
}

View file

@ -13,11 +13,14 @@
}; };
}; };
sbruder.restic.system.extraExcludes = [ sbruder.restic.backups.system.extraExcludes = [
"/var/lib/private/photoprism" "/var/lib/private/photoprism"
]; ];
services.nginx.virtualHosts."photoprism.sbruder.de" = { services.nginx.virtualHosts."photoprism.sbruder.de" = {
enableACME = true;
forceSSL = true;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://127.0.0.1:${toString config.services.photoprism.port}"; proxyPass = "http://127.0.0.1:${toString config.services.photoprism.port}";

View file

@ -15,11 +15,6 @@ in
fqdn = "torrent.sbruder.de"; fqdn = "torrent.sbruder.de";
}; };
services.nginx.virtualHosts."torrent.sbruder.de" = {
enableACME = false;
forceSSL = false;
};
networking.nftables.ruleset = '' networking.nftables.ruleset = ''
table inet qbittorrent { table inet qbittorrent {
chain output { chain output {

View file

@ -0,0 +1,19 @@
<!--
SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
SPDX-License-Identifier: CC-BY-SA-4.0
-->
# hiroshi
## Hardware
QEMU/KVM virtual machine on [koyomi](../koyomi/README.md).
## Purpose
Server for general purpose services.
## Name
Hiroshi Odokawa is a taxi driver from *Odd Taxi*

View file

@ -0,0 +1,53 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ pkgs, ... }:
{
imports = [
./hardware-configuration.nix
../../modules
./services/bang-evaluator.nix
./services/languagetool.nix
./services/li7y.nix
./services/password-hash-self-service.nix
];
sbruder = {
full = false;
restic = {
enable = true;
backups.system.enable = true;
};
wireguard.home.enable = true;
infovhost.enable = true;
nginx = {
hardening.enable = true;
proxyv4.enable = true;
};
};
networking.hostName = "hiroshi";
system.stateVersion = "24.05";
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
};
services.postgresqlBackup = {
enable = true;
startAt = [ ]; # triggered by restic system backup
location = "/var/lib/postgresql-backup";
compression = "none";
};
systemd.services.restic-backups-system = {
after = [ "postgresqlBackup.service" ];
wants = [ "postgresqlBackup.service" ];
};
}

View file

@ -0,0 +1,53 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ modulesPath, ... }:
{
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
sbruder.machine.isVm = true;
boot = {
kernelParams = [ "console=ttyS0" ];
initrd = {
availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
};
loader = {
grub.enable = false;
systemd-boot.enable = true;
efi.canTouchEfiVariables = true;
};
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/41b1b850-4349-435a-ba10-6adefbe25c68";
fsType = "btrfs";
options = [ "compress=zstd" "discard" "noatime" "ssd" ];
};
"/boot" = {
device = "/dev/disk/by-uuid/F0E4-1A5C";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
};
networking = {
useDHCP = false;
usePredictableInterfaceNames = false;
};
systemd.network = {
enable = true;
networks = {
eth0 = {
name = "eth0";
DHCP = "yes";
domains = [ "sbruder.de" ];
};
};
};
}

View file

@ -0,0 +1,73 @@
wg-home-private-key: ENC[AES256_GCM,data:JAlK7jzme1qyVLhoJoRZ5K3qTQoFn69RxFPrhcav7GkXzyP/rfp9IUZ7WDw=,iv:JSytbjdpCQ0co+Wz7Kt9p8QgwwjerK+c/y0R+qQISpM=,tag:yHdH/owL43LDnMk65Iw1tQ==,type:str]
li7y-environment: ENC[AES256_GCM,data:9vlusBKLpT9Rd8cODcGKnKHiZJf6LbXNo6BjiulM6HCASfELnDArEQ6bX3w/kkR0C0ZvgAeT/cSnNjMxQgBL4NcKPaMHB+fxoJ68+PDC4LzAd26u6hWtgPfe6INvjsScnlNRZOFeJNHM2LIbRGOFS8PJ/IltxORpPF0n7oR8kCPhK/H46lL/Hz3UFpwYBmXeizSn5O3NETo=,iv:v8oeMwGyyDvx6VltExzAUGdWLxjx8UfYU4NFKS8q/qQ=,tag:f6jKlQWQh0Gl3LnXpStMjw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2024-08-28T13:24:56Z"
mac: ENC[AES256_GCM,data:vMzaq0A43DkFSV+eBFB6n/HYMQqA8qrBNHBMwLoHyiCvl35BTG0Qx9tHJsqmucWrQJN/w2opm/YZj9/as9xTgVEIaUXn3lFdhSBNuH3ZQYLSayhUFKUQT4q6tBymxzgeFbI/vUmgxhQ/rOlKFV/BVx/GGdOTQBNZMdpyhI8qe0Q=,iv:tOGHmTwrBukks3nJLchPz7Q4BN5Eca6vlM+JcVND1rk=,tag:ZW52VxsZDRn7syscng3Uxw==,type:str]
pgp:
- created_at: "2024-08-20T16:25:03Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdA8BWJC/iC3EO6xmZoy8vJyTR0K5IXZnN9ZLJ0ABGhFBkw
yIA5NSHZDh6jzW9Bc++pzPxUcu/cShc9OLC3UmTXXkO2OQE/PgPeroHit1SykUrv
hF4Dub78fMESoMASAQdAGKhltWUcvYpCWLx1dZ86OsKH0QgZLESG0cvrVUAlNWEw
Akan01/TeYg6u3KBjfJhDJfjdjj1Jz56DFlpNlS21f6mKq36/73rOA5XR22PZJgi
hF4DM6AcvgVUx2MSAQdAigyGpC677Jw+0jXF1g9jRTgtX6iGpawM+ior0ku6PjMw
UGGAviSx4ClSQJDRCxa0XMm0jCOucvwt/RhBtpHJjakW7ygR+8P5ZFjCPNjyt4uX
1GgBCQIQbHEcKTaeBq2331XJtka1TfzeDUuB4qCBzRkbhcyUMloJ085BxgPwCpJr
Et9FDtxGaadZ5Y/1udYaygOSbotoBBb0K6hegtRamiLjfzVoOEl0wlk49aSJcYhB
RNMezIkl4agI2w==
=18pZ
-----END PGP MESSAGE-----
fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763
- created_at: "2024-08-20T16:25:03Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4Dub78fMESoMASAQdASS1oqED/kKjkWPOT24Ryed4+XFDf/F83pjy8XTuzHXAw
7PHMEfiV3rniHWppCMoGn3lEoBojp4EeJ/OwO/0/ujwg9o86Tq1kzEwy04lgYJCK
1GgBCQIQJZXXZsWsF6VRrURVTZDc2dax+5mvGBgiJ1zlopUA6HgZj6dyeiH5gNRp
LmbbXoTu+UMgcePL4CtkvVam3pi+KFnCDYkcZEtfGygoASklb+WHFmlKSVoJcLRF
qEfypkntJ/n39A==
=jSRD
-----END PGP MESSAGE-----
fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0
- created_at: "2024-08-20T16:25:03Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdAqFT6XtuCsKZ/OYjgU/fM8FFzWNQGcyhHDYAZJGQyjksw
MTUpUnRgzqqZ3meafYBDm8FS4ecq7xrv72NGrt5dxzg9ubXV/Dy55sYjcDeeq/ez
1GgBCQIQ2BbwEJz4yevPP2wc2PNV3Y/K1gJF45iYW9Ok7SaX1jLT8IkWF4ktY0R4
YytShmcywpUw+vGCOx4EoyMgZgZfhqH5jo+a9xsukL7yFFKIupILl9ypH351aFN4
wQhFWlKE8CoYwg==
=Jw+A
-----END PGP MESSAGE-----
fp: 403215E0F99D2582C7055C512C77841620B8F380
- created_at: "2024-08-20T16:25:03Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA8mCvf2Chj0JARAAtI5JqcTlUuwbCvEETf3R5Fda28TY66SpQqtd1+4bxV5k
Pvasl0z/nwuc0yFyjGX+GWK4f9vWnxWeJVc6MbXHlgO0RrBFgD8U3eDwxKhBRP9S
blFcf2qPbbf9P38/DWGRjgS7y4Va+kdaGSyT5i7+1lsJxt5Uefg2X4U8nnK+BAiy
QWdA5gXNYERi4nj+SmtFkp++McOfU0UYdlFSwKwhJnch5fL/l4yjzc3qCyYtoNtY
C3qMWBZVFerYz8UCKWGusD20h+ysodY9B49uSqJq2mbQSmEZAnkRj4BMyEPeC6im
cvjwZPBM2Gae2Xh+sf8m6zwL7Bo+5uYIJoaWF2frJ7JhCaWeYCXbFMpd62YJajV0
yMwtrVAIAzScC0HoYELI/UCdJ2wk59Ns7GMLwa2EmJy92SfrUMYqC21eNoFNI6oh
KuahY82SfpGFER4PbpJwuW0XzwzHHYYEJAIDd/eAfJa+Do6tU8a/1VI8VLdQ+nHg
QCSpPyIS8uXBmGFxmZEfviroo1dDcwYoLLR5pp2ctwRknQLvhadGqWjWZhGifEg5
s1GQptL7JK/lfoOQkLes9X2HoEC32DqbqP+6zUammuhCoMgMLPPpcw5jcjLFVxfN
jpFXqmxYBCjJuxLjM868scaKRj4XW1jOLNqHgAdAfFq1+5SkxEZtmvwbeTDEFnDS
WAHKApsFhO3JioY8NVPiYWRHdKvMf9a3IeE3iDuSZ7Crue4Lwg7hmDbTnqQEnShM
jmS3x+Gu182MI3pu2qZrB/DYKtbgW+540nI5p2NFEX7SPsrXyKIPrqM=
=pmGP
-----END PGP MESSAGE-----
fp: 2b9be9660662c6c979ca1149c982bdfd82863d09
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -12,8 +12,9 @@ in
#allowOrigin = "https://languagetool.sbruder.de"; #allowOrigin = "https://languagetool.sbruder.de";
allowOrigin = "*"; allowOrigin = "*";
settings = { settings = {
# http://languagetool.org/download/ngram-data/
languageModel = "/var/lib/languagetool/ngrams"; languageModel = "/var/lib/languagetool/ngrams";
word2vecModel = "/var/lib/languagetool/word2vec"; # https://fasttext.cc/docs/en/language-identification.html
fasttextModel = "/var/lib/languagetool/fasttext/lid.176.bin"; fasttextModel = "/var/lib/languagetool/fasttext/lid.176.bin";
fasttextBinary = "${pkgs.fasttext}/bin/fasttext"; fasttextBinary = "${pkgs.fasttext}/bin/fasttext";
}; };
@ -22,7 +23,13 @@ in
# default log level is INFO, no easy way to reduce it. # default log level is INFO, no easy way to reduce it.
#systemd.services.languagetool.serviceConfig.StandardOutput = "null"; #systemd.services.languagetool.serviceConfig.StandardOutput = "null";
# It often runs out of java heap memory, no matter what settinsg are used.
systemd.services.languagetool.serviceConfig.Restart = "always";
services.nginx.virtualHosts."languagetool.sbruder.de" = { services.nginx.virtualHosts."languagetool.sbruder.de" = {
enableACME = true;
forceSSL = true;
locations = { locations = {
"/".proxyPass = "http://127.0.0.1:${toString cfg.port}"; "/".proxyPass = "http://127.0.0.1:${toString cfg.port}";
}; };

View file

@ -18,7 +18,7 @@ with the front panel changed to a Pure Base 500DXs (for better airflow).
\+ 2×32GB G.Skill Ripjaws V F4-3200C16-32GVK \+ 2×32GB G.Skill Ripjaws V F4-3200C16-32GVK
(both DDR4 3200MHz CL16-18-18-38) (both DDR4 3200MHz CL16-18-18-38)
* PSU: be quiet! System Power 10 750W * PSU: be quiet! System Power 10 750W
* SSD: 1TB Samsung 980 Pro NVMe * SSD: 2TB WD_BLACK SN850X NVMe
* GPU: Intel Arc A770 Limited Edition (16GB VRAM) * GPU: Intel Arc A770 Limited Edition (16GB VRAM)
* Case fans: 2 be quiet! Pure Wings 2 140mm (included in case), 3 more with PWM * Case fans: 2 be quiet! Pure Wings 2 140mm (included in case), 3 more with PWM
* CPU Cooler: Noctua NH-U12S with an additional NF-F12 PWM * CPU Cooler: Noctua NH-U12S with an additional NF-F12 PWM

View file

@ -19,13 +19,16 @@
gui.enable = true; gui.enable = true;
media-proxy.enable = true; media-proxy.enable = true;
podman.enable = true; podman.enable = true;
restic.system = { restic = {
enable = true;
backups.system = {
enable = true; enable = true;
qos = true; qos = true;
extraPaths = [ extraPaths = [
"/data" "/data"
]; ];
}; };
};
unfree.allowSoftware = true; unfree.allowSoftware = true;
wireguard.home.enable = true; wireguard.home.enable = true;
}; };

View file

@ -8,12 +8,12 @@ SPDX-License-Identifier: CC-BY-SA-4.0
## Hardware ## Hardware
System from [Hetzner Online Serverbörse](https://www.hetzner.com/sb). [Hetzner Online AX41-NVMe](https://www.hetzner.com/de/dedicated-rootserver/ax41-nvme/)
- Motherboard: FUJITSU D3401-H1 - Motherboard: ASRockRack B565D4-V1L
- CPU: Intel Core i7-6700 - CPU: AMD Ryzen 5 3600
- RAM: 4×16GB Samsung [M378A2K43CB1-CRC](https://semiconductor.samsung.com/dram/module/udimm/m378a2k43cb1-crc/)/[M378A2K43BB1-CPB](https://semiconductor.samsung.com/dram/module/udimm/m378a2k43bb1-cpb/) (DDR4 2400/2133MHz) - RAM: 2×32GB Samsung [M378A4G43AB2-CWE](https://semiconductor.samsung.com/dram/module/udimm/m378a4g43ab2-cwe/) (DDR4 3200MHz)
- SSD: 2×512GB M.2 NVMe SAMSUNG MZVLB512HAJQ-00000 - SSD: 2×512GB M.2 NVMe SAMSUNG MZVL2512HCJQ-00B00
## Setup ## Setup
@ -24,10 +24,14 @@ and a rescue system that can be activated before a reboot.
Additionally, there is also a *vKVM* rescue system, Additionally, there is also a *vKVM* rescue system,
that boots a hypervisor from the network and runs a VM which boots from the physical disks. that boots a hypervisor from the network and runs a VM which boots from the physical disks.
The rescue system can be used to start a kexec installer generated by [nixos-generators](https://github.com/nix-community/nixos-generators). The rescue system can be used to start a kexec installer provided by this flake (`nix build .#kexec-bundle`).
Ideally, everything goes well and the next reboot works, Ideally, everything goes well and the next reboot works,
but in the case it does not, the vKVM rescue system can be used for debugging. but in the case it does not, the vKVM rescue system can be used for debugging.
Even though the Hetzner documentation states that all current systems have UEFI enabled by default,
my server did not boot when configured for UEFI,
so I used MBR boot instead.
## Purpose ## Purpose
Hypervisor. Exact scope is to be determined. Hypervisor. Exact scope is to be determined.

View file

@ -2,22 +2,27 @@
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../../modules ../../modules
./services/hypervisor.nix ./services/hypervisor.nix
./services/haproxy.nix
]; ];
sbruder = { sbruder = {
restic = {
enable = true;
backups.system.enable = true;
mirror.backblaze.enable = true;
prune.enable = true;
};
wireguard.home.enable = true; wireguard.home.enable = true;
podman.enable = true; podman.enable = true;
}; };
networking.hostName = "koyomi"; networking.hostName = "koyomi";
system.stateVersion = "23.11"; system.stateVersion = "24.05";
} }

View file

@ -11,7 +11,7 @@
boot = { boot = {
swraid.enable = true; swraid.enable = true;
kernelModules = [ "kvm-intel" ]; kernelModules = [ "kvm-amd" "nct6775" ];
kernelParams = [ "ip=dhcp" ]; kernelParams = [ "ip=dhcp" ];
loader = { loader = {
grub = { grub = {
@ -19,13 +19,13 @@
}; };
}; };
initrd = { initrd = {
availableKernelModules = [ "aesni_intel" "ahci" "e1000e" "nvme" ]; availableKernelModules = [ "aesni_intel" "ahci" "igb" "nvme" ];
kernelModules = [ "dm-snapshot" ]; kernelModules = [ "dm-snapshot" ];
network.enable = true; # remote unlocking network.enable = true; # remote unlocking
luks.devices = { luks.devices = {
koyomi-pv = { koyomi-pv = {
name = "koyomi-pv"; name = "koyomi-pv";
device = "/dev/disk/by-uuid/9145417d-e8f5-4aa9-a526-419e507c47fd"; device = "/dev/disk/by-uuid/4907ad59-e6cf-40ed-a0ff-3dc09c0c7a50";
preLVM = true; preLVM = true;
allowDiscards = true; allowDiscards = true;
}; };
@ -44,19 +44,24 @@
fileSystems = { fileSystems = {
"/" = { "/" = {
device = "/dev/disk/by-uuid/3b31163f-4fec-4e1c-b311-7c8aaca76cd4"; device = "/dev/disk/by-uuid/4b4efa64-e571-4937-bb1c-7608e9d7630d";
fsType = "btrfs"; fsType = "btrfs";
options = [ "discard=async" "noatime" "compress=zstd" ]; options = [ "discard=async" "noatime" "compress=zstd" ];
}; };
"/boot" = { "/boot" = {
device = "/dev/disk/by-uuid/12CE-A600"; device = "/dev/disk/by-uuid/83e67d66-ec76-4c9f-8796-1165cdb5362d";
fsType = "vfat"; fsType = "ext2";
}; };
}; };
services.prometheus.exporters.smartctl.devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ]; services.prometheus.exporters.smartctl.devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ];
# Not used for boot, but required to make thin LVs work
services.lvm.boot.thin.enable = true;
# TODO Enable periodic RAID scrubbing/checking with mdcheck
networking.useDHCP = false; networking.useDHCP = false;
networking.usePredictableInterfaceNames = false; networking.usePredictableInterfaceNames = false;
systemd.network = { systemd.network = {
@ -66,7 +71,7 @@
name = "eth0"; name = "eth0";
DHCP = "yes"; DHCP = "yes";
domains = [ "sbruder.de" ]; domains = [ "sbruder.de" ];
address = [ "2a01:4f8:151:712d::1/64" ]; address = [ "2a01:4f9:3051:39c6::1/64" ];
gateway = [ "fe80::1" ]; gateway = [ "fe80::1" ];
}; };
}; };

View file

@ -1,3 +1,5 @@
restic-mirror-backblaze-env: ENC[AES256_GCM,data:VII+kDpsmWRevdeAhoAI4A0NVlofH1ZNrWCKknwasSHEQhi1/9dNzcHhPd3d264xjh85crq9sIhSZ4dvkZnzEL5AglM6zlmZFf1m46w2vQlyW5VHVZ1T2Yja,iv:wyClY0TnBMqY6nBNdrlmRt09dqRxDT6Ui/kDJDQzOE0=,tag:FrTtthFqZ2ndHVvcFxHjDA==,type:str]
restic-ssh-key: ENC[AES256_GCM,data:fDKiNhPBZu3Hf4xx13rJpNrOv+HWmh6LtTqbcWAu+0dxiKRz8J7lJLlg9AnDL5gIkNukzqL1eAXAC7P9B8ocFBGqcOC3QFGem8o61VWXB0JHurxrm/R7jZCKd/delRiv3gnn0S1wVAfkItDTdoLMhfv+E4uIzgR4bcQDIrvozV02jHOxQY54XpsDCyOFnC0FlQxa0W5EyWVvSTHJsXBNjsrdEQB1y6hh+s7jxAAdV8XdnOJ5/ivVoe+mbhKNrkHEPKHD/JOhjJooDgfr1+XsTkN3rbTPHCqJ1fQVkoh3KiHJQKYc/tG5KPm+W4tzsPbuNroUWr8gBlyCf7y7wae5fHAcuwnl2T2ETspU4N4pfdI/rbzr8uFtNEQTbNiHTD2eLzA9OiDhzPneWiQrfKc3/4/67ZT5vs3o0x6kmQyhhy3/SnXkoiyvjQOFPbRdygarKJBNhIVOHLmZz6cMCYbvuLMjmJPu/7hQAvC8g7JRtJ15foA1SrhHaAcKN7QYCnl5d+fKmfioEguEmYa6U0j4,iv:8Jm9r9u2RCfvNpeEEqbB5MHqTJc3k03P6Z2V5s5xAA8=,tag:ESmj1lRwL6lkUnr48nDeyA==,type:str]
wg-home-private-key: ENC[AES256_GCM,data:fFoXn5sLL06hNeXhQGKbheQV4ZNlYxJKWlHpPfyF6PyYbBcz4An9DPYnQKk=,iv:pY2dVEspIijtZkatUrSdg90D0ldxAoy5rUj1lw1cOF8=,tag:jz4q+Yum05S9c5OlciBZ1g==,type:str] wg-home-private-key: ENC[AES256_GCM,data:fFoXn5sLL06hNeXhQGKbheQV4ZNlYxJKWlHpPfyF6PyYbBcz4An9DPYnQKk=,iv:pY2dVEspIijtZkatUrSdg90D0ldxAoy5rUj1lw1cOF8=,tag:jz4q+Yum05S9c5OlciBZ1g==,type:str]
sops: sops:
kms: [] kms: []
@ -5,68 +7,68 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-05-11T21:49:03Z" lastmodified: "2024-08-27T09:48:17Z"
mac: ENC[AES256_GCM,data:yS/v+NWiLlFLTwnbhaYVg98H/ThqW5r+3eC1YsvJRRrF/yZBk6nUtK8CT4tvR9PUeks4a2H15/5aY2oDxnABhXhkbasZjnl3+YGF8SOIwo+YuWJ5A3rHJZQMJGRGg8dwh4xkJMDJKb2Or1uH3ZiSclVMQDiM3RGVifLhtv+gJEc=,iv:ygTcKqU5pzkOoGUx9xw9BzWJx15t28w3tJVH4eAdxS4=,tag:F5/8SSt/eON9zwWGGUyUEQ==,type:str] mac: ENC[AES256_GCM,data:XBL1szDu+Mw7A/D31BJt4rD5a4ic1EuTmUefMYoMdL4kTl5fi7Ckk9EIV6MI5nKhF8ejR4cN94ih2cILzLodj/e89Xf74d0o8RX5PlUzqFsHoKV/yy9QVVtDDqnwo87sGZztUUcjlJX427SfPwdcMlNAuCoEZ/3SOQgcz5yoMB8=,iv:+WOJuSpSwB74brg3/SZ4Yu2WVtE4YOOiGfwlencLWps=,tag:YchYDy1eKXmTbK0Jb1Ewjg==,type:str]
pgp: pgp:
- created_at: "2024-05-11T21:48:51Z" - created_at: "2024-08-20T22:33:06Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdATNhq0wu5gLVG+7PHCtdQRxgC6GqQrvrttZnN3AvnZ0ww hF4DLHeEFiC484ASAQdA059TryQI438sM8HUkXawVy/b05ZXpRuhJwe7y7nwEjgw
qBdXl+6qkWHyjvclklzcNfpcMD7cmRwRDSDSQASmSTAyulBbgjDuou9Tjl/Rxorl +weY4cgFW4vA4dboZfh1ZNTCkqtRFdeOEe7PoP0cAlafqOs4zZu2sgHlcPKYDeJN
hF4Dub78fMESoMASAQdAIhgR5ZyuaP12Mav7NNapUcWrScnmjNPh46oX2W3jDDsw hF4Dub78fMESoMASAQdA9f8/bT94aLGvEBuNn11BhGjsTWyU0mKJugMQRCo55HYw
in+hRRYC6apDKMcC3IFEzo6vy7OfhEeMR2IthtU0Y+bgdfjpwEOZ4J5CLg2ERZO+ d/h7PEKHl2GZWydF3lWTKx0cfLDpywmMBary7PtVK4lFYuDdlXodWC85I6UPe8wp
hF4DM6AcvgVUx2MSAQdAKc70+YldBMdetkmcWWJYDSUbewIJOrDCJBS+TUTQ2hQw hF4DM6AcvgVUx2MSAQdA4AKcSfXJei4vmFQ4DF7xzAuA530Cb7rWpK4AE38ByRow
dq03NJuiqwsrN1YBa1qHELTJj7CvrxTvVSQvDpSEwD3WVk8Qn5z1lMgBrivxCGa8 jFako55pUboMSdXtnC/bzy2cFeuRxT0mGMXgLbDri02/nxG+vljeFYJyozb6UXNp
1GYBCQIQj3MkZci7qGULIHivbsOSwX6a3T9JQRkmHylyzZDxYRUz3TLhNvjuly58 1GYBCQIQYmT27KaMqjQq6zFSr1zKEO+PjBH9rCZTBpsCULNxqOMn+3IE7XoYtdPv
TxBJcHkDmXDP5T+UACrryRIN2h/J/+gw6WkHnPJOcs5JFqB9uneVwpW1A3jNMhRD WVU7zZYaK21JRTbnWDjikdvJe60bSRxExIJX35vH3hczc3WP3V/LqQy6X8Fd81pw
iXDXWxIe5PY= pcbiSfWOTXU=
=zp+l =y7H/
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763 fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763
- created_at: "2024-05-11T21:48:51Z" - created_at: "2024-08-20T22:33:06Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hF4Dub78fMESoMASAQdAs3PQ1mkR/MS3vg1qCTPiQihx7yZvQlqlhYRsRigJDiEw hF4Dub78fMESoMASAQdA1W7CmVHBJD/yJWyGvT6lGEXIhsC/gp0XCoHu672OfTMw
WuZYC66MsLHi2YQEkFoxG0bgt3sHkVRlq72ae713UzfWiI0Dl59dxtGcOtvdo5LK OBqitpHTrHyIN7qmexL9YpGsfPtwRGu6hb6lUsWj2+gJ1Pynk6iGM8kwUxGPnj8C
1GYBCQIQIupCIS36+zkecqWl1h55C0G/bC+SHdwgp5nFbva+3fidastsvakUDuTW 1GYBCQIQnO/cJgEhybp/i1E6l4i9IG7cbWupNTp6uJ7Ag8EB6cvUqAYN5QHpM2/D
dGOLK1FC2xUrct/rLGBmWA48fSOA/VJiiEVzP0TsVCytTx/Y44jm0f5HC85LNnNy FYMJRh4skIB2LzG2lxPyOOR5F5FQ2j/Rtf7SoCeEidWOBhGPQPBSNQOTE+43zwKo
8GoFUoOn6tE= Z0pnq864C0c=
=A7C7 =btUj
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0 fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0
- created_at: "2024-05-11T21:48:51Z" - created_at: "2024-08-20T22:33:06Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdAK53bLfsn0k8SFw/88FliX2Yaev9oMGmKSR7f/6vJmH4w hF4DLHeEFiC484ASAQdAsGJfau7e9h38vm5srU1s9vdvYrCUJanDhM6aTjVQU3Uw
pZxJqMwkpWt3We5DAkN+VFuawOzPNrV0vmmd8StlajZ5GIaz713QJQ8cpVrE/sPh jplWFk/1aNsEAeA2yIydiyw/wzY8h+QGrcfDTNViw6Zwq2kRvVp5t9IW1k1IteO3
1GYBCQIQUuj0dgOWLtcB/w1vHj0qQW8LnMG5uVY7gk+hPmllQb8TJ1aRUkcPrKoE 1GYBCQIQWrU3Y1SLCA6tV0xLCUeyZbUrgnCgJNUceRHmSV0oi3jMLEv0YUfbf+Hl
rXUCl17BO59C4AUWLu/0RviAki6FMZC1S0g1z8eOck6CFSnW4i4uMB0g5Yi5kqpK VIDfM6RZQeaY0WVLAuFnIEYFJ1RhXgv9nFo/3txZw3WYx3kjKPPRacmoHMturD+1
K0oWZqedIzU= Ay5oemXyWMo=
=Z8wz =dfVv
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 403215E0F99D2582C7055C512C77841620B8F380 fp: 403215E0F99D2582C7055C512C77841620B8F380
- created_at: "2024-05-11T21:48:51Z" - created_at: "2024-08-20T22:33:06Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA2YOabq+5CZDAQ//beLzskyTj+PN79rvrupVY5gwWxIhYuoRs2ZkJSlNyRYg hQIMA3FYa3pMDBplARAAjkLNlHDhqSgxY2IbP10Rx+KlATMRBqzDq2Wx+gdBuWB6
exNxwPAjssi3yKoUOy9TNbxzOKP5VwehnOPlJ4jyVgdZ9zksJH9k0WnfhlmabHeC uwGX0Lk1FbcqnhGtUYdtiQBU+7y08oSZ0iFv+tOxTBEGjVBcdUQBjYJa0x1X0kcM
UnYsUSDB7VUFrpacdIKjmFM6OPlu7Xm98RwSabkmlHEE/voF/Ma5yWT0c3Sx2lzv xSfY86bxuJAlvBQJWv7iqdwHPks3DhkePqg8sNwSXUA4wk/L8/JAVnkhbqJ9Am9x
ucNSCqmjY0D6S5tJz+3nYsT54OjS+Jlr96CPOR9dz1jEGGQMfwyMxwMLhVpVBDKE VLJk5xjlFsJwyRMoGui8SDogdc6Voe7zValQXVU5b93Z9klO67dFBEL9nfkUNqhr
uusl5VD3jw50wYbkhvYscGGkdOkLwAFMIwYvw1seYFTb3kux8ChahYQ3QtPn3ZUD mwu0QNRMZGQYE9OYlt41kVRy9x8lATm9J9j12MsEnr9R/8viJyBURHwx+DerRsa9
OoPqYUtgpcnZTAcMGvzL7B0OwJLsCpin454yko56KV/cnIHwSv2cyfsQB0M4dz6l tJCf3UgJjcK1F54DTGg/ethCOtYDAGF//U0rU9Fcgwff9axZr6fDqUVHIeeE0GAX
OalAS5BpqhZ2ulDm34yFlRE7MD+H12tOzBJIFjGQksv9DiuRyezZnevBqlOdott8 7cs+yR5Gp+szfEshm4rSTZPOjZB7xVciCUEIKhlXm2y3dL43idWWYj/+50BMUt1p
cSDfO3RD3wGdUOIVwi3B92N5j1w39d2wKoXa19kM66mzsdbQrXwmxKa8gQMkjsG9 HhizkrbsyA+JiAYSE4T4uwOLVoU/jOpecQnn25hrSHX8OoSIIUiaLWFnNMvwobcq
Ds2sUwQlKZ0HvvNkJTJ+NORWKKvwGXKqVPwOTUaZjzQGUtVWg5WSjmFoPQ049nqf 3ummmjAUQ6nxhuO6NQMogrihyqOusidxlBcT7FcP3+V4seo3Co3IlmsCi1w0HmSf
gLYhy0OeyEAIRe9HjNo5YANPNBF63qTT2++n6xs2ErXjHNNi85yUnhCBqRRI3Od6 SzLPtJoIaDcDCSVgnlINzfPT9dvDeTOppgUjHMZjbTZDGdUc+jEXb3P/IIqgjrJi
HkLlLQN3i6RdV5C1wJwu3k1N6a+dl03gFgO3PSJZaLpIhHJuOJwYT3rCGi3ZgzXS XYtvleP3aoQ84GI3SMvpqwqUfd8kkzvVatGrjA55knQq9HA2o+oq5k9nJnOwEjHS
VgFycpleRMSCTjEIY/Ky4PJOlbUykf4CuFWnvJLSOcqjPbozzqjUaw4xzea2Lloj VgFz6zGoYcr62vaAiBVaSR8ozVQpGjNpq9iC0VR3wpz2J7k9Y8XM+5e3amR15Fm7
+Io3l0AHWqKCmv4qbZxim37YuicyM02A56pk7SMKXOuqbb1m5hBr lPV3ZBl7OUxTURxnfUdECdmf+19gObsJsiu5WTsVNYsqMIG8nDR/
=bvPZ =pbOT
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: a53d4ca8d2cf54613822c81d660e69babee42643 fp: 1f18a57e1d4e6716aed0e0cd71586b7a4c0c1a65
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.8.1 version: 3.8.1

View file

@ -0,0 +1,118 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
baseDomain = "koyomi.sbruder.de";
backends = {
hiroshi = [
"bangs.sbruder.de"
"i7y.eu"
"languagetool.sbruder.de"
"phss.sbruder.de"
];
};
fallbackCert = pkgs.runCommandNoCC "fallback-cert" { } ''
cat > openssl.cnf << EOF
[ ca ]
default_ca = CA_default
[ CA_default ]
database = database
new_certs_dir = .
serial = serial
default_md = default
policy = policy_default
[ policy_default ]
EOF
echo 01 > serial
touch database
${pkgs.openssl}/bin/openssl genpkey -algorithm ec -pkeyopt ec_paramgen_curve:P-256 -out fallback.key
${pkgs.openssl}/bin/openssl req -key fallback.key -new -out fallback.csr -subj "/"
${pkgs.openssl}/bin/openssl ca -batch -config openssl.cnf -in fallback.csr -keyfile fallback.key -selfsign -out fallback.crt -startdate 19700101000000Z -enddate 20380119031407Z
mkdir $out
cat fallback.{key,crt} > $out/full.pem
mv fallback.{crt,key} $out
'';
in
{
services.haproxy = {
enable = true;
config = ''
global
stats socket /var/run/haproxy/haproxy-admin.sock mode 600 level admin
stats timeout 2m
defaults
timeout client 30s
timeout server 30s
timeout connect 30s
resolvers system
parse-resolv-conf
frontend http-in
bind :80
mode http
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
use_backend http-${name} if { hdr(Host) -i ${lib.concatStringsSep " " domains} and path_beg '/.well-known/acme-challenge/' }
'') backends)}
default_backend https-redirect
frontend https-in
bind :443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req.ssl_hello_type 1 }
tcp-request content reject if WAIT_END
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
use_backend https-${name} if { req.ssl_sni -i ${lib.concatStringsSep " " domains} }
'') backends)}
default_backend https-fallback
frontend v6-in
bind [::]:80
bind [::]:443 ssl crt ${fallbackCert}/full.pem
mode http
http-request return status 400 content-type text/html string "<html><body><h1>400 Bad Request</h1>For requests over IPv6, please use the address of the virtual machine directly.</body></html>"
frontend fallback
bind /var/run/haproxy/fallback.sock ssl crt ${fallbackCert}/full.pem
mode http
frontend stats
bind ${config.sbruder.wireguard.home.address}:8404
mode http
http-request use-service prometheus-exporter if { path /metrics }
stats enable
stats uri /stats
stats refresh 10s
backend https-redirect
mode http
http-request redirect scheme https
backend https-fallback
server fallback /var/run/haproxy/fallback.sock
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
backend http-${name}
mode http
server ${name} ${name}.${baseDomain}:80 resolvers system resolve-prefer ipv4 send-proxy-v2
'') backends)}
${lib.concatStrings (lib.mapAttrsToList (name: domains: ''
backend https-${name}
mode tcp
server ${name} ${name}.${baseDomain}:443 resolvers system resolve-prefer ipv4 send-proxy-v2
'') backends)}
'';
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
}

View file

@ -5,10 +5,15 @@
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let let
guests = { guests = {
forgejo-actions-runner = { ci-runner = {
mac = "42:80:00:00:00:02"; mac = "42:80:00:00:00:02";
v4 = "10.80.32.2"; v4 = "10.80.32.2";
v6 = "2a01:4f8:151:712d:1::2"; v6 = "2a01:4f9:3051:39c6:1::2";
};
hiroshi = {
mac = "42:80:00:00:00:03";
v4 = "10.80.32.3";
v6 = "2a01:4f9:3051:39c6:1::3";
}; };
}; };
@ -19,6 +24,16 @@ let
}; };
in in
{ {
sbruder.restic = {
enable = true;
backups.vm-image = {
enable = true;
lvm.lvs = [
"hiroshi"
];
};
};
virtualisation.libvirtd = { virtualisation.libvirtd = {
enable = true; enable = true;
qemu.package = pkgs.qemu_kvm; qemu.package = pkgs.qemu_kvm;
@ -42,7 +57,7 @@ in
networks = { networks = {
br-virt = { br-virt = {
name = "br-virt"; name = "br-virt";
address = [ "10.80.32.1/24" "2a01:4f8:151:712d:1::1/80" ]; address = [ "10.80.32.1/24" "2a01:4f9:3051:39c6:1::1/80" ];
}; };
}; };
}; };
@ -68,7 +83,7 @@ in
# Force static configuration # Force static configuration
dhcp-range = [ dhcp-range = [
"10.80.32.0,static,255.255.255.0" "10.80.32.0,static,255.255.255.0"
"2a01:4f8:151:712d:1::,static,80" "2a01:4f9:3051:39c6:1::,static,80"
]; ];
dhcp-host = lib.flatten (lib.mapAttrsToList dhcp-host = lib.flatten (lib.mapAttrsToList

View file

@ -19,10 +19,13 @@
gui.enable = true; gui.enable = true;
media-proxy.enable = true; media-proxy.enable = true;
podman.enable = true; podman.enable = true;
restic.system = { restic = {
enable = true;
backups.system = {
enable = true; enable = true;
qos = true; qos = true;
}; };
};
unfree.allowSoftware = true; unfree.allowSoftware = true;
wireguard.home.enable = true; wireguard.home.enable = true;
}; };

View file

@ -13,10 +13,13 @@
sbruder = { sbruder = {
gui.enable = true; gui.enable = true;
restic.system = { restic = {
enable = true;
backups.system = {
enable = true; enable = true;
qos = true; qos = true;
}; };
};
unfree.allowSoftware = true; unfree.allowSoftware = true;
wireguard.home.enable = true; wireguard.home.enable = true;
}; };

View file

@ -9,7 +9,6 @@
./hardware-configuration.nix ./hardware-configuration.nix
../../modules ../../modules
./services/bang-evaluator.nix
./services/buchborgen.nix ./services/buchborgen.nix
./services/coturn.nix ./services/coturn.nix
./services/element-web.nix ./services/element-web.nix
@ -17,19 +16,16 @@
./services/grafana.nix ./services/grafana.nix
./services/hedgedoc.nix ./services/hedgedoc.nix
./services/invidious ./services/invidious
./services/mastodon.nix
./services/matrix ./services/matrix
./services/password-hash-self-service.nix
./services/prometheus.nix ./services/prometheus.nix
./services/sbruder.xyz ./services/sbruder.xyz
./services/schabernack.nix
]; ];
sbruder = { sbruder = {
nginx.hardening.enable = true; nginx.hardening.enable = true;
restic.system = { restic = {
enable = true; enable = true;
prune = true; backups.system.enable = true;
}; };
wireguard.home.enable = true; wireguard.home.enable = true;
infovhost.enable = true; infovhost.enable = true;

View file

@ -2,10 +2,8 @@ forgejo-mail: ENC[AES256_GCM,data:3AlFHzVBA5TE4qv5ubG39K0varV8/HabO0q/RJZSD5o=,i
go-neb-overrides: ENC[AES256_GCM,data:1xy+SdsSTuerRox4skitg1mKLr1MoANFoCzz76TKSA31ORo/oUWVGrYxfusZxrFQWjYGRFpSYzmkzPn1RoWmbXyfwPEcisvjenXLNvwcyoontBd7TiiLdukEtya6RfGLRGKc8tfCzbDUWgiYz5IDMFBvKGnewFjB+au0/Ge2+2DTw6M4negjCz343TO/vbyTr5xT/5smmKz7Ouk9SbEo7yEuHkQPQfedGw2PYT82zdXd/Eje3Zq2EB4xcUU7beGrF1zkOdXQ4OVqB8XnkCnuLtNlnJtsffm0rbPDPD3/nhHKpJ8jXrN54V14dSnHW7yOifGMIus0VFMRZcIT7A+BroM9qzJhW3F4gsF1Bwp0CF+6zLLRjgpA0EOyvOwpLIftBZfMIpveAH62MVY0IBfwDdkI1itEOjj9EhTrOGxBx45Cj6Qk3Mk6ncyr15+E+KAmQRxZJrEW8Grk4PyzuxtxYd0n8LSaRUe1eNVUhHkQNpo/zvAPgrzcRnM91EwIoMvlNmwyC63j1h+OBKlXQgChAaB1O6HFXQY=,iv:pnw0jIcMqA771woDYNHxWMWE6wHGaNsXi5aBXOFAHJU=,tag:Wbcqb0FsctZWOS6u5s82mQ==,type:str] go-neb-overrides: ENC[AES256_GCM,data:1xy+SdsSTuerRox4skitg1mKLr1MoANFoCzz76TKSA31ORo/oUWVGrYxfusZxrFQWjYGRFpSYzmkzPn1RoWmbXyfwPEcisvjenXLNvwcyoontBd7TiiLdukEtya6RfGLRGKc8tfCzbDUWgiYz5IDMFBvKGnewFjB+au0/Ge2+2DTw6M4negjCz343TO/vbyTr5xT/5smmKz7Ouk9SbEo7yEuHkQPQfedGw2PYT82zdXd/Eje3Zq2EB4xcUU7beGrF1zkOdXQ4OVqB8XnkCnuLtNlnJtsffm0rbPDPD3/nhHKpJ8jXrN54V14dSnHW7yOifGMIus0VFMRZcIT7A+BroM9qzJhW3F4gsF1Bwp0CF+6zLLRjgpA0EOyvOwpLIftBZfMIpveAH62MVY0IBfwDdkI1itEOjj9EhTrOGxBx45Cj6Qk3Mk6ncyr15+E+KAmQRxZJrEW8Grk4PyzuxtxYd0n8LSaRUe1eNVUhHkQNpo/zvAPgrzcRnM91EwIoMvlNmwyC63j1h+OBKlXQgChAaB1O6HFXQY=,iv:pnw0jIcMqA771woDYNHxWMWE6wHGaNsXi5aBXOFAHJU=,tag:Wbcqb0FsctZWOS6u5s82mQ==,type:str]
hcloud_exporter-environment: ENC[AES256_GCM,data:5gDTeg4C08BgNxBFtzZ7ma6JiafwF4ly5URAG4WxUTlRaUmF32fmbPdAZmveKiKBA8cc6ewcEIfIVJ7d5tbbqCEX+vbf9nr1fuhN05Z6lfsJNLoATclX,iv:GzEnudGDc6+6BJgDtaNnOnT7IK8Z0fsYfs/oJzKO2UA=,tag:LYCvRxNeKdMmNve0aWswrw==,type:str] hcloud_exporter-environment: ENC[AES256_GCM,data:5gDTeg4C08BgNxBFtzZ7ma6JiafwF4ly5URAG4WxUTlRaUmF32fmbPdAZmveKiKBA8cc6ewcEIfIVJ7d5tbbqCEX+vbf9nr1fuhN05Z6lfsJNLoATclX,iv:GzEnudGDc6+6BJgDtaNnOnT7IK8Z0fsYfs/oJzKO2UA=,tag:LYCvRxNeKdMmNve0aWswrw==,type:str]
invidious-extra-settings: ENC[AES256_GCM,data:bThgfyu5ESIyTLD7Q09Qici9ZZw/QYfCyBSjtbNb1EglCy0KHZrvDDAN4uDpdKrHxv8ctoN5Db7tRf5LUl6iyW7A5z9uYg481EXq3Sx6tZztepX0vg==,iv:FZ33tQWRsNEPjwuy/mH/N4e4PyjLx7sbv2G+9S5uigY=,tag:0GQn3AgoM2BPC5iCt5py8w==,type:str] invidious-extra-settings: ENC[AES256_GCM,data:bThgfyu5ESIyTLD7Q09Qici9ZZw/QYfCyBSjtbNb1EglCy0KHZrvDDAN4uDpdKrHxv8ctoN5Db7tRf5LUl6iyW7A5z9uYg481EXq3Sx6tZztepX0vg==,iv:FZ33tQWRsNEPjwuy/mH/N4e4PyjLx7sbv2G+9S5uigY=,tag:0GQn3AgoM2BPC5iCt5py8w==,type:str]
mastodon-mail: ENC[AES256_GCM,data:RT/fS7cqbcePd2qe7CR5jRh2jtKaS81ICbMUOlPUQsY=,iv:C7GYMB0U2KIfXuEnYaoIEfV89/EnJS6V9iG97X8zkPk=,tag:L4SVe6aYGcarvX1hmMqQOw==,type:str]
netbox-secret-key: ENC[AES256_GCM,data:lOE95j6CGkbfJQTLeG41g3BPKNhm0arqxIGAzwvXQyeZLBauAdqufQGKD7D4kPNzdZs=,iv:6HWXEr6Ju4IywP+2jpuTfER/bYI2oUgMSZEJCkq4XX8=,tag:TPD5TTr4Sew8lxPS5WIu5Q==,type:str] netbox-secret-key: ENC[AES256_GCM,data:lOE95j6CGkbfJQTLeG41g3BPKNhm0arqxIGAzwvXQyeZLBauAdqufQGKD7D4kPNzdZs=,iv:6HWXEr6Ju4IywP+2jpuTfER/bYI2oUgMSZEJCkq4XX8=,tag:TPD5TTr4Sew8lxPS5WIu5Q==,type:str]
prometheus-htpasswd: ENC[AES256_GCM,data:tiewfUfpvrmbrgk6AsBdiP4ng4TqG5UYf1mFcWOzuk8oO55rfZu+Naummz5RRYhJZil43nHFvn5LfIWkJv+CyPMZjpj7xRp4vb4/OCCAFjEzHhrzYVBYNkHM+ZLUTewEXuPVtZ6CZ5uviTExLN2V1moG3ExJdIoyUD16qh4=,iv:SkH609VxIVKJLmHUUNzICEjxHSyjLdwXfw0b7iU6png=,tag:BfNGcUZmk9ZXUvhoQZn6iQ==,type:str] prometheus-htpasswd: ENC[AES256_GCM,data:tiewfUfpvrmbrgk6AsBdiP4ng4TqG5UYf1mFcWOzuk8oO55rfZu+Naummz5RRYhJZil43nHFvn5LfIWkJv+CyPMZjpj7xRp4vb4/OCCAFjEzHhrzYVBYNkHM+ZLUTewEXuPVtZ6CZ5uviTExLN2V1moG3ExJdIoyUD16qh4=,iv:SkH609VxIVKJLmHUUNzICEjxHSyjLdwXfw0b7iU6png=,tag:BfNGcUZmk9ZXUvhoQZn6iQ==,type:str]
restic-ssh-key: ENC[AES256_GCM,data:9quBzUwv4qylVzESG94wSgzvuodSDM/smPh0j+LYJjXwEN1xksBIW2/Jv0XmF3Q+AWUF/C/lA2jteI3Mf6Pmn7zlqa3H7GwH8Os6/arQI3ywH2dHQLAFxgST2J0AlLGeZcJbntxW0buYw+Rz3q5Jbo+Wo9tQo+2EVvqX320qWBsEwinnahbUhZym3fipyE9g6JxGa3OFGiIn6JAQhst63WgpOfehQsAYu2bdW1gLrgFtURzDQQRQ28RxeD+nMUWRpQcq5GrX2rfSA7sengfQbmP3Ln1atp1YXctTalHsj+n4photBqLz6OfLaFKBqbdKRbinUgVAEarAocEOKk/qf1C6LS8yKjV9Mh/tKeCJQrCI/AccEP5DfMNqdRaWjoQxvjBRKaupPE7Rcuja++K/jm24nP9J8WDcrRSm0tlrVq2JnPHxJv+eUsZoGkvpyOs9AkTG1H2BCckYS5ZG4atjKoBfUvc3CitPNmPZcjSkPrkdRMZbu1BWR+cixFH9rFAUvVIn+e7sWGnqMA8xGXZS,iv:rLOTtmIFP7rwF9JY9ardO9pNqNh1uaobHKtQaGwSuGk=,tag:pCd4ZV0FjfD18qj9oQ236Q==,type:str]
synapse-registration-shared-secret: ENC[AES256_GCM,data:qwUjGPINIuBC3KYqMPmnU3l9uJ85DJsJFixvTFQTSuR+fcq6DEjx03Xk41ff7NJftAi+Gt0QLdqKp+viJfW7eU6iHKyfcgPE/nj46UECCWLM8HISxPFQ9IrP+DIo02k=,iv:C9jhBPexth+gnAs6+DBtEmP2qsWZoKmgw6ILbtXUScA=,tag:M3U+03I0Bj8Nhuu4GB98xw==,type:str] synapse-registration-shared-secret: ENC[AES256_GCM,data:qwUjGPINIuBC3KYqMPmnU3l9uJ85DJsJFixvTFQTSuR+fcq6DEjx03Xk41ff7NJftAi+Gt0QLdqKp+viJfW7eU6iHKyfcgPE/nj46UECCWLM8HISxPFQ9IrP+DIo02k=,iv:C9jhBPexth+gnAs6+DBtEmP2qsWZoKmgw6ILbtXUScA=,tag:M3U+03I0Bj8Nhuu4GB98xw==,type:str]
synapse-turn-shared-secret: ENC[AES256_GCM,data:9MAsVAEnoF703p1enN70BXqlKZWacYmPCL25CNGdapZulGbMF5rAbpLxkJ3JiBNBYQt+DXSSb6zcmsT6yIqQZ4lW04lwtFV0RPJLfbfW9vUJQ3Bi5NUF,iv:keDUMEeintOwbBQzHHqVl8EFyQC1zqKG2LDvnBFSBxE=,tag:ymSwjZ+qC5kLIxMxlxwcAQ==,type:str] synapse-turn-shared-secret: ENC[AES256_GCM,data:9MAsVAEnoF703p1enN70BXqlKZWacYmPCL25CNGdapZulGbMF5rAbpLxkJ3JiBNBYQt+DXSSb6zcmsT6yIqQZ4lW04lwtFV0RPJLfbfW9vUJQ3Bi5NUF,iv:keDUMEeintOwbBQzHHqVl8EFyQC1zqKG2LDvnBFSBxE=,tag:ymSwjZ+qC5kLIxMxlxwcAQ==,type:str]
turn-static-auth-secret: ENC[AES256_GCM,data:HyFKdLn9yClXwVGv4/UcC5QfnqjTK2ui43/SRJiJYC7soP+BZnbtCTFkVe04H2smRQQi9ftrXLWQQx5DdGZxpg==,iv:tIwZcq4pVzWa1bl7zX/YsEuaVCyDenJnPGL0RhF9lmg=,tag:ddXaLQ3U990eupAHLyXx6w==,type:str] turn-static-auth-secret: ENC[AES256_GCM,data:HyFKdLn9yClXwVGv4/UcC5QfnqjTK2ui43/SRJiJYC7soP+BZnbtCTFkVe04H2smRQQi9ftrXLWQQx5DdGZxpg==,iv:tIwZcq4pVzWa1bl7zX/YsEuaVCyDenJnPGL0RhF9lmg=,tag:ddXaLQ3U990eupAHLyXx6w==,type:str]
@ -16,8 +14,8 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-06-01T12:03:17Z" lastmodified: "2024-10-08T20:39:38Z"
mac: ENC[AES256_GCM,data:6fJfEtnHSQV7oGZ7HMrXYH1lX8ZzfTChOZC25scDP/q5FH8QZ52OntRuQ8DbR+AKUPN/w6o4EotZVxX53Q2Xxi6QdHSqo07GDsWUnIOb5eCNGmEB3c2w20DJv2smTnEr7d6051aPzEUO0ZxUPxxlqcifC6dsdpdxySyG/VY9OQQ=,iv:KAWFRoOQKRd2tf58QYGD8SnHJk1aLwBxgkcRkPgjuN8=,tag:LJFOJuFblp53Te9zoYKq0Q==,type:str] mac: ENC[AES256_GCM,data:tgrvHkBsuxvkOe65YUkA/7iOcuwE3Vd6l46wLRSXK2DVED2FAdvO/cXvwsUKzIRKjrs/QXUl4T+lWGQC024Wiy6gXQB3edjxDT6aiGSzXWQAOmTI8/oLzxNTeuysTKNtIAxbz5x6d88JFx5PswtuYUb8x60xMPp3LTJbKnao/LI=,iv:l48P6gmEyeqSOHotLRCmYb7aZgnANceUvveVvGgpAyE=,tag:X5fFIxDxW9sIO4yF4B0C5Q==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:10Z" - created_at: "2024-01-22T00:20:10Z"
enc: |- enc: |-

View file

@ -3,20 +3,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ lib, pkgs, ... }: { lib, pkgs, ... }:
let
# This uses
# https://github.com/vector-im/element-web#configuration-best-practices
# but allows to disable the frame-ancestors rule for /usercontent/.
mkSecurityHeaders = withFrameOptions: ''
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
'' + lib.optionalString withFrameOptions ''
add_header Content-Security-Policy "frame-ancestors 'none'";
'' + lib.optionalString (!withFrameOptions) ''
add_header Content-Security-Policy "frame-ancestors 'self'";
'';
in
{ {
services.nginx.virtualHosts."chat.sbruder.de" = { services.nginx.virtualHosts."chat.sbruder.de" = {
enableACME = true; enableACME = true;
@ -24,8 +11,13 @@ in
root = pkgs.element-web; root = pkgs.element-web;
extraConfig = mkSecurityHeaders true; # https://github.com/vector-im/element-web#configuration-best-practices
locations."/usercontent/".extraConfig = mkSecurityHeaders false; extraConfig = ''
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "frame-ancestors 'self'";
'';
# nixpkgss override mechanism doesnt allow overriding of all options # nixpkgss override mechanism doesnt allow overriding of all options
locations."=/config.chat.sbruder.de.json".alias = pkgs.writeText "config.chat.sbruder.de.json" (lib.generators.toJSON { } { locations."=/config.chat.sbruder.de.json".alias = pkgs.writeText "config.chat.sbruder.de.json" (lib.generators.toJSON { } {

View file

@ -0,0 +1,29 @@
From 9167e70698e82ba9f9c41bff32154bb531322a11 Mon Sep 17 00:00:00 2001
From: Omar Roth <omarroth@protonmail.com>
Date: Wed, 28 Aug 2024 10:34:47 +0200
Subject: [PATCH 2/2] Require login
Co-authored-by: Simon Bruder <simon@sbruder.de>
---
src/invidious/routes/before_all.cr | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/invidious/routes/before_all.cr b/src/invidious/routes/before_all.cr
index 5695dee9..c981a463 100644
--- a/src/invidious/routes/before_all.cr
+++ b/src/invidious/routes/before_all.cr
@@ -122,5 +122,11 @@ module Invidious::Routes::BeforeAll
end
env.set "current_page", URI.encode_www_form(current_page)
+
+ unregistered_path_whitelist = {"/login", "/licenses", "/privacy"}
+ if !env.get?("user") && !unregistered_path_whitelist.includes?(env.request.path)
+ env.response.headers["Location"] = "/login"
+ haltf env, status_code: 302
+ end
end
end
--
2.44.1

View file

@ -0,0 +1,4 @@
SPDX-FileCopyrightText: 2019 Omar Roth <omarroth@protonmail.com>
SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
SPDX-License-Identifier: AGPL-3.0-or-later

View file

@ -17,6 +17,7 @@
package = pkgs.unstable.invidious.overrideAttrs (o: o // { package = pkgs.unstable.invidious.overrideAttrs (o: o // {
patches = (o.patches or [ ]) ++ [ patches = (o.patches or [ ]) ++ [
./0001-Prefer-opus-audio-streams-in-listen-mode.patch ./0001-Prefer-opus-audio-streams-in-listen-mode.patch
./0002-Require-login.patch
]; ];
}); });
nginx.enable = true; nginx.enable = true;
@ -42,6 +43,8 @@
modified_source_code_url = "https://github.com/sbruder/invidious/tree/patches"; modified_source_code_url = "https://github.com/sbruder/invidious/tree/patches";
https_only = lib.mkForce true; https_only = lib.mkForce true;
registration_enabled = false;
# this can be removed # this can be removed
# when this service is re-deployed on a host with state version ≥ 24.05 # when this service is re-deployed on a host with state version ≥ 24.05
db.user = "invidious"; db.user = "invidious";
@ -62,7 +65,6 @@
''; '';
locations = { locations = {
"/robots.txt".return = "200 'User-agent: *\\nDisallow: /'"; "/robots.txt".return = "200 'User-agent: *\\nDisallow: /'";
"/privacy".return = "301 'https://sbruder.xyz/#privacy'";
"/feed/popular".return = "403"; # leaks data about its users "/feed/popular".return = "403"; # leaks data about its users
}; };
}; };

View file

@ -1,32 +0,0 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, ... }:
{
sops.secrets.mastodon-mail = {
owner = config.services.mastodon.user;
sopsFile = ../secrets.yaml;
};
services.mastodon = {
enable = true;
configureNginx = true;
localDomain = "procrastination.space";
smtp = {
createLocally = false;
host = "vueko.sbruder.de";
port = 465;
user = "mastodon@sbruder.de";
passwordFile = config.sops.secrets.mastodon-mail.path;
fromAddress = config.services.mastodon.smtp.user;
authenticate = true;
};
streamingProcesses = 5;
extraConfig = {
SMTP_TLS = "true";
RAILS_LOG_LEVEL = "warn";
};
};
}

View file

@ -8,4 +8,9 @@
./mautrix-whatsapp.nix ./mautrix-whatsapp.nix
./go-neb.nix ./go-neb.nix
]; ];
# required by mautrix-whatsapp and go-neb
nixpkgs.config.permittedInsecurePackages = [
"olm-3.2.16"
];
} }

View file

@ -8,6 +8,12 @@ let
mkStaticTargets = targets: lib.singleton { inherit targets; }; mkStaticTargets = targets: lib.singleton { inherit targets; };
mkStaticTarget = target: mkStaticTargets (lib.singleton target); mkStaticTarget = target: mkStaticTargets (lib.singleton target);
relabelVpnConfig = {
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:[0-9]*";
};
in in
{ {
services.prometheus = { services.prometheus = {
@ -76,12 +82,9 @@ in
"nazuna.vpn.sbruder.de:9100" "nazuna.vpn.sbruder.de:9100"
"yuzuru.vpn.sbruder.de:9100" "yuzuru.vpn.sbruder.de:9100"
"koyomi.vpn.sbruder.de:9100" "koyomi.vpn.sbruder.de:9100"
"hiroshi.vpn.sbruder.de:9100"
]; ];
relabel_configs = lib.singleton { relabel_configs = lib.singleton relabelVpnConfig;
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:9100";
};
} }
{ {
job_name = "smartctl"; job_name = "smartctl";
@ -93,11 +96,7 @@ in
"shinobu.vpn.sbruder.de:9633" "shinobu.vpn.sbruder.de:9633"
"koyomi.vpn.sbruder.de:9633" "koyomi.vpn.sbruder.de:9633"
]; ];
relabel_configs = lib.singleton { relabel_configs = lib.singleton relabelVpnConfig;
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:9633";
};
} }
{ {
job_name = "qbittorrent"; job_name = "qbittorrent";
@ -105,11 +104,7 @@ in
"fuuko.vpn.sbruder.de:9561" "fuuko.vpn.sbruder.de:9561"
"nazuna.vpn.sbruder.de:9561" "nazuna.vpn.sbruder.de:9561"
]; ];
relabel_configs = lib.singleton { relabel_configs = lib.singleton relabelVpnConfig;
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:9561";
};
} }
( (
let let
@ -128,10 +123,7 @@ in
{ {
job_name = "dnsmasq"; job_name = "dnsmasq";
static_configs = mkStaticTarget "shinobu.vpn.sbruder.de:${toString config.services.prometheus.exporters.dnsmasq.port}"; static_configs = mkStaticTarget "shinobu.vpn.sbruder.de:${toString config.services.prometheus.exporters.dnsmasq.port}";
relabel_configs = lib.singleton { relabel_configs = lib.singleton relabelVpnConfig;
target_label = "instance";
replacement = "shinobu";
};
} }
{ {
job_name = "hcloud"; job_name = "hcloud";
@ -158,11 +150,7 @@ in
"okarin.vpn.sbruder.de:9433" "okarin.vpn.sbruder.de:9433"
"yuzuru.vpn.sbruder.de:9433" "yuzuru.vpn.sbruder.de:9433"
]; ];
relabel_configs = lib.singleton { relabel_configs = lib.singleton relabelVpnConfig;
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:9433";
};
} }
{ {
job_name = "snmp"; job_name = "snmp";
@ -188,6 +176,13 @@ in
} }
]; ];
} }
{
job_name = "haproxy";
static_configs = mkStaticTargets [
"koyomi.vpn.sbruder.de:8404"
];
relabel_configs = lib.singleton relabelVpnConfig;
}
]; ];
rules = rules =

View file

@ -1,63 +0,0 @@
# SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# I dont do this, because I want to.
# I think I might have to do this because of § 8.2 of Hetzners ToS.
{ config, lib, ... }:
let
serviceBlocks = {
nitter = [
{ path = "/ks1v/status/1439866313476689924"; report = "2023-04-21-Hetzner-C591581F-ROSKOMNADZOR.txt"; }
];
iv = [
{ video = "NR57D2UVqm4"; report = "2023-04-28-Hetzner-C633C02D-ROSKOMNADZOR.txt"; }
];
libreddit = [
];
};
in
{
services.nginx.virtualHosts = lib.mapAttrs'
(domain: blocks: lib.nameValuePair "${domain}.sbruder.xyz" {
locations = lib.listToAttrs
(map
(block:
let
# workaround for nginx dropping parent headers
# see https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheaderredefinition.md
parentHeaders = lib.concatStringsSep "\n" (lib.filter
(lib.hasPrefix "add_header ")
(lib.splitString "\n" config.services.nginx.commonHttpConfig));
transparency_url = "https://sbruder.xyz/transparency/${block.report}";
return_statement = ''
${parentHeaders}
add_header Link "<${transparency_url}>; rel=blocked-by" always;
add_header Content-Type text/html always;
return 451 '<html><head><title>451 Unavailable For Legal Reasons</title></head><body><center><h1>451 Unavailable For Legal Reasons</h1><p><a href="${transparency_url}">Transparency</a></p></center><hr><center>nginx</center></body></html>';
'';
path =
if block ? "path"
then block.path
else
(if block ? "video"
then "/" # not pretty, but I dont know how to do this differently
else throw "invalid block");
location_block =
if block ? "video"
then {
extraConfig = ''
if ($arg_v = ${block.video}) {
${return_statement}
}
'';
}
else { extraConfig = return_statement; };
in
lib.nameValuePair
path
location_block)
blocks);
})
serviceBlocks;
}

View file

@ -5,10 +5,6 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
{ {
imports = [
./blocks.nix
];
services.nginx.virtualHosts."sbruder.xyz" = { services.nginx.virtualHosts."sbruder.xyz" = {
root = pkgs.stdenvNoCC.mkDerivation { root = pkgs.stdenvNoCC.mkDerivation {
name = "sbruder.xyz"; name = "sbruder.xyz";
@ -45,13 +41,6 @@
locations = { locations = {
"/imprint/".alias = "${pkgs.sbruder.imprint}/"; "/imprint/".alias = "${pkgs.sbruder.imprint}/";
"/transparency/" = {
alias = "/var/www/transparency/";
extraConfig = ''
autoindex on;
charset utf-8;
'';
};
}; };
}; };
} }

View file

@ -1,47 +1,29 @@
<!-- <!--
SPDX-FileCopyrightText: 2022-2023 Simon Bruder <simon@sbruder.de> SPDX-FileCopyrightText: 2022-2024 Simon Bruder <simon@sbruder.de>
SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-License-Identifier: CC-BY-SA-4.0
--> -->
On this domain, the following services are currently available: ## End of life
* [Invidious](https://iv.sbruder.xyz) Because of the increasing hostility of YouTube,
the public availability of the Invidious service was discontinued on **2024-09-27**.
Registration of new accounts is disabled since **2024-08-22**.
Access by unauthenticated users is disabled since **2024-08-28**.
All accounts which did not explicitly opt out were deleted on **2024-09-29**.
They are all semi-public instances. This information site is scheduled to be deleted in late Q4 2024.
That means, they are not included in lists of public instances,
but feel free to use them for personal purposes.
You can do so by using a browser plugin like [Privacy Redirect](https://github.com/SimonBrazell/privacy-redirect)
and configuring the addresses to point to this server.
However, please note the following if you want to use them:
* These services are provided as-is without any guarantees.
* You must not use these services for any activities illegal under German law.
* You must not use these services to interfere with the operation of the services
or the sites that originally provide the data.
* Please dont over/abuse these services.
They run on a tiny VPS and wont be able to handle high workloads.
Also note the following service-specific things:
* **Invidious**: There are no backups, so you are responsible for using the data export feature to back up important data.
The VPS providing the services is running NixOS.
The configuration is available [here](https://git.sbruder.de/simon/nixos-config/src/branch/master/machines/renge).
If you have any questions, please [contact me](https://sbruder.de).
## History ## History
Previously, the following services were also available: Previously, the following services were also publicly available:
* [Invidious](https://iv.sbruder.xyz)
* [Libreddit](https://libreddit.sbruder.xyz) * [Libreddit](https://libreddit.sbruder.xyz)
* [Nitter](https://nitter.sbruder.xyz) * [Nitter](https://nitter.sbruder.xyz)
They are no longer offered, They are no longer offered,
as both Twitter (which no longer exists in its previous form) and Reddit as Twitter (which no longer exists in its previous form), Reddit, and YouTube
have become extremely hostile to third party applications, have become extremely hostile to third party applications,
which made them unreliable and forced the developers (at least for Libreddit) which made them unreliable and forced the developers (at least for Libreddit)
to discontinue development. to discontinue development.
@ -50,40 +32,10 @@ The recommended migration path is to use alternative hosted instances
(<https://nitter.net> has been mostly working at the time of writing this) (<https://nitter.net> has been mostly working at the time of writing this)
or discontinue usage of that platform. or discontinue usage of that platform.
<!-- REUSE-IgnoreStart -->
## A Note to Copyright Holders
The services are only relaying content that is otherwise already available on the Internet.
If your rights are infringed by content available from this site,
please report this to the site originally making it available.
Otherwise the content will still be available on the Internet.
If you still want to report illegal content to me instead of the original site,
you can contact me by the means specified in the imprint.
Please dont send letters by snail mail if you want a fast response.
<!-- REUSE-IgnoreEnd -->
## Imprint ## Imprint
See [Imprint](/imprint/). See [Imprint](/imprint/).
## Privacy
If you log in to an Invidious account,
the data you provide to the service will be stored.
You can export or delete that data by using its built-in data control feature.
In the case of an error, details of the problematic request might be stored on the server
and used strictly for debugging and fixing the error.
## Transparency
For transparency reasons,
you can find all take down requests [here](/transparency/).
I was not sure if the reported content could be seen as violating Hetzners ToS,
and therefore complied, even though I dont want to support the authority asking for removal.
#### Fine Print #### Fine Print
<small> <small>

View file

@ -1,48 +0,0 @@
# SPDX-FileCopyrightText: 2021-2022 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
domain = "schulischer-schabernack.de";
in
{
services.nginx = {
commonHttpConfig = ''
# privacy-aware log format
log_format schabernack '$remote_addr_schabernack - - [$time_local] "$request" $status $body_bytes_sent "-" "$http_user_agent"';
# anonymise ip address
map $remote_addr $remote_addr_schabernack {
~(?P<ip>\d+\.\d+)\. $ip.0.0;
~(?P<ip>[^:]+:[^:]+): $ip::;
default 0.0.0.0;
}
'';
virtualHosts = {
${domain} = {
forceSSL = true;
enableACME = true;
root = "/var/www/schabernack";
# only log page views, rss feed access, media file download and embed views
extraConfig = ''
location ~ index\.html|rss\.xml|\.(opus|m4a|ogg|mp3|\.podlove.json)$ {
access_log /var/log/nginx/schabernack.log schabernack;
}
'';
};
"www.${domain}" = {
forceSSL = true;
enableACME = true;
globalRedirect = domain;
extraConfig = ''
access_log off;
'';
};
};
};
}

View file

@ -1,3 +1,4 @@
wg-he-private-key: ENC[AES256_GCM,data:bT1G2nZHJO9j04I4j3QZYn7BxGX4XHxzgXDr3iFTnu/kirik6+0Eh/AUp+4=,iv:SeowjlP64t8lPn+WXqrOtZJWA3geTSO9ST9JNuPQwu0=,tag:ctLXe7BP0Ob/ADD4q7yOmg==,type:str]
wg-home-private-key: ENC[AES256_GCM,data:gm4INfmp226u4wp+LuKgf5m2nTFFw4S24w4PRPcW/A7CU713c9NtQ+kPDKg=,iv:JAir9z5/Db6+Oroq+0vXPZLZLA2gjY2Be6hRAmgV5AE=,tag:fxL9nK3v5xERfcoBbCUsXg==,type:str] wg-home-private-key: ENC[AES256_GCM,data:gm4INfmp226u4wp+LuKgf5m2nTFFw4S24w4PRPcW/A7CU713c9NtQ+kPDKg=,iv:JAir9z5/Db6+Oroq+0vXPZLZLA2gjY2Be6hRAmgV5AE=,tag:fxL9nK3v5xERfcoBbCUsXg==,type:str]
wg-upstream-private-key: ENC[AES256_GCM,data:CO50H7QsLQ2x0QQXnB7c0leG8NdV66gWrdWBWOR9z4ukSN7qj/qqe83t82k=,iv:2as2HfTfRje3TEap8QpPfzz4saNDgjo6Ty1DTF23JVE=,tag:ZYe+59wrpX7mV1HcDllMdg==,type:str] wg-upstream-private-key: ENC[AES256_GCM,data:CO50H7QsLQ2x0QQXnB7c0leG8NdV66gWrdWBWOR9z4ukSN7qj/qqe83t82k=,iv:2as2HfTfRje3TEap8QpPfzz4saNDgjo6Ty1DTF23JVE=,tag:ZYe+59wrpX7mV1HcDllMdg==,type:str]
hostapd-config: ENC[AES256_GCM,data:a0ESrrsquLq6VRJM588C5A+FmVxJwJSzwRuv2o//LL5OybcDS8jkVUajosXEs0qmQ6Xfc1gFDcevCYUwJ24eZ+ynKLWwoNx8RXXwbpllO7FkI68vcauUij1CtUgVb8aHheKfrFuyW7WU1wE3NTtOt2gij1+nM3iKS3vFXtX2n9L2fuy2b3EhOUBiakxAeQmyVmclSVBDYt12i4h4tW7GpPr8AjoIiZgz0Hyx5zA5f/JTPzz/P200eM0tCttNPbMNPBGztJfw7raRIX+v6xw7QNPMgf03TOae17mt6uggTNKJfEPeanzcEMA3xR6xoFUqJL6Hvowyl4MrSFc+E5Rvft+qhp8m6tAqQln9Z3MzaDtxSBWnWdvWEcyeK1aDBQ57/aIwo8kVs47Iblqbi5+jM/n4DoeQtqTM1kS7sZ3XDQ26suW5KCw+VIeqEEqdu6g5ZXMO2SipSOzP5jPjX+5ubX3SXcyoAIo41Efa6YGdWtl3,iv:oLk5tatZEY5AI/PlTBJHShGCKiyvve9rPhGARAtMMj4=,tag:Bkan2Hff8L8ZcC67r+fWjg==,type:str] hostapd-config: ENC[AES256_GCM,data:a0ESrrsquLq6VRJM588C5A+FmVxJwJSzwRuv2o//LL5OybcDS8jkVUajosXEs0qmQ6Xfc1gFDcevCYUwJ24eZ+ynKLWwoNx8RXXwbpllO7FkI68vcauUij1CtUgVb8aHheKfrFuyW7WU1wE3NTtOt2gij1+nM3iKS3vFXtX2n9L2fuy2b3EhOUBiakxAeQmyVmclSVBDYt12i4h4tW7GpPr8AjoIiZgz0Hyx5zA5f/JTPzz/P200eM0tCttNPbMNPBGztJfw7raRIX+v6xw7QNPMgf03TOae17mt6uggTNKJfEPeanzcEMA3xR6xoFUqJL6Hvowyl4MrSFc+E5Rvft+qhp8m6tAqQln9Z3MzaDtxSBWnWdvWEcyeK1aDBQ57/aIwo8kVs47Iblqbi5+jM/n4DoeQtqTM1kS7sZ3XDQ26suW5KCw+VIeqEEqdu6g5ZXMO2SipSOzP5jPjX+5ubX3SXcyoAIo41Efa6YGdWtl3,iv:oLk5tatZEY5AI/PlTBJHShGCKiyvve9rPhGARAtMMj4=,tag:Bkan2Hff8L8ZcC67r+fWjg==,type:str]
@ -7,8 +8,8 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2023-08-08T09:43:37Z" lastmodified: "2024-08-26T18:50:19Z"
mac: ENC[AES256_GCM,data:lxoKzGyPwdfeI5Dlmgx9K9SBhfRIaokvum+dJWABUoGtIMtrhp4K4ZRF1Rjja8oTi4w3b+s9aUBpxt8TLu9vJZFsUkhY2gqW5bX3Ub/3xMAR9YSG3LtijRSMuKkdVlAkdjB6Guz9aHNVBG3fTZ+SfTlyOQdImW6bK4tydbGHKgY=,iv:6kVR4zZfHnqhcOT3N2tClGST8h7FLjIseXDu2xS2DEY=,tag:rd/f7cHSoxLT3O7HluVWLA==,type:str] mac: ENC[AES256_GCM,data:k26ZEKuFtS0GLMqFIbY0QiVfHvmpxt3JgLvZIhEHcC3wQ80OhRNeyKocZhua1T5iSfhfvlckXYZl6tTZkCEh4fj3NmYMtQ9vwpoexdYWwx5ylPT3rpByfBbO+foHgQ3JXk6Kyt2R9ULjghMU3/lEcsG4AuGU1XMomsTzrdigXY8=,iv:ls3nIFIwTM//tSvee/aHj6Qv2nn/gZMKgGF+aQWNxeg=,tag:l58uHLpvPfIkbUn9gl+lzg==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:19Z" - created_at: "2024-01-22T00:20:19Z"
enc: |- enc: |-
@ -79,4 +80,4 @@ sops:
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 28677f2e3584b39f528a779caf445ebb39c882b7 fp: 28677f2e3584b39f528a779caf445ebb39c882b7
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.7.3 version: 3.8.1

View file

@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ lib, pkgs, ... }:
let
cfg = pkgs.callPackage ./common.nix { };
in
{
services.avahi = {
enable = true;
reflector = true;
allowInterfaces = lib.mapAttrsToList (name: _: "br-${name}") (lib.filterAttrs (_: { avahi, ... }: avahi) cfg.vlan);
};
}

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -26,32 +26,65 @@ let
cidr = v6; cidr = v6;
net = fst v6Split; net = fst v6Split;
suffix = snd v6Split; suffix = snd v6Split;
withoutLocalComponent = lib.substring 0 ((lib.stringLength net) - 1) net;
gateway = "${net}1"; gateway = "${net}1";
gatewayCidr = "${gateway}/${suffix}"; gatewayCidr = "${gateway}/${suffix}";
}; };
}; };
macToIpv6InterfaceIdentifier = mac:
let
macList = lib.splitString ":" mac;
macListIpv6 = lib.flatten [
(lib.toHexString (lib.bitXor (builtins.fromTOML "x = 0x${lib.elemAt macList 0}").x 2))
(lib.sublist 1 2 macList)
[ "ff" "fe" ]
(lib.sublist 3 3 macList)
];
interfaceIdentifierNoColons = lib.strings.toLower (lib.concatStrings macListIpv6);
interfaceIdentifier = lib.concatStrings [
(lib.substring 0 4 interfaceIdentifierNoColons)
":"
(lib.substring 4 4 interfaceIdentifierNoColons)
":"
(lib.substring 8 4 interfaceIdentifierNoColons)
":"
(lib.substring 12 4 interfaceIdentifierNoColons)
];
in
interfaceIdentifier;
in in
{ rec {
vlan = { vlan = {
lan = { lan = {
id = 10; id = 10;
subnet = mkSubnet "10.80.1.0/24" "fd00:80:1::/64"; subnet = mkSubnet "10.80.1.0/24" "2001:470:73b9:1::/64";
domain = "lan.shinonome-lab.de"; domain = "lan.shinonome-lab.de";
avahi = true;
}; };
management = { management = {
id = 20; id = 20;
subnet = mkSubnet "10.80.2.0/24" "fd00:80:2::/64"; subnet = mkSubnet "10.80.2.0/24" "2001:470:73b9:2::/64";
domain = "management.shinonome-lab.de"; domain = "management.shinonome-lab.de";
avahi = false;
}; };
guest = { guest = {
id = 30; id = 30;
subnet = mkSubnet "10.80.3.0/24" "fd00:80:3::/64"; subnet = mkSubnet "10.80.3.0/24" "2001:470:73b9:3::/64";
domain = "guest.shinonome-lab.de"; domain = "guest.shinonome-lab.de";
avahi = false;
}; };
iot = { iot = {
id = 40; id = 40;
subnet = mkSubnet "10.80.4.0/24" "fd00:80:4::/64"; subnet = mkSubnet "10.80.4.0/24" "2001:470:73b9:4::/64";
domain = "iot.shinonome-lab.de"; domain = "iot.shinonome-lab.de";
avahi = true;
};
printer = {
id = 41;
subnet = mkSubnet "10.80.5.0/24" "2001:470:73b9:5::/64";
domain = "printer.shinonome-lab.de";
avahi = true;
}; };
}; };
tc = { tc = {
@ -123,4 +156,15 @@ in
} }
]; ];
}; };
staticHosts = lib.mapAttrs
(_: options: options // {
address6 = "${vlan.${options.vlan}.subnet.v6.withoutLocalComponent}${macToIpv6InterfaceIdentifier options.hwaddr}";
})
{
fuuko = {
hwaddr = "18:c0:4d:d2:93:f0";
address4 = "10.80.1.98";
vlan = "lan";
};
};
} }

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -31,11 +31,14 @@ let
in in
{ {
imports = [ imports = [
./avahi.nix
./dnsmasq.nix ./dnsmasq.nix
./nft.nix ./nft.nix
./tc.nix ./tc.nix
]; ];
sbruder.wireguard.he.enable = true;
boot.kernel.sysctl = { boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true; "net.ipv4.conf.all.forwarding" = true;
"net.ipv6.conf.all.forwarding" = true; "net.ipv6.conf.all.forwarding" = true;
@ -106,6 +109,20 @@ in
# Only use RA # Only use RA
DHCPv6Client = false; DHCPv6Client = false;
UseDNS = "no"; UseDNS = "no";
UseGateway = false; # should not be used by default for routing (wg-he takes precendence)
};
routingPolicyRules = lib.singleton {
routingPolicyRuleConfig = {
Family = "ipv6";
FirewallMark = 31092; # 0x7974
Table = 31092; # 0x7974
};
};
routes = lib.singleton {
routeConfig = {
Gateway = "_ipv6ra";
Table = 31092; # 0x7974
};
}; };
}; };
physical-lan = { physical-lan = {
@ -128,6 +145,13 @@ in
name = "enp4s0"; name = "enp4s0";
bridge = [ "br-lan" ]; bridge = [ "br-lan" ];
}; };
# extended from common config
wg-he = {
address = lib.singleton "2001:470:73b9::1";
routes = lib.singleton {
routeConfig.Gateway = "::"; # on link
};
};
} }
]; ];
}; };

View file

@ -5,6 +5,11 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
cfg = pkgs.callPackage ./common.nix { }; cfg = pkgs.callPackage ./common.nix { };
bypassHe = [
"googlevideo.com"
"youtube.com"
];
in in
{ {
services.dnsmasq = { services.dnsmasq = {
@ -51,9 +56,23 @@ in
]) ])
cfg.vlan); cfg.vlan);
dhcp-host = lib.mapAttrsToList
(name: { hwaddr, address4, vlan, ... }: "${hwaddr},tag:br-${vlan},${address4},${name}")
cfg.staticHosts;
nftset = [
"/${lib.concatStringsSep "/" bypassHe}/6#ip6#he-bypass#addresses"
];
server = [ server = [
"127.0.0.1#5053" "127.0.0.1#5053"
]; ];
# Authoritative zones for external reachability (only AAAA records)
auth-server = "shinobu.shinonome-lab.de,2001:470:73b9::1";
auth-zone = map
(vlan: "${vlan.domain},${vlan.subnet.v6.cidr}")
(lib.attrValues cfg.vlan);
}; };
}; };
systemd.services.dnsmasq.after = [ "systemd-networkd.service" ]; systemd.services.dnsmasq.after = [ "systemd-networkd.service" ];

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -17,7 +17,12 @@ let
passthru = { passthru = {
VLANS = lib.attrNames cfg.vlan; VLANS = lib.attrNames cfg.vlan;
VLAN_BRIDGES = map (name: "br-${name}") (lib.attrNames cfg.vlan); VLAN_BRIDGES = map (name: "br-${name}") (lib.attrNames cfg.vlan);
}; } // (lib.listToAttrs (lib.flatten (lib.mapAttrsToList
(name: staticHostConfig:
(map
(option: option // { name = "STATIC_HOST_${name}_${option.name}"; })
(lib.attrsToList staticHostConfig)))
cfg.staticHosts)));
defines = lib.concatStringsSep defines = lib.concatStringsSep
"\n" "\n"

View file

@ -4,34 +4,90 @@
define NAT_LAN_IFACES = { "br-lan", "br-guest" } define NAT_LAN_IFACES = { "br-lan", "br-guest" }
define PHYSICAL_WAN = "enp1s0" define PHYSICAL_WAN = "enp1s0"
# only includes interfaces that use NAT
define NAT_WAN_IFACES = { $PHYSICAL_WAN } define NAT_WAN_IFACES = { $PHYSICAL_WAN }
# also includes interfaces that do not use NAT
define WAN_IFACES = { $NAT_WAN_IFACES, "wg-he" }
table inet filter { table inet filter {
chain forward { chain forward {
type filter hook forward priority filter; policy drop type filter hook forward priority filter; policy drop
# Use MSS clamping to avoid too large packets not going through the tunnel.
tcp flags syn / syn,rst tcp option maxseg size set rt mtu
# plastic router, might be vulnerable (FIXME v6 is still reachable) # plastic router, might be vulnerable (FIXME v6 is still reachable)
iifname "br-guest" ip daddr "192.168.0.1" drop iifname "br-guest" ip daddr "192.168.0.1" drop
# allow traffic between selected VLANs and wan # allow traffic between selected VLANs and wan
iifname $NAT_LAN_IFACES oifname $NAT_WAN_IFACES counter accept iifname $NAT_LAN_IFACES oifname $WAN_IFACES counter accept
iifname $NAT_WAN_IFACES oifname $NAT_LAN_IFACES ct state established,related counter accept iifname $WAN_IFACES oifname $NAT_LAN_IFACES ct state established,related counter accept
# allow lan clients to be publicly reachable
iifname "wg-he" oifname "br-lan" counter accept
# traffic from lan to all other vlans is allowed # traffic from lan to all other vlans is allowed
iifname "br-lan" oifname $VLAN_BRIDGES counter accept; iifname "br-lan" oifname $VLAN_BRIDGES counter accept;
iifname $VLAN_BRIDGES oifname "br-lan" ct state established,related counter accept iifname $VLAN_BRIDGES oifname "br-lan" ct state established,related counter accept
iifname $NAT_WAN_IFACES oifname "br-iot" ct state established,related counter accept iifname $WAN_IFACES oifname "br-iot" ct state established,related counter accept
iifname "br-printer" oifname "br-lan" ip daddr $STATIC_HOST_fuuko_address4 tcp dport { 21, 30000-30009 } counter accept
iifname "br-printer" oifname "br-lan" ip6 daddr $STATIC_HOST_fuuko_address6 tcp dport { 21, 30000-30009 } counter accept
} }
} }
table inet nat { table ip nat {
chain postrouting { chain postrouting {
type nat hook postrouting priority filter; policy accept type nat hook postrouting priority filter; policy accept
oifname $NAT_WAN_IFACES masquerade oifname $NAT_WAN_IFACES masquerade
} }
} }
# Bypass HE tunnel by setting a firewall mark.
# This acts in two places that are handled separatly by nftables:
# Packets from the local host (output hook) and forwared packets (prerouting hook).
# To simplify the handling,
# there is a single chain that handles both,
# which is jumped to from the specific chains.
# Additionally, masquerading is allowed for all packages with a destination of the dynamic set.
table ip6 he-bypass {
# Dynamically managed by dnsmasq (based on resolved addresses).
set addresses {
type ipv6_addr
comment "IPv6 addresses for which the HE tunnel should be bypassed by using NAT on wan instead"
}
# This must be of type route, otherwise no route lookup will be performed
chain output {
type route hook output priority mangle
jump common
}
# This does not need to be of type route
chain prerouting {
type filter hook prerouting priority mangle
jump common
}
chain common {
ip6 daddr @addresses mark set 0x7974 counter
}
chain postrouting {
type nat hook postrouting priority filter; policy accept
oifname $NAT_WAN_IFACES ip6 daddr @addresses masquerade
}
}
table ip6 public-access {
chain input {
type filter hook input priority filter; policy accept
iifname "wg-he" oifname "br-lan" counter accept
}
}
# Only allow select connections from and to (physical) wan, # Only allow select connections from and to (physical) wan,
# overriding NixOS firewall in some cases. # overriding NixOS firewall in some cases.
table inet restrict-wan { table inet restrict-wan {
@ -60,7 +116,7 @@ table inet restrict-wan {
} }
# Traffic control # Traffic control
# Neets output and prerouting to match packets from localhost and lan # Needs output and prerouting to match packets from localhost and lan
table inet tc { table inet tc {
chain output { chain output {
type route hook output priority mangle type route hook output priority mangle

View file

@ -9,7 +9,6 @@
./hardware-configuration.nix ./hardware-configuration.nix
../../modules ../../modules
./services/fuuko-proxy.nix # FIXME!
./services/media.nix ./services/media.nix
./services/murmur.nix ./services/murmur.nix
./services/restic.nix ./services/restic.nix
@ -17,7 +16,10 @@
sbruder = { sbruder = {
nginx.hardening.enable = true; nginx.hardening.enable = true;
restic.system.enable = true; restic = {
enable = true;
backups.system.enable = true;
};
wireguard.home.enable = true; wireguard.home.enable = true;
full = false; full = false;
infovhost.enable = true; infovhost.enable = true;

View file

@ -1,27 +0,0 @@
# SPDX-FileCopyrightText: 2022-2023 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ lib, ... }:
{
services.nginx.virtualHosts = builtins.listToAttrs (map
(fqdn: lib.nameValuePair fqdn {
enableACME = true;
forceSSL = true;
locations."/" = {
extraConfig = ''
proxy_pass http://fuuko.vpn.sbruder.de/;
proxy_set_header Host ${fqdn};
'';
proxyWebsockets = true;
};
})
[
"languagetool.sbruder.de"
"media.sbruder.de"
"photoprism.sbruder.de"
"torrent.sbruder.de"
]);
}

View file

@ -10,13 +10,15 @@
../../modules ../../modules
./services/static-sites.nix ./services/static-sites.nix
./services/li7y.nix
]; ];
sbruder = { sbruder = {
nginx.hardening.enable = true; nginx.hardening.enable = true;
full = false; full = false;
wireguard.home.enable = true; wireguard = {
he.enable = true;
home.enable = true;
};
infovhost.enable = true; infovhost.enable = true;
}; };

View file

@ -1,13 +1,13 @@
wg-he-private-key: ENC[AES256_GCM,data:aTH+AUBgG2D1CUF0zp1OzTUBu5Td2J2fsq3EpYEUuPGQFA+EbAYS+4AEipg=,iv:vNkqtoixZ+I+C5L4Vbck3EhCYGKzzIvwHIjiNs5PPIQ=,tag:6SMQ9oqKd7FdLvQNt2SAYA==,type:str]
wg-home-private-key: ENC[AES256_GCM,data:0ylkx9p62CBGqVg+T52eHbMwbLcZM/v3tg/wJukDq76heN1TtQqbbqgVZKc=,iv:/aUkqKhihnBWQFLIRjS7kHigBCBXX7L4KY5q+cO9Q00=,tag:jQSMVElMfIyrG5hs7HuxUQ==,type:str] wg-home-private-key: ENC[AES256_GCM,data:0ylkx9p62CBGqVg+T52eHbMwbLcZM/v3tg/wJukDq76heN1TtQqbbqgVZKc=,iv:/aUkqKhihnBWQFLIRjS7kHigBCBXX7L4KY5q+cO9Q00=,tag:jQSMVElMfIyrG5hs7HuxUQ==,type:str]
li7y-environment: ENC[AES256_GCM,data:cm4+672JelbYsBm0rwrF/I9gS72XfAlj335v0+EfXmPSD1LCBJ3clR7jZC7SVH5D9ZSaSlrY8J/+7hgDmzsiR2kypNBvfMvN825AF5QFehnYeHhxUktU+uig7RzpRUeWSPM0r8j6lmpGNc7vd3S+L3TWn2ZfCJ8Kc28Ad2M9yFiZ7PPqB6qqLnsx2peQuafDhefuohLPOYA=,iv:84yL6l7zqeb7l3w3ARskJoQEvI1+HxoCCKrLhB0kx7E=,tag:GCetAOW7pvyjKEM26A9ZbA==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-07-14T17:32:43Z" lastmodified: "2024-08-28T13:24:49Z"
mac: ENC[AES256_GCM,data:7D9xHNpdhI6CgX94PAoJJIJqVZ403ZL7dXbdnod2do4M+Qf0yRrRDxi6hPipf0BX0vsSq1npdiXcnwP50PZHal8LW7IJRjfefW5WnO+BLD42sIxt5mikdNfZhpyg3dHB7j+8m1lE1+veK/Ho06V32sckibhBG4AFBfMZ/k1VIns=,iv:NS9CaSyEUdmJEKFejiaugtZ5Nf8norhoaCaOwPZsxow=,tag:Y2Nu92iYO0PSqtXMLc3D7g==,type:str] mac: ENC[AES256_GCM,data:fKT7rZ1Vid/oo0GRaoTd07Fdq3XqhM8godEck+x0gee9DTdl+kbVJEXejNS1aeyx7WveudrUCTm1y5s0mvRoClyPSgkAXT+UvZ6L+8MxZeInKMT0c5bKNDzJVlzXdNLJ6oQ4Oa1dkhs6dElkkyevb2KT02PRmGYB8hQki3YqdJM=,iv:fZYIDSROMeYj/D6hjiS8vZP566X3m8wcPdMzA+OQyxw=,tag:KqNu8I3AloRvqMnJIQy+zg==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:20Z" - created_at: "2024-01-22T00:20:20Z"
enc: |- enc: |-

View file

@ -10,7 +10,7 @@
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."~ .*".return = "303 'https://iv.sbruder.xyz/watch?v=ojToYs6nCnk&t=1684'"; locations."~ .*".return = "303 'https://www.youtube.com/watch?v=ojToYs6nCnk&t=1684'";
}; };
"www.brennende.autos" = { "www.brennende.autos" = {
enableACME = true; enableACME = true;
@ -18,6 +18,10 @@
globalRedirect = "https://brennende.autos/"; globalRedirect = "https://brennende.autos/";
}; };
"share.sbruder.de".locations."= /".extraConfig = ''
autoindex off;
'';
}; };
sbruder.static-webserver.vhosts = { sbruder.static-webserver.vhosts = {
@ -45,10 +49,29 @@
"www.salespointframe.work" "www.salespointframe.work"
"verkaufspunktrahmenwerk.de" "verkaufspunktrahmenwerk.de"
"www.verkaufspunktrahmenwerk.de" "www.verkaufspunktrahmenwerk.de"
"verkaufspuntrahmenwerk.de"
"www.verkaufspuntrahmenwerk.de"
]; ];
user.name = "salespoint"; user.name = "salespoint";
}; };
"schulischer-schabernack.de" = {
redirects = [
"www.schulischer-schabernack.de"
"staging.schulischer-schabernack.de"
];
user.name = "schabernack";
}; };
"share.sbruder.de" = {
redirects = [ ];
user.name = "share";
};
};
services.nginx-interactive-index.virtualHosts = {
"share.sbruder.de".locations."/".enable = true;
};
sbruder.restic.backups.system.extraExcludes = [
config.sbruder.static-webserver.vhosts."share.sbruder.de".root
];
} }

View file

@ -52,6 +52,12 @@ in
deviceUri = "ipps://fuuko.lan.shinonome-lab.de:631/printers/etikettierviech"; deviceUri = "ipps://fuuko.lan.shinonome-lab.de:631/printers/etikettierviech";
description = "SII SLP 650"; description = "SII SLP 650";
} }
{
name = "bro";
model = "everywhere";
deviceUri = "ipps://bro.printer.shinonome-lab.de";
description = "brother DCP-L2660DW";
}
]; ];
}) })
]; ];

View file

@ -41,6 +41,7 @@
./gui.nix ./gui.nix
./infovhost.nix ./infovhost.nix
./initrd-ssh.nix ./initrd-ssh.nix
./local-mail.nix
./locales.nix ./locales.nix
./logitech.nix ./logitech.nix
./mailserver ./mailserver

32
modules/local-mail.nix Normal file
View file

@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, pkgs, ... }:
{
sops.secrets.system-mail.sopsFile = ../secrets/local-mail.yaml;
programs.msmtp = {
enable = true;
setSendmail = true;
accounts.default = {
host = "vueko.sbruder.de";
port = "465";
tls = "on";
tls_starttls = "off";
from = ''"system+%U@%H"@sbruder.de'';
allow_from_override = "off";
auth = "on";
user = "system@sbruder.de";
passwordeval = "cat ${config.sops.secrets.system-mail.path}";
aliases = pkgs.writeText "msmtp-aliases" ''
default: simon@sbruder.de
'';
};
};
boot.swraid.mdadmConf = ''
MAILFROM "mdadm on ${config.networking.hostName}" <"system+root@${config.networking.hostName}"@sbruder.de>
MAILADDR simon@sbruder.de
'';
}

View file

@ -69,6 +69,12 @@ in
"postmaster@example.com" "postmaster@example.com"
]; ];
}; };
localOnly = mkOption {
type = bool;
description = "Whether the user should only be able to send mails to local domains.";
default = false;
example = true;
};
}; };
}); });
description = "Users of the mail server"; description = "Users of the mail server";

View file

@ -42,6 +42,8 @@ lib.mkIf cfg.enable {
services.postfix = { services.postfix = {
enable = true; enable = true;
setSendmail = lib.mkForce false;
enableSubmission = true; # plain/STARTTLS (latter is forced in submissionOptions) enableSubmission = true; # plain/STARTTLS (latter is forced in submissionOptions)
enableSubmissions = true; # submission with implicit TLS (TCP/465) enableSubmissions = true; # submission with implicit TLS (TCP/465)
@ -54,6 +56,20 @@ lib.mkIf cfg.enable {
mapFiles = { mapFiles = {
inherit valiases; inherit valiases;
restricted_senders = pkgs.writeText "restricted_senders"
(lib.concatStringsSep
"\n"
(lib.flatten
(map
(user: (map (address: "${address} local_only") ([ user.address ] ++ user.aliases)))
(lib.filter (user: user.localOnly) cfg.users))));
local_domains = pkgs.writeText "local_domains"
(lib.concatMapStringsSep
"\n"
(domain: "${domain} OK")
cfg.domains);
}; };
config = { config = {
@ -86,6 +102,21 @@ lib.mkIf cfg.enable {
"reject_unknown_sender_domain" "reject_unknown_sender_domain"
]; ];
# cant be in submissionOptions (which does not support spaces in NixOS)
submission_sender_restrictions = listToString [
"reject_sender_login_mismatch"
"check_sender_access hash:/etc/postfix/restricted_senders"
];
smtpd_restriction_classes = listToString [
"local_only"
];
local_only = listToString [
"check_recipient_access hash:/etc/postfix/local_domains"
"reject"
];
# generated 2021-02-04, Mozilla Guideline v5.6, Postfix 3.5.6, OpenSSL 1.1.1i, intermediate configuration # generated 2021-02-04, Mozilla Guideline v5.6, Postfix 3.5.6, OpenSSL 1.1.1i, intermediate configuration
# https://ssl-config.mozilla.org/#server=postfix&version=3.5.6&config=intermediate&openssl=1.1.1i&guideline=5.6 # https://ssl-config.mozilla.org/#server=postfix&version=3.5.6&config=intermediate&openssl=1.1.1i&guideline=5.6
smtpd_tls_security_level = "may"; smtpd_tls_security_level = "may";
@ -125,9 +156,7 @@ lib.mkIf cfg.enable {
"reject" "reject"
]; ];
smtpd_sender_restrictions = listToString [ smtpd_sender_restrictions = "$submission_sender_restrictions";
"reject_sender_login_mismatch"
];
cleanup_service_name = "submission-header-cleanup"; cleanup_service_name = "submission-header-cleanup";
}; };

View file

@ -11,6 +11,14 @@ in
hardening.enable = lib.mkEnableOption "nginx hardening"; hardening.enable = lib.mkEnableOption "nginx hardening";
privacy.enable = (lib.mkEnableOption "nginx privacy options") // { default = true; }; privacy.enable = (lib.mkEnableOption "nginx privacy options") // { default = true; };
recommended.enable = (lib.mkEnableOption "recommended options") // { default = true; }; recommended.enable = (lib.mkEnableOption "recommended options") // { default = true; };
proxyv4 = {
enable = (lib.mkEnableOption "PROXY protocol for IPv4 connections");
trustedAddresses = (lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Trusted addresses which can override the source address";
default = [ "10.0.0.0/8" "127.0.0.0/8" "172.16.0.0/12" "192.168.0.0/16" ];
});
};
}; };
config = lib.mkMerge [ config = lib.mkMerge [
@ -27,9 +35,12 @@ in
''; '';
}) })
(lib.mkIf cfg.privacy.enable { (lib.mkIf cfg.privacy.enable {
services.nginx.commonHttpConfig = '' services.nginx = {
logError = "stderr crit"; # error (the default severity) logs potential PII (IP addresses) on 404 errors
commonHttpConfig = ''
access_log off; access_log off;
''; '';
};
}) })
(lib.mkIf cfg.recommended.enable { (lib.mkIf cfg.recommended.enable {
services.nginx = { services.nginx = {
@ -39,5 +50,22 @@ in
recommendedTlsSettings = lib.mkDefault true; recommendedTlsSettings = lib.mkDefault true;
}; };
}) })
(lib.mkIf cfg.proxyv4.enable {
services.nginx = {
commonHttpConfig = (lib.concatMapStrings
(address: ''
set_real_ip_from ${address};
'')
cfg.proxyv4.trustedAddresses) + ''
real_ip_header proxy_protocol;
'';
defaultListen = [
{ addr = "[::]"; port = 80; ssl = false; }
{ addr = "0.0.0.0"; port = 80; proxyProtocol = true; ssl = false; }
{ addr = "[::]"; port = 443; ssl = true; }
{ addr = "0.0.0.0"; port = 443; proxyProtocol = true; ssl = true; }
];
};
})
]; ];
} }

View file

@ -4,9 +4,9 @@
{ config, lib, ... }: { config, lib, ... }:
{ lib.mkIf (config.sbruder.wireguard.home.enable && !config.sbruder.machine.isVm) {
services.prometheus.exporters.smartctl = { services.prometheus.exporters.smartctl = {
enable = config.sbruder.wireguard.home.enable && !config.sbruder.machine.isVm; enable = true;
listenAddress = config.sbruder.wireguard.home.address; listenAddress = config.sbruder.wireguard.home.address;
# devices need to be specified for all systems that use NVMe # devices need to be specified for all systems that use NVMe
# https://github.com/NixOS/nixpkgs/issues/210041 # https://github.com/NixOS/nixpkgs/issues/210041

View file

@ -12,10 +12,6 @@ in
type = lib.types.attrsOf lib.types.str; type = lib.types.attrsOf lib.types.str;
description = "Known public keys that can be used in the configuration"; description = "Known public keys that can be used in the configuration";
default = { default = {
"simon@hitagi" = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC1kQUoPII8A9/bgPA+OrZGQLPA8MxkdmPSCCsfGMh9qRZfF7BSD8W6VdE/28tLw+39QeUl1+/9VuVvGjZBP1zBAbKIcKx4DjtgxpNXCsfWMjXFtpTGk2dyl71CaY5n72YlADxXYwtEvuwfNixgE2yTCefMbBsfwqYC0GZGiDlFtjxdg+RuUC8jU++C+WFUFct9gj9ieQ0LWjud+Oh0AF0JhyGnou+wVZIIO8mwo7Cc5xiPldXhbc13XiNC3mpNGCLFj+nh1feazk8TeAVDBps6xaDkOd+hDwTBQh8LoimePK7MiShzLvC38Vd/sim5ym/IqY634CjqBDGCMp1KXnqHUTT8CqeifMv10+aRJKUPevVkO3nEE3VoSPt7Ui9ZzLnL4qhZyygoBau+PvD2WCWm+gRwBkvU1uNrYKi4HIGhB/gXcYHKJimqJwLMyqG5Wv1jfuhn3ZZN+uNqTgdAznGgPRU1Q/Mx6nMEDiQip78qdYEc0YGwdb/TldEL6aHRjuNuZPpTW+zakQHiQTRb/0VdZT1bAwyT9yL0Uf40h706Kh/pKiSQ1yq1dlSdl3RlfedbqLqGjspds1iRSrSXyH2MBghPbz/SF7Vt4LW/tXF0rcyV7CU98ZvxJDWeN60OE0vPf/AT5udYyfPO1691y0F8jGKxGYYPg9R/Y5o7J24PbQ==";
"simon@mayushii" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJ7qUGZUjiDhQ6Se+aXr9DbgRTG2tx69owqVMkd2bna";
"simon@nunotaba" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILcOt4mAwIuAGMfRdfeoGX4UFkQDhkbihJcsAgG7JE/j";
# pgp key
"alpha" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE1KsR0pgwLfhbP/BDeyb7CLnIqbWiaS52QKUOYLtioH"; # Nitrokey 3 "alpha" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE1KsR0pgwLfhbP/BDeyb7CLnIqbWiaS52QKUOYLtioH"; # Nitrokey 3
"beta" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtp4pbIVjjXN7J277+pm5EyzIQVD5aHpoi45J1PNVCL"; # Nitrokey 3 "beta" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOtp4pbIVjjXN7J277+pm5EyzIQVD5aHpoi45J1PNVCL"; # Nitrokey 3
"backup" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfsufQIdFzWK1B1uelCzt8XJaoublRPn1gjZvumSEr+"; # Offline backup key "backup" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPfsufQIdFzWK1B1uelCzt8XJaoublRPn1gjZvumSEr+"; # Offline backup key
@ -25,9 +21,6 @@ in
type = lib.types.listOf lib.types.str; type = lib.types.listOf lib.types.str;
description = "Names of trusted public keys, used to generate <literal>sbruder.pubkeys.trustedKeys</literal>"; description = "Names of trusted public keys, used to generate <literal>sbruder.pubkeys.trustedKeys</literal>";
default = [ default = [
"simon@hitagi"
"simon@mayushii"
"simon@nunotaba"
"alpha" "alpha"
"beta" "beta"
"backup" "backup"

View file

@ -1,9 +1,139 @@
# SPDX-FileCopyrightText: 2020-2021 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
cfg = config.sbruder.restic;
sftpTarget = "u313368-sub4@u313368-sub4.your-storagebox.de";
sftpPort = 23;
repository = "sftp://${sftpTarget}:${toString sftpPort}/personal";
mkPruneConfig = { tag, timerConfig, opts }: {
inherit repository timerConfig;
passwordFile = config.sops.secrets.restic-password.path;
paths = [ ];
extraOptions = [
"-o"
"sftp.command='ssh -i ${config.sops.secrets.restic-ssh-key.path} -p ${toString sftpPort} ${sftpTarget} -s sftp'"
];
pruneOpts = [
"--compression auto"
"--tag ${tag}"
"--verbose"
] ++ opts;
};
in
{ {
imports = [ imports = [
./system.nix ./system.nix
./vm-image.nix
]; ];
options.sbruder.restic = {
enable = lib.mkEnableOption "restic";
authScript.enable = (lib.mkEnableOption "script to use restic as user without dealing with authentication") // {
default = cfg.enable && config.sbruder.gui.enable;
};
prune.enable = lib.mkEnableOption "pruning";
mirror.backblaze.enable = lib.mkEnableOption "mirroring to Backblaze B2";
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
sops.secrets = {
restic-password = { };
restic-repository = { };
};
}
(lib.mkIf cfg.authScript.enable {
environment.systemPackages = [
(pkgs.writeShellScriptBin "restic-auth" ''
${pkgs.restic}/bin/restic \
--password-command="pass data/backup/restic-nixos" \
--repo "${repository}" \
$@
'')
];
})
(lib.mkIf cfg.prune.enable {
sops.secrets.restic-ssh-key = {
sopsFile = ../../machines/${config.networking.hostName}/secrets.yaml;
};
services.restic.backups = {
system-prune = mkPruneConfig {
tag = "system";
timerConfig = {
OnCalendar = "*-1/2-07 03:00:00";
RandomizedDelaySec = "4h";
};
opts = [
"--keep-daily 7"
"--keep-monthly 12"
"--keep-weekly 5"
"--keep-yearly 10"
];
};
vm-image-prune = mkPruneConfig {
tag = "vm-image";
timerConfig = {
OnCalendar = "06:00";
RandomizedDelaySec = "1h";
};
opts = [
"--keep-last 1"
];
};
};
})
(lib.mkIf cfg.mirror.backblaze.enable {
sops.secrets = {
restic-ssh-key.sopsFile = ../../machines/${config.networking.hostName}/secrets.yaml;
restic-mirror-backblaze-env.sopsFile = ../../machines/${config.networking.hostName}/secrets.yaml;
};
systemd.services.restic-mirror-backblaze = {
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = {
ExecStart = "${pkgs.rclone}/bin/rclone --config /dev/null sync :sftp,user=u313368-sub4,host=u313368-sub4.your-storagebox.de,port=23,key_file=$CREDENTIALS_DIRECTORY/ssh-key: :b2:sbruder-restic";
EnvironmentFile = config.sops.secrets.restic-mirror-backblaze-env.path;
LoadCredential = "ssh-key:${config.sops.secrets.restic-ssh-key.path}";
DynamicUser = true;
CapabilityBoundingSet = null;
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "noaccess";
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
};
};
systemd.timers.restic-mirror-backblaze = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "00/6:00:00";
RandomizedDelaySec = "2h";
};
};
})
]);
} }

View file

@ -4,11 +4,8 @@
{ pkgs, config, lib, ... }: { pkgs, config, lib, ... }:
let let
cfg = config.sbruder.restic.system; cfg = config.sbruder.restic.backups.system;
sftpTarget = "u313368-sub4@u313368-sub4.your-storagebox.de";
sftpPort = 23;
repository = "sftp://${sftpTarget}:${toString sftpPort}/personal";
excludes = [ excludes = [
# Caches # Caches
"/home/*/Downloads/" "/home/*/Downloads/"
@ -37,14 +34,6 @@ let
] ++ cfg.extraExcludes; ] ++ cfg.extraExcludes;
excludesFile = pkgs.writeText "excludes.txt" (lib.concatStringsSep "\n" excludes); excludesFile = pkgs.writeText "excludes.txt" (lib.concatStringsSep "\n" excludes);
# script to use restic as user without dealing with authentication
authScript = pkgs.writeShellScriptBin "restic-auth" ''
${pkgs.restic}/bin/restic \
--password-command="pass data/backup/restic-nixos" \
--repo "${repository}" \
$@
'';
# HACK: NixOS nftables implementation runs nft -c inside the build sandbox, # HACK: NixOS nftables implementation runs nft -c inside the build sandbox,
# where the target hosts cgroups are not available, # where the target hosts cgroups are not available,
# and therefore fails. # and therefore fails.
@ -65,8 +54,8 @@ let
''; '';
in in
{ {
options.sbruder.restic.system = { options.sbruder.restic.backups.system = {
enable = lib.mkEnableOption "restic"; enable = lib.mkEnableOption "restic system backup";
timerConfig = lib.mkOption { timerConfig = lib.mkOption {
type = with lib.types; attrsOf str; type = with lib.types; attrsOf str;
default = { default = {
@ -87,20 +76,10 @@ in
type = lib.types.nullOr lib.types.int; type = lib.types.nullOr lib.types.int;
default = null; default = null;
}; };
qos = (lib.mkEnableOption "QoS marking (DSCP AF12) of outgoing packets") // { default = !(lib.isNull cfg.uploadLimit); }; qos = (lib.mkEnableOption "QoS marking (DSCP AF12) of outgoing packets") // { default = !(isNull cfg.uploadLimit); };
prune = lib.mkEnableOption "pruning";
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
sops.secrets = {
restic-password = { };
restic-repository = { };
} // lib.optionalAttrs cfg.prune {
restic-ssh-key = {
sopsFile = ../../machines/${config.networking.hostName}/secrets.yaml;
};
};
services.restic.backups.system = { services.restic.backups.system = {
inherit (cfg) timerConfig; inherit (cfg) timerConfig;
repositoryFile = config.sops.secrets.restic-repository.path; repositoryFile = config.sops.secrets.restic-repository.path;
@ -119,13 +98,14 @@ in
"--tag system" "--tag system"
"--verbose" "--verbose"
] ++ lib.optional (cfg.uploadLimit != null) "--limit-upload=${toString cfg.uploadLimit}"; ] ++ lib.optional (cfg.uploadLimit != null) "--limit-upload=${toString cfg.uploadLimit}";
} // (lib.optionalAttrs cfg.qos {
backupPrepareCommand = '' backupPrepareCommand = ''
${pkgs.nftables}/bin/nft -f ${qosRules} ${pkgs.nftables}/bin/nft -f ${qosRules}
''; '';
backupCleanupCommand = '' backupCleanupCommand = ''
${pkgs.nftables}/bin/nft delete table inet restic ${pkgs.nftables}/bin/nft delete table inet restic
''; '';
}; });
systemd.services."restic-backups-system".serviceConfig = { systemd.services."restic-backups-system".serviceConfig = {
"Nice" = 10; "Nice" = 10;
@ -133,32 +113,5 @@ in
"IOSchedulingPriority" = 7; "IOSchedulingPriority" = 7;
Slice = "restic.slice"; Slice = "restic.slice";
}; };
services.restic.backups.system-prune = lib.mkIf cfg.prune {
inherit repository;
passwordFile = config.sops.secrets.restic-password.path;
timerConfig = {
OnCalendar = "*-1/2-07 03:00:00";
RandomizedDelaySec = "4h";
};
paths = [ ];
extraOptions = [
"-o"
"sftp.command='ssh -i ${config.sops.secrets.restic-ssh-key.path} -p ${toString sftpPort} ${sftpTarget} -s sftp'"
];
pruneOpts = [
"--compression auto"
"--keep-daily 7"
"--keep-monthly 12"
"--keep-weekly 5"
"--keep-yearly 10"
"--tag system"
"--verbose"
] ++ lib.optional (cfg.uploadLimit != null) "--limit-upload=${toString cfg.uploadLimit}";
};
environment.systemPackages = [
authScript
];
}; };
} }

View file

@ -0,0 +1,84 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
cfg = config.sbruder.restic.backups.vm-image;
in
{
options.sbruder.restic.backups.vm-image = {
enable = lib.mkEnableOption "restic vm image backup";
timerConfig = lib.mkOption {
type = with lib.types; attrsOf str;
default = {
OnCalendar = "03:00";
RandomizedDelaySec = "3h";
};
};
lvm = {
vg = lib.mkOption {
type = lib.types.str;
default = "${config.networking.hostName}-vg";
};
lvs = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
};
};
};
config = lib.mkIf cfg.enable {
systemd.services = lib.listToAttrs (map
(lv: lib.nameValuePair "restic-backups-vm-image-${lv}" {
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
restartIfChanged = false;
path = with pkgs; [ lvm2 restic ];
script = ''
set -euo pipefail
LV_NAME=${lib.escapeShellArg lv}
FULL_LV_NAME=${lib.escapeShellArg cfg.lvm.vg}/"$LV_NAME"
SNAPSHOT_LV_NAME="restic-snapshot-$LV_NAME"
FULL_SNAPSHOT_LV_NAME=${lib.escapeShellArg cfg.lvm.vg}/"$SNAPSHOT_LV_NAME"
lvcreate --name "$SNAPSHOT_LV_NAME" --snapshot "$FULL_LV_NAME" --permission r --ignoreactivationskip
function cleanup {
lvchange --activate n "$FULL_SNAPSHOT_LV_NAME"
lvremove "$FULL_SNAPSHOT_LV_NAME"
}
trap cleanup EXIT INT TERM
restic backup \
--tag vm-image \
--host ${config.networking.hostName}-hypervisor \
--verbose \
--stdin \
--stdin-filename "$LV_NAME" \
< "/dev/$FULL_SNAPSHOT_LV_NAME"
'';
environment = {
RESTIC_CACHE_DIR = "/var/cache/restic-backups-system"; # hack: reuse system backups directory
RESTIC_REPOSITORY_FILE = config.sops.secrets.restic-repository.path;
RESTIC_PASSWORD_FILE = config.sops.secrets.restic-password.path;
};
serviceConfig = {
Type = "oneshot";
};
})
cfg.lvm.lvs);
systemd.timers = (lib.listToAttrs (map
(lv: lib.nameValuePair "restic-backups-vm-image-${lv}" {
wantedBy = [ "timers.target" ];
inherit (cfg) timerConfig;
})
cfg.lvm.lvs));
};
}

View file

@ -26,7 +26,6 @@
hostNames = [ "hitagi" "hitagi.lan.shinonome-lab.de" "hitagi.vpn.sbruder.de" ]; hostNames = [ "hitagi" "hitagi.lan.shinonome-lab.de" "hitagi.vpn.sbruder.de" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIg/622wS8SFlzS29TPW9li3pNdbdHNjlGb4XTyXR0QR"; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIg/622wS8SFlzS29TPW9li3pNdbdHNjlGb4XTyXR0QR";
}; };
# TODO: replace with vueko!
vueko = { vueko = {
hostNames = [ "vueko.sbruder.de" "vueko.vpn.sbruder.de" ]; hostNames = [ "vueko.sbruder.de" "vueko.vpn.sbruder.de" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG8lKcWxMBM52BiwZLNf/iRywiRIZyMV4jyoHnoOL/2a root@vueko"; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG8lKcWxMBM52BiwZLNf/iRywiRIZyMV4jyoHnoOL/2a root@vueko";
@ -89,11 +88,19 @@
}; };
koyomi = { koyomi = {
hostNames = [ "koyomi" "koyomi.sbruder.de" "koyomi.vpn.sbruder.de" ]; hostNames = [ "koyomi" "koyomi.sbruder.de" "koyomi.vpn.sbruder.de" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAZVoGK0JNltzqVWN9dejWMkedfzcipTv6iX52HTHaVz"; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP6KAN4FJoCLciJ14W9dSbfsObc8GLIP/dhG5kHiHm8B";
}; };
koyomi-initrd = { koyomi-initrd = {
hostNames = [ "[koyomi.sbruder.de]:2222" ]; hostNames = [ "[koyomi.sbruder.de]:2222" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINPQuXX9EJXcz7wkG/yDxrZVODaitAQ1lfGzedNrYKhI"; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGx8YpnM1pNBIbqkfYpUnSv8VZihBItHQpCrhZ8ixlK1";
};
ci-runner = {
hostNames = [ "ci-runner" "ci-runner.sbruder.de" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHerI7UteS/Hb0XnxFGrox0VD92DJ0qc3PvCvgPjjTDp";
};
hiroshi = {
hostNames = [ "hiroshi" "hiroshi.sbruder.de" "hiroshi.vpn.sbruder.de" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMpTtUcPbuoqflM55C50HG4oY6dHPMaaACaAQhGxkx8x";
}; };
}; };
} }

View file

@ -1,9 +1,10 @@
# SPDX-FileCopyrightText: 2020-2023 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ {
imports = [ imports = [
./he.nix
./home.nix ./home.nix
./support.nix ./support.nix
]; ];

120
modules/wireguard/he.nix Normal file
View file

@ -0,0 +1,120 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ lib, config, ... }:
let
serverHostName = "yuzuru";
serverPort = 51820;
peers = {
yuzuru = {
subnets = [ ];
publicKey = "mWm92aZybisoLtd11g4XqwUZvQGVxMfPW9/za3/1/0Y=";
};
shinobu = {
subnets = [ "2001:470:73b9::/56" ];
publicKey = "c8lnzMWFeTzQmXwNV0DlD2ROJqBcDL0F9WN5u4lVeFQ=";
};
};
cfg = config.sbruder.wireguard.he;
enableServer = config.networking.hostName == serverHostName;
in
{
options.sbruder.wireguard.he.enable = lib.mkEnableOption "WireGuard tunnel wg-he";
config = lib.mkIf cfg.enable {
sops.secrets.wg-he-private-key = {
owner = config.users.users.systemd-network.name;
sopsFile = ./../../machines + "/${config.networking.hostName}/secrets.yaml";
};
systemd.network = {
enable = true;
netdevs = {
wg-he = {
netdevConfig = {
Kind = "wireguard";
Name = "wg-he";
};
wireguardConfig = {
PrivateKeyFile = config.sops.secrets.wg-he-private-key.path;
} // (lib.optionalAttrs enableServer {
ListenPort = serverPort;
});
wireguardPeers =
if enableServer
then
map
({ publicKey, subnets }: {
wireguardPeerConfig = {
PublicKey = publicKey;
AllowedIPs = subnets;
};
})
(lib.attrValues
(lib.filterAttrs
(n: v: n != config.networking.hostName)
peers))
else
lib.singleton {
wireguardPeerConfig = {
PublicKey = peers."${serverHostName}".publicKey;
AllowedIPs = "::/0";
Endpoint = "85.215.73.203:${toString serverPort}";
PersistentKeepalive = 25;
};
};
};
} // (lib.optionalAttrs enableServer {
he = {
netdevConfig = {
Name = "he";
Kind = "sit";
MTUBytes = "1480";
};
tunnelConfig = {
Remote = "216.66.80.30"; # tserv1.fra1.he.net
Local = "85.215.73.203";
TTL = 255;
};
};
});
networks = {
wg-he = {
name = "wg-he";
networkConfig = lib.optionalAttrs enableServer {
IPForward = "ipv6";
};
routes = lib.singleton {
routeConfig.Destination = "2001:470:73b9::/48";
};
};
} // (lib.optionalAttrs enableServer {
he = {
name = "he";
address = lib.singleton "2001:470:1f0a:5db::2/64";
gateway = lib.singleton "2001:470:1f0a:5db::1";
routingPolicyRules = lib.singleton {
routingPolicyRuleConfig = {
From = "2001:470:73b9::/48";
Table = "0x73b9";
};
};
routes = lib.singleton {
routeConfig = {
Gateway = "2001:470:1f0a:5db::1";
Table = "0x73b9";
};
};
};
# FIXME interface name is hardcoded
eth0 = {
networkConfig.Tunnel = "he";
};
});
};
networking.firewall.allowedUDPPorts = lib.optional enableServer serverPort;
};
}

View file

@ -52,6 +52,10 @@ let
address = "10.80.0.17"; address = "10.80.0.17";
publicKey = "fvQDGqmkcFUvfUFmkSagJZy6pGIP6ewZrzTQfaz+mmE="; publicKey = "fvQDGqmkcFUvfUFmkSagJZy6pGIP6ewZrzTQfaz+mmE=";
}; };
hiroshi = {
address = "10.80.0.18";
publicKey = "eXbRmOcRRJpcgGb0Ztuw6t83K6QKtd+exWTbKCjmXQw=";
};
}; };
cfg = config.sbruder.wireguard.home; cfg = config.sbruder.wireguard.home;

View file

@ -24,10 +24,6 @@ SPDX-License-Identifier: CC-BY-SA-4.0
<td>Matrix</td> <td>Matrix</td>
<td><a id="matrix" href="#">(requires javascript)</a></td> <td><a id="matrix" href="#">(requires javascript)</a></td>
</tr> </tr>
<tr>
<td>Fediverse</td>
<td><a rel="me" href="https://procrastination.space/@simon">@simon@procrastination.space</a></td>
</tr>
<tr> <tr>
<td>Codeberg</td> <td>Codeberg</td>
<td><a href="https://codeberg.org/sbruder">sbruder</a></td> <td><a href="https://codeberg.org/sbruder">sbruder</a></td>

View file

@ -11,176 +11,208 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2023-12-28T16:12:09Z" lastmodified: "2024-08-28T20:20:46Z"
mac: ENC[AES256_GCM,data:f7gcMjAEMU6uOeS7x2zvtyu+7DvPOCbtBy+zStALFou6B2rMBuqzJC1CynFh1f+NAKGtv1P3sMdag5Es5xsRHjFqQ0FfWceAB2anTsqW3ZLu+ZKS02p03lR5Tz59GQgS1MHcNkEovY2qZ/Mk/BODJzKYjqmb7ItjXTcSAGII5vg=,iv:gZE0w3Ih5x8xJ0x7sU+ZWo289PIaBUn/y8y78QDqidQ=,tag:cxlGk81xQGifm3IyE5ypwg==,type:str] mac: ENC[AES256_GCM,data:i6AZEdSTH6Ig74wX6kdemIIzd2v0VbuKmhYRDEchVHg+4UmL/PoLwPCv9As4toFvHp0dWE2p9tarOirkbraoFKVB0MeDRdKE0WEBu5biY4ZPTufHPUKyQ5v2VkFkBhAmI/hYPgHXwfzKt3vTDBJtfcYUl9+GqITerF7JDTYXngk=,iv:nbR4eGBEK+YQKS8MmFuz4LWApaHs2YwxvJcQgDkpdE4=,tag:OF+tq5AlE4RtuMqwmRy4jg==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdAMljFciaKpt4CFhKyd3DBRdw7nXUOpoQ/uRaH42PokX0w hF4DLHeEFiC484ASAQdAFrkVwdgRZXKc/acSJVqXZfNJ9VaA/W7cYHSSC9aZ1w8w
9Tt/8CLlbAfEj/fxk3OiFIEj9TWONuiY4fXBZJEoAjqtSIB5u9T4TVxoZBDZsd+b k2edqP8gtuHPBYLrjFaaDz/d1dPy9dVymFFmp8AJ3Qo92y5on5xLEerPujYYb3cX
hF4Dub78fMESoMASAQdAWRtlHvulNRlIuDsR8uLExkyn/wIGUbJHe4eNimHEFAww hF4Dub78fMESoMASAQdAU63ToAm4bKdFQYWAShN32Gq2W1jmqebw0f0ZG/cpXm8w
u98tk0tKz6XaFWgvC4pX9l+/npq1MtFuPAAKtLXPI7gROYTU7zxglN/FUbcSPXys pocyMFI53mSA3WL2VmQcMKHRMyf1qitdZKx+3iJgyc6NApuez68nGXupg52/48j2
hF4DM6AcvgVUx2MSAQdAC9pkys4R9Jri5L+AkPTQdHt5mUHyrtpjHtPktbmHKkQw hF4DM6AcvgVUx2MSAQdAMZPou/8fugVQrouLi4kamJ4L7BXvqWedtnTXYA2Pb0ww
CpzcI3x8dX1OaMqp29YV8/mlXeJeuXtP87Ks9xQruy/YN6xFOdxrLvrdwcn1IQxr FDBRwh+XFSLr8IwuPtFs7lMnlfi31xrU/1Akn5FVdIADlD05SJZJJnKmUfchPkD4
1GgBCQIQiHKw9da5wP9XapqBAAbHox5FlswqhOMVxbuVxI4YwRYHr1U97dtzFtfF 1GgBCQIQwqjdcXmPuFI/ZoMJzcWBmvqu9gt8cgAmgMygUcerp28YygrD+gMVAlFi
1BEyc0xVnfNZyNMltMbNmcZ8gvKPSYl253OUmYy7m017EX68BlL2u/HzMPasFkoD Dwzj5Zxj16hG6fnLTw5BTV2yIUWZOxZ6RBOwOo7g7iDc0l3f4qdRMFQJpK6BW2KZ
Q0kti55h74LRWg== /qOTDJFVxLHmbw==
=/n9U =ox32
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763 fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdABgR3LZkCbks4CRb09YrM4Rg4RRN6aJNEztqmjuNzfUYw hF4Dub78fMESoMASAQdAf9qty6ZhueDUMAh05KtdT9N/VfADCWb7D7SSzfT3Wlsw
ontBlE2TFJqAvbRAruuJ+L49IRdNfN7j45xOKFVSIbvCabhnGSDVjNQW7gAkPgSX 49MzT0tApQAvEQUIxVWGmMrhT/8ohHtWSE4BGtFkq/9bNqz6tMv2O0x2a31JLrpP
hF4Dub78fMESoMASAQdA7G+16rWPMK63gf5KPWLUONlPBqhZjt1OQs2TgAnK3Wgw 1GgBCQIQR8LD7XKQndP2fJcvmlNeE/dQSc1h/EBB5iWLY9zgARKm1k8l4Jxyc5Z0
eFtvcgbxKnOsN9+YcXEFpWQNRNoOT4/xXOZsmUydaR9AJ611qjwGPBJIUeswUGeX oNuJoApjSnn8NTMGVDCFQY6mytMWpkkD3ZuUtXOVqzJwvV4OGCMFjrmvdunXrkNE
hF4DM6AcvgVUx2MSAQdA+NsqwKvRJ6KRfEYgiKUrVNUGDcyKspOm1PPWaTUdGgkw TL8kCaUFyl5+dQ==
Q1X3pIuncW1yfrPVGvA6Bapcizf3EmT7+8IaBke2ZmSXfgTxVB+WrcRKptmI42Cd =vvQW
1GgBCQIQIweZyiOg/AYuhQwH0PO1SnfHiHqgznYXNficCiGbm7u32ZIvd10N0ZB3
vWw6CV5seZDCnp+AUdS3DD53i2/NYZS84vD684m9LobozMaZRHQzjxvr3lijLBPQ
BkXNyBIMguXAEw==
=weHU
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0 fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdA4vQoDAcD9CBZH9yQ3E37IGqwTYiaAhwXLQcPwypxzkcw hF4DLHeEFiC484ASAQdA8RK1aKiXM7TqFY6gwVW1OeFLvgqq4WfN4dr/emzJ2UEw
GppP4rW7Ih8pyOkWzvl+5cLsLJncqw/Tsy5Bona/HJ4x7sgl9X4sbuH4azvOaSeT HnknNN/If/jSFezuGxpyY3qx6Vq1QYT8MgqZMDJiktZhTheQW6JJ5Pi3ab6q2YvU
hF4Dub78fMESoMASAQdAIZAaWNGxSR+oQAKY2ntJrMCEWHGAqtJNuamRZcW9YFIw 1GgBCQIQzs0l2zLP6BBWGJweq6EWyMBhhVs0jcIR7JXSTVXtWkpCfLDIJVaXf23z
gCP4QaN4V+Ti1vWUo1r3bIx0O96MOc0VgXc01OwWpSKDKFQttZdMQOCPvEejttpS jj7RruJvG2BXDoR3mpeJLbI/7L5liJUESDrarV5GCebOdsddEFqI6dVOwZbNDhTy
hF4DM6AcvgVUx2MSAQdAeYWfEPUS4HGGraIphr3x/l12nIKdv0US7mjhbUADskMw eut6YKbhRGVRtg==
d7cvfwHyh22keNrz3vENL1nC5E4kLA5qx8Gdqm/i+6caAGwUdfWCKvoFpBfrcS0R =ivM4
1GgBCQIQk7tCqIMBozy2OJeWC4HtWXFYljMZQqloa6vR3RGD71EL1RpcC4JFBBHu
tbaYzXnVKZj48HoIUAY/pXrJmKSrJYRD234mbmkEykMAvw+FD/yOtu3r4rWtpPaz
GX0CbVtAxiBXhw==
=1jzO
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 403215E0F99D2582C7055C512C77841620B8F380 fp: 403215E0F99D2582C7055C512C77841620B8F380
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA08nOrzNSYBrARAAh9rUz+6g8bJ2KxAwMQ4yxKuS6thjKQOo2mkszOSfAMNL hQIMA08nOrzNSYBrAQ/+Ji61Ouf7d5x6W5DGukElbFwu2P64q0EIWSF4xG/AV9iF
cpA/eX3r19u1DuU+/5CDJYK7rcmPQj0D8XPi5Ndvkqu/OE+uXGCzGL/PV9iY2eAi /7a8lMfVINUNa6tO+d0CZs6KdMoQZtIfsqCWDJfMzip5jlKz1MYRF9zSBwlPrfxT
/x9sM95LWIVVeJY7UZ9B0CNuJeNUI9xtj+U1e5ZZPFPhLAA2NgOODjeK02l11zQp nj5ZwgyigZd/x0ZK19ubYJ2HqhyH+TYfWdxSOHb+eS23TIArCnyvzY9LFi8shfWM
iD5Y0FywgQn6DkcdOQTzgzVSCFIt92C46fK6IWrwT0mJTffOqbS7vCDBMHIMaixB diTAKxUkPoqbQQyqc7jh/gWbbpqdu2nxEQuxxLp/8Bc/o0CPYozaeOHWhOf5btwq
0SaS4EqArKs7sqojMNCywzrRkrV+5AxqzuKEEppqWKg41kPL6tGtqXgS/vQY8/30 EPZQUySd+7KI28OPWBQKoZGIoPKQcH4qJex9awAVsTdxcuRj3d/MS3KnNKPf9ksA
y70G/rj1H7Mz0ncutUIChvLuqJDnmEt0Y1N0OjvGV10j70OxDHrHKtgguyUymPw4 zUJHNYT/8PYojwEhUCBQ1m9RnaNZ0qHy9CnY2CdoB+l301KULVJXaIw24s+fvq6W
HcDEZaBqt59wCuSvnlnurZD/sz5s4/3fOfKBGTvUvQ2hZzDw+DYD+N/tKP7GJ3WW 0oCIEwzr2wwYXkzm7Uh2S9QIiyf+ZpdEe+uBSGtHef0T/BRbbvRz8Ucp7U/njTCU
YiizRMQQDg+oq86fTKTqIILi2qNw9+enllF3nEUJJW5S9CKY0s1JSXfgoyOCig8X OYGVQsVKrdpF34vXXmnez+NCw/W17loOKUGAnuO7ZuZaKLXFFsd4fObSYU5vakmR
mqeHhVHv6H7glgPAg9RWshfdIttUXvi4uIBqoXfjP5y2NqMOUMTEg0vaqXOJ2SHD 9czrnIpskrh22TQ+154eJxkf4AfvvRzzPcvDSTcg0IMJED/9IWlqR0ddsuLSWBY+
Jhp1DMZcDK3sApBLJVM8fyf7ftNKs9vDG6Tdwo4muq0rI8CxIfS1rgTGzuEhQHzP UmX58K4kldslSi/2CktgHamAFhN75BZeQyQlksTeMgNEKS+X0pAXmv0a8T002mQf
K22LubjkkDUJYabznxophUl5CqKRzG0L4hf3Wm8VW/1XHakok2j6tEmpP3AJU4nS ugxz+6zqnF4eKypzcJ9zMWLYUfziHKmHfVlUPUC0BXaF4BJTBoETTpLAVasY1pXS
WAEE3/FidXEsO0qZ11nOZmTX9L3cw1PCLysfXo8uDGuMkGjMnVQaeKz7grL6+rRc WAELRfPtQcEQTKCuOV9Ucz23Omu8sAjnhtMyoZPTYZgBirEz4dURCoW3Ye5jShK9
4Tep3y2H2ihytXN192TeXiluNveUaxm+a3dnfy3eAjE+5O+mYqI53SQ= btpq7IIMvr6Rufnp4TsW1BI0//mX7ShIU+tz/k8a2OHpDph8FpFTx8Y=
=eDdF =j80V
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 3176be14f468c6d43ab2206b4f273abccd49806b fp: 3176be14f468c6d43ab2206b4f273abccd49806b
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA2UzePEMpuAKARAAhDlEsUQwEIqOQXugazUyOG2IYCasj90QNEdySEO/irWz hQIMA2UzePEMpuAKAQ//V29gGjU/84DIU4tRlTpk6vGJhNK5AsnqcP0oGMXSZbly
m16IVEZTmEgOWjBWsFonTKTkK11Yeg0hObB/33YVu5BiFQX5sAbmjXv+J/JShbqf oTRNxEro2WlN/B1Wb1Gzy/9Jj2URNYft69GgLec5p1JwE9V0OFA74xSsCjAQtPzg
ytVSEisQ0iEDDRz4+z9iux9YxUE2yzeDqRIfe60W+rbZlZySS7je/WSM4jZKUZMO ZzZiuyC56BQxYWdcvaJf4qvMWMmphB0VDMDaFVoPLMJZ9ss0x/yjHwgbWtORGLMy
pBlhOcBTkZo5V8igZ0LirCLMv0j8eE3yN5HJB8bu8vkUVqM23GPUKE6dAu5ExM5v 8fvOmksRJpYaKhtqfdfF6ZQFAfIJv/F0tnjrqQhZ5IjbwHI+YHQl15aMTYulA+W1
XuEEPnQ4SPJXLN/eaMU9wDBVB7E84ht0ZqWD6vyvdj6oH2gs9ysPw1ylRQiOxFdB LWKruVBb64BffXkmi8ZinqdmNzCDI3UMDXFpT4TuVGlQ4kSJgjrmOZc30WypuHJf
XiS0KLNXS2V6VWxwEVqu/ny8Ua5794n3cS4PVRyMbDF3QhpBzxdhEYgdZNCfLYmM tffmWhV8002rwZCloeY1bKlB5ENpPs4f0ydfymwXNvIG0GraATQcohtnx2e7WXc3
t0axMyZlj7TeXmz4Dpel0Bs1xDl55vX3bdI8v38yaeEz2Pdrd7QispdLPJvFVREk DqVEGExZNvTK/0d3zTZVRuC2/0+ZcBpHJpiFJOiLqkNL7w8JsQ8r0gY+PZagROtM
gTiG7rhAK86UHBAIM2CFWyibAbBMwVKBx89+0SeEJqHfobwoKMF4yHFJxR1QxuI1 YbnOQ0YBWtyYzXh5dO6gDKGySU7b+5KGpr9U6NN6owdz0QcABQJBRficFKAhOQio
Lcm0/du5HKzcrffB6BFL/W4D5fmfKn0H3hRZcJDPw+Qi/vgFWWebu01WpRCDziuK GZjq5ODE7pwlwcYKnCvLjfCx4mC5UY2B0U7RmyPhc+G6ql9jLgzTDYMhl3KIABMo
BrMpkWbVG2feBlhhhcxK8wyqd9kbmI3aAH+f8UIZVNQz2a4MO2N1/G8jXV6/lnQO FvrZFIT9ukQ1otHSpApjoyeUdS9Sr7vLBcMg2GHrx2pfH2DIevVgUu3mgpACEEPJ
wOnd9bSMnf2bUqssZZVL8K1PZ66Jw2HkR88I9WU77lT5+VCeHX9bnihs5phG4tPS R1WTUr9hmqXNXaCP7F57p3hpOqGK6FTW0gEDHjSBP4sa8an2Z6ebWxaNzK2B12/S
WAEGCGLfFlz37pfOMMMciBv/le27EdS8JAoUjWx8wApp20ipiD1aTjc2iAHM7pyG WAHl5x28cT++faH6+u+I1DYsLPGTfKaKxHsYWU/AcBoGepJw+yvhb0p2tigdQSjT
i3YgMqba0kiaDlO5enlOC0X4DwwAYBJnskaAx1re6NVSNZTsJ0OMqZo= SILbzn/q59RqCoMFxH6zTQPfLzPpd6AkzmMhBbzGZOvOzP1mQQVQE9g=
=7zkU =diMc
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 17FEEBB45E4245330507C960653378F10CA6E00A fp: 17FEEBB45E4245330507C960653378F10CA6E00A
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA5TfpJU9hyneAQ//VzV9YJKjmTVkRs0ulaSG0uAg6WDrD39jK8ZDYlASvIPE hQIMA5TfpJU9hyneAQ/9FMDmgyZf3aCD5QPZTrwrz6TOmDOyndvMUCg5qQba8XGO
ik8pT8Te5wEK6sUlQRtKrqVZeySuFhSNT1M1nDLgaSE4uqN8kii8tORAHsi1rI1P ryLb35S9gmlwo9u/dZaAXL0TcWKA+AKOJpRa5jiH5O+8iFLNpgv3A0AO2m9xdVeO
rStaKiXf9dQXr33CP4W5+Lmkmkp1j+GwAVlRCyR0olsnTwBIchT6MFponSiwOT38 QvE9MzQVd0u9MOtReZ0u0sE/HnurRkYgpksFT435Fg3qSZ1cY+JjzQujheQ6jj1a
KkCaLwdrKiLrY+gA2gme0wtLig00k+07WcVB0NXljM0yV13lXoy+iblkkUUi9FVQ agaA09qz66RCHLZ4pZL9tu382B+hZYL+KoOyNqR0pKc2ecKEAe+OUS1kxqGb2Gs8
njJqtW/kclRiJP/hhF0O89nMxx6hl/bzBwPrVAKAqvRTGG+BO5WujvwW4quKDxu6 twFFibwyvFs80UygqOpPxOobyaU4AeZguEApv+TOA7EmHCzcNnKB1RHWCKfup7Zh
Z96jmFnZNg01SEo6LVAcVIMJjwpmBvQEmnSuZNsZ4ZTO1AvQ9Z6y3l99fWO8yUi1 dA+55Cq5yDGXDyeRsSQOeQcff99aYyZG+j5WafNv0IPiPFNlS/R+ak2xqp+oxzPI
489pGyWF/f9LpyRwC65Y2YQxPyziWOFgFliJvnnMAeZp8xuTfyZ8wJwm4hzy8N0O KoNn/DD4FL8V5neH53nYj49x6OlG90Dv6hK/AcULl8pTxq6Hu0Vditgn/OlzT5rE
bJJVzyDhMu0Ry4Y5PaS3XecO5iKbO47XiHcIa5FhhoISVpxWKVJygtHqawEfXLdb BQKRxZ+XBFU4GLgjiQIXahJ8voDH/Kyxb1VAZsoRrKNYK3VUjC4ODKI5LJAJGxfZ
VjWAQUlOBR6JTyCu7vyf2bfmeP00X+kBDb0B1dfOlBW/RUOjxTlnNqgbwK0vaKQl CNUfyiynQ1HLQ7UUnKOzEEtxeZd6DuZYadsCvrdNuDPd+TVXR7XJLQPiM0Lp+ceQ
QZPkc40j/y6y6e5qKCd3pWskGITuMtkIEMT9UPlfGHRIQ1fuOR/nXr0p3eGv3b3Y 8RcqX48CfKNun950h9z+6b/1poZqtwYIzb3qsgUExt6dDGNxAHdvYhFLQfC4fysq
m99RuRinPMstjDtXrwl2W2LPN8t7nAWv53QPWbCp6zt7lqoN2fC8ShDxt6pM8FzS MrYSqalJsVsxFKmG7uDqtG0YI7r4vntSiiE1CCd1I8uamj++Yo9JAJgn1FyJic3S
WAHxnCxBcoLAxh5OrsFJZ3LJp4kDdPBWRajeGXQq+/sFE6h7n859kDBoZOAABK1K WAGinFjUm6ohbVtppNBkUcS5XJish6MU2Hh1UsK2RGDarsuendzBOHZKfGN2uZAU
sAnZwSo42z3xrmX8qH7JUaqpqBunxyZ3jH9Y5PMSNHJjGbpMdq5zk0w= S2pVRt39ruehNyPRZG4UFCGPvyUWFsDvmr1J7WlAGDASEwZ2IlvD0Qw=
=YADR =B1nw
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 4EA330328CD0D3076E90960194DFA4953D8729DE fp: 4EA330328CD0D3076E90960194DFA4953D8729DE
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA2nIGHycQ3VOAQ//Wp7cLK/tIURzeZdXS3coC2nrQJxuCXwo7zlnGUNk1LIw hQIMA2nIGHycQ3VOAQ/+L/J90b8NLLqDnznK/LGApKSc/xi2kS55yZW08pPvoe3E
e38xMEh+zttCGdRi69ePQ9XaostRxhplytX6aSP1/ZQTEiQHL44h/UN8OZVp3v6l Thk9aLZOE6hvdu+rQxWfGhHRDyyvCh4AFGVCJ1NwnT9RM0UBJYfeI5ERNiInIjud
ripIGPFpRIlEIxsRGyfucAXOl283Qav1NhnKWTovivyEG17zLs02FwjJKJzdJwjp 9E/HAWpGBgtm2wRYbMX3zqIT0H/8UyyFkczyHvSCIvmgf2yH7KCgpzXoX87Qcqvj
rPufEL18fM3UXahQwm0MXF4xvBjnQAyH0Vic3x0RJSejAoA+396vUu/GERTB98Ls 9+v+fiPjij43rTSD7VtA6zEXwQLyJsTFgmsK9iIySnKGuxxfanyuzi6oklUC8eIZ
MYX5FvMrS/FGXmhcXC6vJtdXblgDqJbioffmFjJZsyyOhDMCM69sTzxCL4PoKNzX iHKKeJsKuFvyb8FI6GrUYgC3MsxhkpQ6MYSIP2V3RBZdg2jnQpRm7HH7K1KKaFvU
nChtRPlNjEzZluf7hoEep/5TPh+OCpZ9XK2YmwK/EuO2Gg1pW+2I7rk1HBmcppoz 2rsQ6eoBNnBsm0yQ2SotL+UXDKL845tALqYHjfM7WaopP6g/iOylDevotV/jGVaQ
JKoDnWAAVBjGyE4a/rgehT4oQON57nk0G3HiYe/5oky5U8L3lErXM/BlP/QODOwT 5VD9KWE4RwUZjUTIgkQJew8hXLR+tMPNmw6SpRVtiAK4tF8mxydxjLsXYTz4KSTb
tT+NM/tgv5ojlGvbI/t7fje/vg6qLWa7X6kSoPrh1T2tWuTDku4b+4glu94GMbt3 MkytYzyhi29vMJWB0Qv/ewWVODfvTdqSaaCzfKFW9W4SHziYKRrPF7ekR7CV8sLG
uHa/Barz8FVmteTM9zfgGkM68pjodUCvzge4X2SKzQWiFb3brFlc8Bu5XEttHUMd Cj7v1GHsLdHgxO7ccD8yFNp1TEu/AlsQk+ziDoPJOaWZXthuG3brwX/jvAtFH7D3
2qESrXFuGmpWUTHQKF2aaVXzyyFIBMtEdO/yzJBGY/ocIg3ays0ChzfYTBH2VVJE DYWdhkOcxY7JtbcMRTznB7Uz6D5WQuF470xKpC19W7MOD/zPoreP8Y4GCBbQSLxC
ZbNv8GZruRmoiyc+VYqijRaLXUCMy1KCGnFtA5/viQZWsKt2HoqG9jzh4MHlNHXS IZSih0Xpess8LVkEHwttu432aqyRBvI0eFh2zh7/mn0gziG7NX7wfU5W+GDAtM7S
WAGDaq3FYcHgTVsmttY0OWp9EPtj0usE8K3cKlBPns26UpewSF+SOp5A8dwyAuye WAGXrqS3P1+igMKFI/ENp1IDkYVzcPjNrCFw1cMdpiWTq0AU0z5tPjJNJCLHue/s
8ARgsS5OoZOGjKLHVsnkPK0eFA2qgp/CNIkgc+An8ydVn3nlUAzb/Wk= LUy/H/1LMrpy2ce53LMfcoFkIQpPLN5j4wL8FPVQcb8g1pZ0GaYNeJ0=
=1i1T =1E6h
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 2372651C56E22972C2D9F3F569C8187C9C43754E fp: 2372651C56E22972C2D9F3F569C8187C9C43754E
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMA0Sjf6jBUFOzAQ//biw2LHUfJhz8Ro7Fx/8avssEZUsCO0rL0+GI0w8uOPMV hQIMA0Sjf6jBUFOzAQ/8CGe3bEUUuvCGPnEZxCQGFHh5EJcNBfh73/bFx0ag3IEu
BwKRC9g6tbk181vsg4FyZ3k7uoYI8oCfjIvt0lsFCIcQWO5/KKpoSXCtJhfK/ECI uhGjtWXCoOWr5H3pEMlqVT/aLGiEoYkJQfMLd2famHhoeggMfyHFv8bZRHu/jJ+Z
4Dw/P0P8F9If2zpm32PLI6Mzf0zhNJq+nXo94WTwDypH9gY9WmhTPSMRCbMaGBf9 /35mlGoJ5YZjAl0WEj9+9DrLNn+VHSuNNxiH377eutJBuygQE8N2EDJeciHuuVxP
7+YzfJ+gfPHcKdJe8ojoGU4MQy8l8hJrvM1pmcslZCMH1Ft2mlHhsVJj7KfAmhM1 d7zhX9U4AuybWw+sqwPC5qah1s/2Ceuu0BVXLHpDS1/O5gnOOqVctbWlTcdrGuDV
I86uFMIMyi3nDcdzZ+mRO8lSfZzNt3ex3gMiFq80fLkTyxniAJd9nODNf6OZC0R8 R+yBqClkQ9KLDk3fzYg0ulrmjDJqHI/QXt43ImAZSEsrreg2OA7CZA8Z1OMYHNNV
syQHoykTBsuwut2M8MsSelZvq66GxSCzbGDjqbc9r9toL12UOPEzrG/eBFrqCJ2U +71xE6PzkjZReR/J2Dje03SQR6rakEZcBkbhANUhOVL9JBjBGCloEDD2dWK7kFNd
aqir8lSSn+IP76cdZ6aDfOufk9dEfPD8Lycq2SpysMl/vhv7yFdavNsl5/2kFYYE AcYoauKWI/7DsIWTbL2F+Yc5p7rf6SlzMlJW2Dfk4hfoFjiDdcYu51pMAVTMt+cY
7IUkF+fZ7u7MVUjmEV3/nlMwyx0HjrDKmvm5+yIBxasyxnP6RAd+1caoWJYne+Pr eGC2gPyKzo+axY2+EQnwuiGjsBNTz6NyWG+rfpGtZ4/HrnRjLFnqGGExCDau+IlW
J8eGiUVhcmTsKXccUQQ8V+xHZ2sk27UJF2l8LVRsLxqCkFaKPIeilyzKU2Zj60Gu jYy83DcgInFHLw9TmaA/0t9vW6kBKEwEuYiJhSexUGUNLEjLwCREQfTTuC29Fghp
5YNCmg35bk7E9BfkSI/3Xt2XWBIvQHPQkFNYSfmTho+XbWX8hMKvfrFriQsx7lPZ 5neMS8fJMribQup1FUnfIYRZs+7EfGiS1FiVzzY7OGRXMxEaYL+13lVqPzpcSV9w
46tSzHEmz0QJOs6c8Y8YsxJL4/+FFZ9zu9P+yEmGA6++bylvX6Ye1BtMEoZJi4vS ZNC1II5XBtxWsHqpyEX2XTmYPrdu9yNcz1QBa++ypSG0qBq5kD4oFOc21WalbA/S
WAE5RDZQEMiM54w08W3FbJf1P1x2M8ZczFqhogVZLiTqSNsG9GNf9wEZQ2QW+L3/ WAHT98W5dKddbNXXCHoRZDXZLmei+XRdOOqMwzyjyTODkehRm2On3Xamy+gh3wGx
nH8vdUK+fgudPKFVj6BY3v6XPAMQEBdGUD8B+ATmapwDBSjcUv0oM74= RftfMyiicVdGKrHb9o/B9sTPpDzGF1Up5MFp/mjovWe/6EIMlzCG/xA=
=dQ6C =38lj
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 23EEDF49AAF1B41DCD1CD10F44A37FA8C15053B3 fp: 23EEDF49AAF1B41DCD1CD10F44A37FA8C15053B3
- created_at: "2024-01-22T00:20:22Z" - created_at: "2024-08-20T22:32:59Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
hQIMAyhQdcrIW3A1AQ/+NirEhJAwoH1vP2tbTj+j0uR0tTBUISBKJ4f765FTFAV/ hQIMAyhQdcrIW3A1AQ//dsIcQ/e2+8IxUiJFeb1vuCcVV3Y1WV8aPBAapTuIbHLc
jL1GPDGUVjRCadDlaqjCLuAYQVwU9bnmk7WkUVQiXiZsk/Ct1EX/Feuxhmd05Kj+ NSWwpR/s34qzxnatgL4dNG113OU+N+YCUHb7/8fMCOtfBTcvqzplOQlCZQ25YMhg
Z+cgJf+Rs/jYO7znTjuLBOI+FHd6qum0Olwo3qUgn7r1ey7+3CzeBTOYVdcnIp17 6mLwOrQFrFsfB7X2ppnxn4c3bNHCXWUl8Gxk+o+kDQwEZvswh7nO+DOxsE9592NQ
FgMGV1aIvAOo6hL0KlwwsutlvQKNf0BwbGDu1EjGRXwUMQc3yX0Ih+RgqEDuq69c 6gbxGoBEN3REIdJF1Q/6hh44qz9pYwDfONIXL0DykKG7BZtanREZKwdTqKJu9BfM
hoHLFGxrmk38VnLrHqbjamrNrooz1TApon8FlLdHPAt1VvrAdlKG7Cz8jiE3kN65 3MY4q9tmYbYEV00O81IJrRKHVk0ftRkh6+70hREriEzKAk1pVg93uAJ8eq/+uBkD
HMJtJc0kwdW+U5g3bjOZyQxZv6NuylyWwKB6q9WdL3lp4Rhn2BOLjtczNPboTH2k sltIaHjV9a2sUKtQrZAUUy5rHjLEZSfXpN3wZf/Kmd3eh3m0PsZTYrsPrClWXCfq
3uU14BvJpek8pBxkfroVeAmOcYhPfdcN+Vslx2lsUvLQtxGkTRrkoonPd2i9sAiP gB06/NaW9PTqQVKeQ/Dz1bHy+SSlEuuL7SqxrLQNAdm8334Ca5nwwMjQcoQHvJ6l
4qihCT+JeGJCVEB1UP5VFjeWchxGlSMhhsqWD11qip7ImzV//M/y4shzekNfJ2OJ TYT18OhbI8YzTS+0q3YcmaQhzACaRgbjSD2DH/wdpDwpovymxsbYjSGyoEnBorL7
WsvO9LtkW4VuvKlR4YmEZxRqxbWh5S//0TECWI/TgZLuM247vRac1jCe9thDGNmk 8ALaK4qGDSvpAXtR89l7lv5EcUTkiup6KtEA0X/pC0sZtzE1LlRInaT6+7n1w128
+4L1Th62VXZPuQPGOphRnKP4Bw+CuHyWOpmxxXbO2rliWGVvo7eUbrbhDfJ0j+D2 pG6lPkb3HWlKD4tye1LPSzA9qaE20eyhBsoNv+EGfv6xznB8km8pKc0is7oT/+xf
lUDBCN9vtmFqmMm9nCsgOPR/g7IC20clLEsG9K/kaNL8L4dZGLpUxCugU+UECm/S dueJQvNz+YAj63ftYjbH/OVnXaa9nl0DSJLGwGfVRvKVN8+uhVaD5Nd+WR/pPBHS
WAE1JZa2e7yYhg7LOoFR9+fdfB5okaeolTWO5zpydAYlKGyoiaOrITEYxaSJbnmy WAEmg6IG/3ImzWLCmySM0wENlTXsCJY5c1lHnONH+co2VoLgMiwzwyj/3XhqYcL6
1kvDDid0CnrZ3pT2lhyufv6/v486fMHHQT4+B+kQYinbq1VRilwoxzc= MCZRiDYDWOp5klV53y6cBtsZBbpw7Hj8a6h0Js0KtklMfJGwhhijXbA=
=uzUS =G8hj
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 06a917fc4a2a1b6b0f69a830285075cac85b7035 fp: 06a917fc4a2a1b6b0f69a830285075cac85b7035
- created_at: "2024-08-20T22:32:59Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA3FYa3pMDBplARAAgnTuOJJxv31KsodTrpBY6j2HJmLs0bIEYjsLeyZlNWKO
4oBVFJEhHdOddgYizaGi0NkJBpH+eN5khT9njslyB+p2cAvNCpKCEp/vpbvbWhsL
fNSA/2zP2+dZBI9VPxGSW8YABlJv5abs3GFTXHGg0zcgtPGkjjNyP8+WfaOOb6kP
1OLGokKe/ALN87l/27J3spNSwR1C8wvqZ/0elvhQQhhQtBpG3BT/vnxEKZPHIh7Z
1BIP30tYRpvSGADfq3p9DxsurBgdNQK9aIq6YnKoWq1gLnOKfe00mxV1L91zKSLE
sRno13k+2Oj5uDpS1H+WtnAN7Rj9AfFw149NAubJuwovWlCOe+/3/1WgVt3y72mn
Xgo2K3e5SSIjTkgzzVsGAPqOVlznvoVECBHzSUjPHaXGxybNCHd3WYQgTqLtFwUZ
tbbiexvSfTg9Wud8Y1CnMsYGYnkcreu77Kc52aj49t+y0DXuL7/oOzs+MkN+u81c
sLs/DqzUueP4/d90V5QeQXzuQqOlB3NWLH+KMNK2O/moZlGGFA3Bi+gAZoGGHclC
Uy9BBY5COGON+VX0iT5xKt1v7Jgq6vI81Gi6bkEUZ1OMW9Hz7mErxYnKiYutduz1
1w/r5pNiLGQfX5KSYg33GZ5yACBRXTQZ/5RQpvUQ1IuirS7LmSQmpIFj3Wkz6rHS
WAFG+fatTeX+U2byDgtfQ8DOX9PGx3ZoHcg1VvOBVzE21CcbCqhm2rK8sVMByyBm
EG3fvIayLK2JeE/5ENRW82Pj6N0SmaberDErj4xntNECLrDuJk6hK1Y=
=ZbM8
-----END PGP MESSAGE-----
fp: 1f18a57e1d4e6716aed0e0cd71586b7a4c0c1a65
- created_at: "2024-08-20T22:32:59Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA8mCvf2Chj0JAQ/+NId7BWeD1tjA2ROCVsjpNMPAUHfZxsBoP2UqOfcGh9Ou
6XSfKhdB7OImUfJESr5YKswqbIcUAUbyG3H7mDs1Ztj9I7Uf6NpnFjamwLKkFCR9
g4716imh+R60eX6tOAYgMRBsx7RPu2j+78GWfxdHTVMAZbm/YIX6PPbBJCGYD3XK
uyPv+ifPC0VfERbtoNNb29FWJVtlB5SQVxcW9m0lNRZt1wuHESW9XJyA5f8gR7QA
1sSOkeqlEZSGcu98PLwtcDGmvOp2s+gPv1hEEAdcniE9qeKir4ZfOVKt/cPW+S32
SUbT8pROLEyWzqAxziIWbJxrycuSBpBHhAyMJI1LLgMsjumAuT4gIlws9AUNLBJL
O0/1gsPSyt21B36wyt4VG9/K1Hu8CPNE7PBavjOCCK2WEY/WEpPALbWnwkAkwvBc
bcFTwuah1R0rwfM33wRYppQ88n+a8mwAkWqJdVxdO3nbsIf/He/Q2sBlQkbGJ2+0
Qg8MOloHEddI1TJyRNmxUfrM/4sx1BS+olxN5/BHQw+Lbh1uJfLLNw7CTEpRr50t
+Nqcs46F/ydBrSGhHBuzSUj1S37cTVzJVULKCPDEAImselQ+dHy51n+5UBeIABIV
Fec/EOi6lpiRf0ZNrQJCMWjzqetWUU2BHFeONhGAJ5jH/P+XL4WGJe1MnK6ifZzS
WAHLiyNyTve4MOIHSQJJ2WJim0DRp5FDQmKQ0/V7cSvBJauL4GIv+Oi4hyzlKgO/
9MMISHRqOy4/9pdR9aUAj0H19prILDFX+I0Akh8LuSnrOmhjH4HuvdY=
=MCCh
-----END PGP MESSAGE-----
fp: 2b9be9660662c6c979ca1149c982bdfd82863d09
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.8.1 version: 3.8.1

BIN
secrets/local-mail.yaml Normal file

Binary file not shown.

View file

@ -24,6 +24,7 @@
./neovim ./neovim
./pass.nix ./pass.nix
./programs.nix ./programs.nix
./rust.nix
./scripts ./scripts
./sway ./sway
./tmate.nix ./tmate.nix

View file

@ -2,7 +2,7 @@
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, nixosConfig, ... }: { config, lib, nixosConfig, pkgs, ... }:
let let
mkOverridesFile = prefs: '' mkOverridesFile = prefs: ''
// Generated by Home Manager. // Generated by Home Manager.
@ -17,6 +17,7 @@ in
lib.mkIf nixosConfig.sbruder.gui.enable { lib.mkIf nixosConfig.sbruder.gui.enable {
programs.librewolf = { programs.librewolf = {
enable = true; enable = true;
package = pkgs.librewolf.override { nativeMessagingHosts = with pkgs; [ browserpass ]; };
settings = { settings = {
"accessibility.force_disabled" = 1; "accessibility.force_disabled" = 1;
"browser.uidensity" = 1; # more compact layout "browser.uidensity" = 1; # more compact layout

View file

@ -119,6 +119,7 @@ in
# communication # communication
linphone # sip softphone linphone # sip softphone
mumble # VoIP group chat mumble # VoIP group chat
signal-desktop # Signal desktop client
# creative/design # creative/design
openscad # parametric/procedural 3d modelling openscad # parametric/procedural 3d modelling
@ -134,6 +135,7 @@ in
# office # office
aspellDicts.de aspellDicts.de
aspellDicts.en aspellDicts.en
gnome.simple-scan # sane GUI
gnucash # bookkeeping gnucash # bookkeeping
hunspellDicts.de-de hunspellDicts.de-de
hunspellDicts.en-gb-ise # dictionary hunspellDicts.en-gb-ise # dictionary

View file

@ -0,0 +1,16 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ lib, pkgs, ... }:
{
home.file.".cargo/config.toml".source = (pkgs.formats.toml { }).generate "cargo-config.toml" {
registry = {
global-credential-providers = lib.singleton "cargo:token-from-stdout ${pkgs.writeShellScript "" ''
set -eu
pass cargo/registry-token/"$(base64 -w0 <<< "''${CARGO_REGISTRY_INDEX_URL}")"
''}";
};
};
}

View file

@ -25,12 +25,10 @@ let
in in
{ {
xdg.configFile = { xdg.configFile = {
"youtube-dl/config".text = textConfig;
"yt-dlp/config".text = textConfig; "yt-dlp/config".text = textConfig;
}; };
home.packages = with pkgs; [ home.packages = with pkgs; [
youtube-dl
unstable.yt-dlp unstable.yt-dlp
]; ];
} }