Compare commits

..

21 commits

Author SHA1 Message Date
Simon Bruder 16cf73afb9
okarin: Migrate to different VPS
Previously, it was hosted on Ionos’s VMware-based infrastructure. I
already had a VPS on their new KVM-based infrastructure, as I was
planning to migrate okarin to it eventually (as it is cheaper). However,
the new infrastructure does not offer PTR records for IPv6 addresses.
Therefore, I was waiting until they would implement that feature (as the
support promised me they would to in the near future).

However, they are now migrating the (at least my) guests from their
VMware hypervisors onto the KVM ones, assigning new IPv6 addresses to
them. This makes the old VPS essentially the same as the old one, but
with less memory and more expensive. So I decided to migrate now.
2024-04-17 12:40:46 +02:00
Simon Bruder 853e817901
sbruder.xyz: Remove deprecated services 2024-04-16 23:40:39 +02:00
Simon Bruder 7daad927e8
yuzuru/static-sites: Migrate okarin’s sites 2024-04-16 23:40:37 +02:00
Simon Bruder ae35e82369
vueko/mail: Add alias 2024-04-14 17:24:11 +02:00
Simon Bruder 670ff94dda
tools: Fix reptyr build in qemu-user-aarch64
This was already fixed in NixOS unstable:
https://github.com/NixOS/nixpkgs/pull/292342
2024-04-13 12:23:36 +02:00
Simon Bruder 62c26e06a5
neovim: Switch to nixd
rnix-lsp is no longer maintained and the package is currently broken in
nixpkgs as it depends on an insecure Nix version.
2024-04-13 12:09:36 +02:00
Simon Bruder 5f81e9db4b
renge/invidious: Remove patch
It is included in the newer version.
2024-04-13 12:08:36 +02:00
Simon Bruder 10f2e5638f
flake.lock: Update
Flake lock file updates:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/d465f4819400de7c8d874d50b982301f28a84605' (2024-02-28)
  → 'github:numtide/flake-utils/b1d9ab70662946ef0850d488da1c9019f3a9752a' (2024-03-11)
• Updated input 'home-manager':
    'github:nix-community/home-manager/652fda4ca6dafeb090943422c34ae9145787af37' (2024-02-03)
  → 'github:nix-community/home-manager/d6bb9f934f2870e5cbc5b94c79e9db22246141ff' (2024-04-06)
• Updated input 'home-manager-unstable':
    'github:nix-community/home-manager/cf111d1a849ddfc38e9155be029519b0e2329615' (2024-03-06)
  → 'github:nix-community/home-manager/40ab43ae98cb3e6f07eaeaa3f3ed56d589da21b0' (2024-04-13)
• Updated input 'nix-pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/5df5a70ad7575f6601d91f0efec95dd9bc619431' (2024-02-15)
  → 'github:cachix/pre-commit-hooks.nix/40e6053ecb65fcbf12863338a6dcefb3f55f1bf8' (2024-04-12)
• Updated input 'nix-pre-commit-hooks/gitignore':
    'github:hercules-ci/gitignore.nix/43e1aa1308018f37118e34d3a9cb4f5e75dc11d5' (2023-12-29)
  → 'github:hercules-ci/gitignore.nix/637db329424fd7e46cf4185293b9cc8c88c95394' (2024-02-28)
• Updated input 'nix-pre-commit-hooks/nixpkgs-stable':
    'github:NixOS/nixpkgs/3dc440faeee9e889fe2d1b4d25ad0f430d449356' (2024-01-10)
  → 'github:NixOS/nixpkgs/614b4613980a522ba49f0d194531beddbb7220d3' (2024-03-17)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/59e37017b9ed31dee303dbbd4531c594df95cfbc' (2024-03-02)
  → 'github:nixos/nixos-hardware/f58b25254be441cd2a9b4b444ed83f1e51244f1f' (2024-04-12)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/880992dcc006a5e00dd0591446fdf723e6a51a64' (2024-03-05)
  → 'github:nixos/nixpkgs/b2cf36f43f9ef2ded5711b30b1f393ac423d8f72' (2024-04-10)
• Updated input 'nixpkgs-overlay':
    'git+https://git.sbruder.de/simon/nixpkgs-overlay?ref=refs/heads/master&rev=32ef4fd545a29cdcb2613934525b97470818b42e' (2024-01-01)
  → 'git+https://git.sbruder.de/simon/nixpkgs-overlay?ref=refs/heads/master&rev=2bcb2b6c7b0e04f4ef8e51e00fd93a5e5cb00bf8' (2024-04-12)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/9df3e30ce24fd28c7b3e2de0d986769db5d6225d' (2024-03-06)
  → 'github:nixos/nixpkgs/1042fd8b148a9105f3c0aca3a6177fd1d9360ba5' (2024-04-10)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/25dd60fdd08fcacee2567a26ba6b91fe098941dc' (2024-03-06)
  → 'github:Mic92/sops-nix/538c114cfdf1f0458f507087b1dcf018ce1c0c4c' (2024-04-08)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/66d65cb00b82ffa04ee03347595aa20e41fe3555' (2024-03-03)
  → 'github:NixOS/nixpkgs/e38d7cb66ea4f7a0eb6681920615dfcc30fc2920' (2024-04-06)
2024-04-13 10:39:56 +02:00
Simon Bruder 1f75062bc2
vueko/mail: Add alias 2024-04-04 16:00:01 +02:00
Simon Bruder 526db3d97b
vueko/mail: Add alias 2024-04-02 19:13:43 +02:00
Simon Bruder ad209fa0f7
vueko/mail: Add alias 2024-04-02 15:41:23 +02:00
Simon Bruder 00bada7b12
renge: Fix invidious
The patch is already in upstream, but for multiple reasons, I decided to
only apply the patch and not update.
2024-03-31 19:57:09 +02:00
Simon Bruder f30318869b
vueko/mail: Add alias 2024-03-31 13:07:27 +02:00
Simon Bruder 709f8d5676
ncmpcpp: Follow now playing lyrics 2024-03-31 13:03:35 +02:00
Simon Bruder 51e8dd4169
vueko/mail: Add alias 2024-03-15 14:05:28 +01:00
Simon Bruder fc7f0f8648
co2_exporter: Fix typo in doCheck 2024-03-15 14:01:32 +01:00
Simon Bruder 11d0870f5c
vueko/mail: Add alias 2024-03-14 10:59:43 +01:00
Simon Bruder a1645314f4
games: Drop yuzu
It is dead[1].

[1]: https://arstechnica.com/gaming/2024/03/switch-emulator-makers-agree-to-pay-2-4-million-to-settle-nintendo-lawsuit/
2024-03-07 11:59:36 +01:00
Simon Bruder 47cb7b4b32
flake.lock: Update
Flake lock file updates:

• Updated input 'flake-utils':
    'github:numtide/flake-utils/1ef2e671c3b0c19053962c07dbda38332dcebf26' (2024-01-15)
  → 'github:numtide/flake-utils/d465f4819400de7c8d874d50b982301f28a84605' (2024-02-28)
• Updated input 'home-manager-unstable':
    'github:nix-community/home-manager/043ba285c6dc20f36441d48525402bcb9743c498' (2024-02-14)
  → 'github:nix-community/home-manager/cf111d1a849ddfc38e9155be029519b0e2329615' (2024-03-06)
• Updated input 'nix-pre-commit-hooks':
    'github:cachix/pre-commit-hooks.nix/0db2e67ee49910adfa13010e7f012149660af7f0' (2024-02-07)
  → 'github:cachix/pre-commit-hooks.nix/5df5a70ad7575f6601d91f0efec95dd9bc619431' (2024-02-15)
• Updated input 'nixos-hardware':
    'github:nixos/nixos-hardware/f1b2f71c86a5b1941d20608db0b1e88a07d31303' (2024-02-13)
  → 'github:nixos/nixos-hardware/59e37017b9ed31dee303dbbd4531c594df95cfbc' (2024-03-02)
• Updated input 'nixpkgs':
    'github:nixos/nixpkgs/01885a071465e223f8f68971f864b15829988504' (2024-02-13)
  → 'github:nixos/nixpkgs/880992dcc006a5e00dd0591446fdf723e6a51a64' (2024-03-05)
• Updated input 'nixpkgs-unstable':
    'github:nixos/nixpkgs/35ff7e87ee05199a8003f438ec11a174bcbd98ea' (2024-02-13)
  → 'github:nixos/nixpkgs/9df3e30ce24fd28c7b3e2de0d986769db5d6225d' (2024-03-06)
• Updated input 'sops-nix':
    'github:Mic92/sops-nix/48afd3264ec52bee85231a7122612e2c5202fa74' (2024-02-13)
  → 'github:Mic92/sops-nix/25dd60fdd08fcacee2567a26ba6b91fe098941dc' (2024-03-06)
• Updated input 'sops-nix/nixpkgs-stable':
    'github:NixOS/nixpkgs/d8cd80616c8800feec0cab64331d7c3d5a1a6d98' (2024-02-10)
  → 'github:NixOS/nixpkgs/66d65cb00b82ffa04ee03347595aa20e41fe3555' (2024-03-03)
2024-03-07 09:50:31 +01:00
Simon Bruder 07cac97bef
vueko/mail: Add alias 2024-03-02 11:47:52 +01:00
Simon Bruder 4c119f0b80
authoritative-dns: Drop INWX secondaries 2024-02-27 15:57:04 +01:00
111 changed files with 3013 additions and 2576 deletions

View file

@ -7,7 +7,6 @@ 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: &all-keys 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,9 +19,6 @@ keys: &all-keys
- &shinobu 28677f2e3584b39f528a779caf445ebb39c882b7 - &shinobu 28677f2e3584b39f528a779caf445ebb39c882b7
- &nazuna 0b8be5d87a10a0e68dda97212c4befad1f9e915c - &nazuna 0b8be5d87a10a0e68dda97212c4befad1f9e915c
- &yuzuru a1ee5bc0249163a047440ef2649e770ec6ea16e4 - &yuzuru a1ee5bc0249163a047440ef2649e770ec6ea16e4
- &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:
@ -100,27 +97,6 @@ creation_rules:
- *simon-alpha - *simon-alpha
- *simon-beta - *simon-beta
- *yuzuru - *yuzuru
- path_regex: machines/koyomi/secrets\.yaml$
key_groups:
- pgp:
- *simon
- *simon-alpha
- *simon-beta
- *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:
@ -133,8 +109,3 @@ creation_rules:
- *fuuko - *fuuko
- *mayushii - *mayushii
- *renge - *renge
- *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": 1726560853, "lastModified": 1710146030,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -85,16 +85,16 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1726989464, "lastModified": 1712386041,
"narHash": "sha256-Vl+WVTJwutXkimwGprnEtXc/s/s8sMuXzqXaspIGlwM=", "narHash": "sha256-dA82pOMQNnCJMAsPG7AXG35VmCSMZsJHTFlTHizpKWQ=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "2f23fa308a7c067e52dfcc30a0758f47043ec176", "rev": "d6bb9f934f2870e5cbc5b94c79e9db22246141ff",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nix-community", "owner": "nix-community",
"ref": "release-24.05", "ref": "release-23.11",
"repo": "home-manager", "repo": "home-manager",
"type": "github" "type": "github"
} }
@ -106,11 +106,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1728337164, "lastModified": 1712989663,
"narHash": "sha256-VdRTjJFyq4Q9U7Z/UoC2Q5jK8vSo6E86lHc2OanXtvc=", "narHash": "sha256-r2X/DIAyKOLiHoncjcxUk1TENWDTTaigRBaY53Cts/w=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "038630363e7de57c36c417fd2f5d7c14773403e4", "rev": "40ab43ae98cb3e6f07eaeaa3f3ed56d589da21b0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -189,11 +189,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1703863825, "lastModified": 1698974481,
"narHash": "sha256-rXwqjtwiGKJheXB43ybM8NwWB8rO2dSRrEqes0S7F5Y=", "narHash": "sha256-yPncV9Ohdz1zPZxYHQf47S8S0VrnhV7nNhCawY46hDA=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-github-actions", "repo": "nix-github-actions",
"rev": "5163432afc817cf8bd1f031418d1869e4c9d5547", "rev": "4bb5e752616262457bc7ca5882192a564c0472d2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -205,6 +205,9 @@
"nix-pre-commit-hooks": { "nix-pre-commit-hooks": {
"inputs": { "inputs": {
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-utils": [
"flake-utils"
],
"gitignore": "gitignore", "gitignore": "gitignore",
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
@ -212,11 +215,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1728092656, "lastModified": 1712897695,
"narHash": "sha256-eMeCTJZ5xBeQ0f9Os7K8DThNVSo9gy4umZLDfF5q6OM=", "narHash": "sha256-nMirxrGteNAl9sWiOhoN5tIHyjBbVi5e2tgZUgZlK3Y=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "1211305a5b237771e13fcca0c51e60ad47326a9a", "rev": "40e6053ecb65fcbf12863338a6dcefb3f55f1bf8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -228,11 +231,11 @@
}, },
"nixos-hardware": { "nixos-hardware": {
"locked": { "locked": {
"lastModified": 1728269138, "lastModified": 1712909959,
"narHash": "sha256-oKxDImsOvgUZMY4NwXVyUc/c1HiU2qInX+b5BU0yXls=", "narHash": "sha256-7/5ubuwdEbQ7Z+Vqd4u0mM5L2VMNDsBh54visp27CtQ=",
"owner": "nixos", "owner": "nixos",
"repo": "nixos-hardware", "repo": "nixos-hardware",
"rev": "ecfcd787f373f43307d764762e139a7cdeb9c22b", "rev": "f58b25254be441cd2a9b4b444ed83f1e51244f1f",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -244,16 +247,16 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1728328465, "lastModified": 1712741485,
"narHash": "sha256-a0a0M1TmXMK34y3M0cugsmpJ4FJPT/xsblhpiiX1CXo=", "narHash": "sha256-bCs0+MSTra80oXAsnM6Oq62WsirOIaijQ/BbUY59tR4=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "1bfbbbe5bbf888d675397c66bfdb275d0b99361c", "rev": "b2cf36f43f9ef2ded5711b30b1f393ac423d8f72",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "nixos", "owner": "nixos",
"ref": "nixos-24.05", "ref": "nixos-23.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
@ -272,11 +275,11 @@
"poetry2nix": "poetry2nix" "poetry2nix": "poetry2nix"
}, },
"locked": { "locked": {
"lastModified": 1719952130, "lastModified": 1712934106,
"narHash": "sha256-j38XlExNwK4ycmoNEdH/dHUd1QGdNvD3gx/UuLY+04Q=", "narHash": "sha256-JubHgaV6HUZarwwq4y2rxJaaj2a6euErJfCqpmhrhWk=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "3487b8ce24d40cc898f3dba0a9af5e028e1d5844", "rev": "2bcb2b6c7b0e04f4ef8e51e00fd93a5e5cb00bf8",
"revCount": 68, "revCount": 66,
"type": "git", "type": "git",
"url": "https://git.sbruder.de/simon/nixpkgs-overlay" "url": "https://git.sbruder.de/simon/nixpkgs-overlay"
}, },
@ -287,43 +290,43 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1720386169, "lastModified": 1710695816,
"narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", "narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "194846768975b7ad2c4988bdb82572c00222c0d7", "rev": "614b4613980a522ba49f0d194531beddbb7220d3",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "nixos-24.05", "ref": "nixos-23.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-stable_2": { "nixpkgs-stable_2": {
"locked": { "locked": {
"lastModified": 1728156290, "lastModified": 1712437997,
"narHash": "sha256-uogSvuAp+1BYtdu6UWuObjHqSbBohpyARXDWqgI12Ss=", "narHash": "sha256-g0whLLwRvgO2FsyhY8fNk+TWenS3jg5UdlWL4uqgFeo=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "17ae88b569bb15590549ff478bab6494dde4a907", "rev": "e38d7cb66ea4f7a0eb6681920615dfcc30fc2920",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "release-24.05", "ref": "release-23.11",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1728241625, "lastModified": 1712791164,
"narHash": "sha256-yumd4fBc/hi8a9QgA9IT8vlQuLZ2oqhkJXHPKxH/tRw=", "narHash": "sha256-3sbWO1mbpWsLepZGbWaMovSO7ndZeFqDSdX0hZ9nVyw=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "c31898adf5a8ed202ce5bea9f347b1c6871f32d1", "rev": "1042fd8b148a9105f3c0aca3a6177fd1d9360ba5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -359,11 +362,11 @@
"rust-overlay": "rust-overlay" "rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1721396844, "lastModified": 1703801091,
"narHash": "sha256-VduymKyeovo7JzcJ3ar4fryebNu36RnKlI+/TOMWN8w=", "narHash": "sha256-ay1oI2IxhODG4KheqdxqlHlt6bUmvAogRZbzIcavR+k=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "a09c08847b2539a069833d9ef72d74224c170a54", "rev": "9bddae5f112cdc471faf1a71d34bc4cc2497e946",
"revCount": 19, "revCount": 16,
"type": "git", "type": "git",
"url": "https://git.sbruder.de/simon/password-hash-self-service" "url": "https://git.sbruder.de/simon/password-hash-self-service"
}, },
@ -387,11 +390,11 @@
"treefmt-nix": "treefmt-nix" "treefmt-nix": "treefmt-nix"
}, },
"locked": { "locked": {
"lastModified": 1714509427, "lastModified": 1701399357,
"narHash": "sha256-YTcd6n7BeAVxBNhzOgUHMmsgBkfQ2Cz9ZcFotXrpEg8=", "narHash": "sha256-QSGP2J73HQ4gF5yh+MnClv2KUKzcpTmikdmV8ULfq2E=",
"owner": "nix-community", "owner": "nix-community",
"repo": "poetry2nix", "repo": "poetry2nix",
"rev": "184960be60652ca7f865123e8394ece988afb566", "rev": "7acb78166a659d6afe9b043bb6fe5cb5e86bb75e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -450,11 +453,11 @@
"nixpkgs-stable": "nixpkgs-stable_2" "nixpkgs-stable": "nixpkgs-stable_2"
}, },
"locked": { "locked": {
"lastModified": 1728345710, "lastModified": 1712617241,
"narHash": "sha256-lpunY1+bf90ts+sA2/FgxVNIegPDKCpEoWwOPu4ITTQ=", "narHash": "sha256-a4hbls4vlLRMciv62YrYT/Xs/3Cubce8WFHPUDWwzf8=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "06535d0e3d0201e6a8080dd32dbfde339b94f01b", "rev": "538c114cfdf1f0458f507087b1dcf018ce1c0c4c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -501,11 +504,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1714058656, "lastModified": 1699786194,
"narHash": "sha256-Qv4RBm4LKuO4fNOfx9wl40W2rBbv5u5m+whxRYUMiaA=", "narHash": "sha256-3h3EH1FXQkIeAuzaWB+nK0XK54uSD46pp+dMD3gAcB4=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "c6aaf729f34a36c445618580a9f95a48f5e4e03f", "rev": "e82f32aa7f06bbbd56d7b12186d555223dc399d1",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -8,10 +8,10 @@
inputs = { inputs = {
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05"; nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager/release-24.05"; home-manager.url = "github:nix-community/home-manager/release-23.11";
home-manager.inputs.nixpkgs.follows = "nixpkgs"; home-manager.inputs.nixpkgs.follows = "nixpkgs";
home-manager-unstable.url = "github:nix-community/home-manager"; home-manager-unstable.url = "github:nix-community/home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable"; home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
@ -23,6 +23,7 @@
nixos-hardware.url = "github:nixos/nixos-hardware/master"; nixos-hardware.url = "github:nixos/nixos-hardware/master";
nix-pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix/master"; nix-pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix/master";
nix-pre-commit-hooks.inputs.flake-utils.follows = "flake-utils";
nix-pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs-unstable"; nix-pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs-unstable";
sops-nix.url = "github:Mic92/sops-nix"; sops-nix.url = "github:Mic92/sops-nix";
@ -155,11 +156,12 @@
pkgs.writeShellScript "unlock-${hostname}" '' pkgs.writeShellScript "unlock-${hostname}" ''
set -exo pipefail set -exo pipefail
# opening luks fails if gpg-agent is not unlocked yet # opening luks fails if gpg-agent is not unlocked yet
pass "devices/${hostname}/luks" | ssh \ pass "devices/${hostname}/luks" >/dev/null
ssh \
${lib.optionalString unlockOverV4 "-4"} \ ${lib.optionalString unlockOverV4 "-4"} \
-p 2222 \ -p 2222 \
"root@${targetHost}" \ "root@${targetHost}" \
"cat > /crypt-ramfs/passphrase" "cat > /crypt-ramfs/passphrase" < <(pass "devices/${hostname}/luks")
'') '')
self.nixosConfigurations); self.nixosConfigurations);
@ -169,23 +171,6 @@
}); });
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

@ -1,28 +0,0 @@
-----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-----

View file

@ -1,28 +0,0 @@
-----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 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
xsFNBAAAAAABEACxOC3MelTJWQ+eZDunjDfvYC2bPFP/jZRlgxBp0NOzh4Oql6D+
0CjuQPbqEaqEGJ3xqT4u/E0jovSqFKsxGGimeu4F0CkobzBhVZhEhw3oQRG5uSFS
x/S1QMO9v3RcjIVM8iBSrsrCx8EJDrfveJQor7ullhaGA6XMnxPB2In8MwnjtBFH
G4njMJj5jFtpWxHs8fAum9kBNgtxkahbjOiTXq0nWfIPr65X5Pz0pxSH9fnWsbr5
+QARbL6bWVy5hkS1UItS3KEnJyotLep4JkFEN7UySPjX25z85kAw4eLMn0pRNCLz
b+b76IX04T5r1PGUisu6wNyITJz8yQWyB7fba8NJf1nMPtbY9CNwWtXbl47mp8jJ
qEEBjv8mQor3V5QzjQkMLb30m8w5QTbNaupxFsjeLiUAq+LRm4wxO7Yzu032sbit
HWpcceAho7VJUqwSqgqE8KGANVldgxgG/w8l19c/iD4nVvwlTTCiS12yCMmkKgj9
JN2WSzmdrpPOyWbYZzRbQsNlxbndkWP9iusnP9cceE6diUZCYTwdZZIwYY1anxy2
NXoXM+r+EYCj4urHsTzj2o+04mitsZH+7wUWLtSIuI0upqpq9DYDN1kZE0c0sfxY
VCu3dRL0wtNWokoYwWV+l8nMFhQgnhlMf21DgUlA0BNi9BhESKWIpSvDBQARAQAB
zSlyb290IChJbXBvcnRlZCBmcm9tIFNTSCkgPHJvb3RAbG9jYWxob3N0PsLBYgQT
AQgAFgUCAAAAAAkQcVhrekwMGmUCGw8CGQEAAOOdEAAL1r+OcspofLYAnefX52uU
CMnBOIK00CuOi+Bg+4gRNTEeed7tOKf9RqU2AArzkRrJindflSnkCe088/Qfw/ui
HXs0hGewcp3i/v5SW0MJI5fZox5hSYTKkfUswgwNf8ZyzFdnxYyIXR2dfWiTo8Uv
VcAe1n/rIe7W7T6uKsrdlgYs2iT7Gbo4Txned2nl8Zq2lE7qzpbksqOV1iy+I0RS
CIyV7PRBQfOIC+rIRPeZD1tOxD2PH4CJPW9jwmM9E42/7gcu/cJBN/MP2vUJS8/l
sbvOT2pMqOqrJRXrmlJE2zNyQK1gJeYdhtNN+8INYoy29yeyvMnaSaUsXpjEb76E
jqvYeFEF6LR2RAQJ1HdCQCGianrFcqpDq7pW1fs+TB+YSFcXUEsNdIeIwROP0hyG
usACFHst2FfYVEd3uz98EHMrgVz3sw48BpK3s8aYVdaRAU/L6lljW3a+6+oAPjMJ
6z6yfgTXX5m+ZwdBCPyF6KlRtZNZQTwqmsULcJcb/fLNynZULRSA3TW6rDhS4NXb
wRF1OSwMMTqX2svuqKlZQhOfaa7w9QL9A/Y4Fa3lZoQOGSdT2+/e0d+MD2T4JqZ6
3fC4XIqUkhcgeOsfJ0WOQdxm/RRhz8pwQhzUAjYk2jG/JmaYUCVaMugJSLBjXN78
JKqniA3Iyr5AP2yBxFt9Ag==
=yxFM
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -1,15 +0,0 @@
<!--
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

@ -1,79 +0,0 @@
# 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

@ -1,58 +0,0 @@
# 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

@ -1,73 +0,0 @@
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

@ -23,9 +23,6 @@ in
}; };
vueko = { vueko = {
system = "aarch64-linux"; system = "aarch64-linux";
extraModules = [
"${inputs.infinisilSystem}/config/new-modules/murmur.nix"
];
targetHost = "vueko.sbruder.de"; targetHost = "vueko.sbruder.de";
}; };
@ -49,6 +46,9 @@ in
}; };
renge = { renge = {
system = "aarch64-linux"; system = "aarch64-linux";
extraModules = [
"${inputs.infinisilSystem}/config/new-modules/murmur.nix"
];
targetHost = "renge.sbruder.de"; targetHost = "renge.sbruder.de";
}; };
@ -76,23 +76,4 @@ in
targetHost = "yuzuru.sbruder.de"; targetHost = "yuzuru.sbruder.de";
}; };
koyomi = {
system = "x86_64-linux";
extraModules = [
hardware.common-cpu-amd
hardware.common-pc-ssd
];
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
]; ];
@ -19,10 +19,7 @@
sbruder = { sbruder = {
wireguard.home.enable = true; wireguard.home.enable = true;
nginx.hardening.enable = true; nginx.hardening.enable = true;
printing.server.enable = true; restic.system = {
restic = {
enable = true;
backups.system = {
enable = true; enable = true;
qos = true; qos = true;
extraPaths = [ extraPaths = [
@ -37,7 +34,6 @@
"/data/torrent" "/data/torrent"
]; ];
}; };
};
unfree.allowSoftware = true; unfree.allowSoftware = true;
}; };
@ -54,20 +50,4 @@
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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2021-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -92,8 +92,6 @@
} }
]; ];
services.prometheus.exporters.smartctl.devices = [ "/dev/nvme0n1" "/dev/sda" "/dev/sdb" "/dev/sdc" ];
powerManagement.cpuFreqGovernor = "schedutil"; powerManagement.cpuFreqGovernor = "schedutil";
networking = { networking = {

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -12,9 +12,8 @@ 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";
# https://fasttext.cc/docs/en/language-identification.html word2vecModel = "/var/lib/languagetool/word2vec";
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";
}; };
@ -23,13 +22,7 @@ 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

@ -8,9 +8,6 @@
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

@ -1,119 +0,0 @@
# 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,14 +13,11 @@
}; };
}; };
sbruder.restic.backups.system.extraExcludes = [ sbruder.restic.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,6 +15,11 @@ 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

@ -1,19 +0,0 @@
<!--
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

@ -1,53 +0,0 @@
# 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

@ -1,53 +0,0 @@
# 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

@ -1,73 +0,0 @@
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,60 +0,0 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, pkgs, ... }:
{
sops.secrets.li7y-environment = {
sopsFile = ../secrets.yaml;
owner = "li7y";
};
users.users.li7y = {
isSystemUser = true;
home = "/var/lib/li7y";
createHome = true;
group = "li7y";
};
users.groups.li7y = { };
virtualisation = {
podman = {
enable = true;
defaultNetwork.settings = {
ipv6_enabled = true;
};
};
};
systemd.services.podman-li7y = {
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStartPre = "${pkgs.podman}/bin/podman pull git.sbruder.de/simon/li7y";
ExecStart = "${pkgs.podman}/bin/podman run --rm --name=li7y --userns=keep-id -v /run/postgresql:/run/postgresql --env-file ${config.sops.secrets.li7y-environment.path} -e 'DATABASE_URL=postgres:///?port=5432&host=/run/postgresql' -e LISTEN_ADDRESS=:: -p 127.0.0.1:8080:8080 git.sbruder.de/simon/li7y";
User = "li7y";
};
};
services.nginx = {
enable = true;
virtualHosts."i7y.eu" = {
forceSSL = true;
enableACME = true;
locations."/".proxyPass = "http://127.0.0.1:8080";
};
};
services.postgresql = {
enable = true;
ensureDatabases = [ "li7y" ];
ensureUsers = [
{
name = "li7y";
ensureDBOwnership = true;
}
];
};
}

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: 2TB WD_BLACK SN850X NVMe * SSD: 1TB Samsung 980 Pro 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

@ -18,17 +18,14 @@
}; };
gui.enable = true; gui.enable = true;
media-proxy.enable = true; media-proxy.enable = true;
podman.enable = true; mullvad.enable = true;
restic = { restic.system = {
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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -55,8 +55,6 @@
{ device = "/dev/disk/by-uuid/98de7ced-4d7c-4915-bf5b-1a0300458ea6"; } { device = "/dev/disk/by-uuid/98de7ced-4d7c-4915-bf5b-1a0300458ea6"; }
]; ];
services.prometheus.exporters.smartctl.devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ];
# GPU # GPU
hardware.opengl = { hardware.opengl = {
package = pkgs.mesa.drivers; package = pkgs.mesa.drivers;
@ -74,7 +72,7 @@
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
clinfo clinfo
nvtopPackages.intel nvtop-amd # also returns basic stats for intel
]; ];
security.wrappers."intel_gpu_top" = { security.wrappers."intel_gpu_top" = {

View file

@ -1,41 +0,0 @@
<!--
SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
SPDX-License-Identifier: CC-BY-SA-4.0
-->
# koyomi
## Hardware
[Hetzner Online AX41-NVMe](https://www.hetzner.com/de/dedicated-rootserver/ax41-nvme/)
- Motherboard: ASRockRack B565D4-V1L
- CPU: AMD Ryzen 5 3600
- RAM: 2×32GB Samsung [M378A4G43AB2-CWE](https://semiconductor.samsung.com/dram/module/udimm/m378a4g43ab2-cwe/) (DDR4 3200MHz)
- SSD: 2×512GB M.2 NVMe SAMSUNG MZVL2512HCJQ-00B00
## Setup
As it is a physical server (not a VM) in a remote location,
extra care must be taken when installing.
Fortunately, Hetzner provides an automated way to reset the server (by sending Ctrl+Alt+Del or force resetting)
and a rescue system that can be activated before a reboot.
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.
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,
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
Hypervisor. Exact scope is to be determined.
## Name
Araragi Koyomi is a student from the *Monogatari Series*.

View file

@ -1,28 +0,0 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{
imports = [
./hardware-configuration.nix
../../modules
./services/hypervisor.nix
./services/haproxy.nix
];
sbruder = {
restic = {
enable = true;
backups.system.enable = true;
mirror.backblaze.enable = true;
prune.enable = true;
};
wireguard.home.enable = true;
podman.enable = true;
};
networking.hostName = "koyomi";
system.stateVersion = "24.05";
}

View file

@ -1,79 +0,0 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ modulesPath, pkgs, ... }:
{
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot = {
swraid.enable = true;
kernelModules = [ "kvm-amd" "nct6775" ];
kernelParams = [ "ip=dhcp" ];
loader = {
grub = {
devices = [ "/dev/nvme0n1" "/dev/nvme1n1" ];
};
};
initrd = {
availableKernelModules = [ "aesni_intel" "ahci" "igb" "nvme" ];
kernelModules = [ "dm-snapshot" ];
network.enable = true; # remote unlocking
luks.devices = {
koyomi-pv = {
name = "koyomi-pv";
device = "/dev/disk/by-uuid/4907ad59-e6cf-40ed-a0ff-3dc09c0c7a50";
preLVM = true;
allowDiscards = true;
};
};
# FIXME XXX HACK
# This is required to have the md device available under /dev/disk/by-uuid.
# Both commands are run as part of the regular stage-1 init script,
# but for some reason, they need to be run twice.
preLVMCommands = ''
udevadm trigger
udevadm settle
'';
};
};
fileSystems = {
"/" = {
device = "/dev/disk/by-uuid/4b4efa64-e571-4937-bb1c-7608e9d7630d";
fsType = "btrfs";
options = [ "discard=async" "noatime" "compress=zstd" ];
};
"/boot" = {
device = "/dev/disk/by-uuid/83e67d66-ec76-4c9f-8796-1165cdb5362d";
fsType = "ext2";
};
};
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.usePredictableInterfaceNames = false;
systemd.network = {
enable = true;
networks = {
eth0 = {
name = "eth0";
DHCP = "yes";
domains = [ "sbruder.de" ];
address = [ "2a01:4f9:3051:39c6::1/64" ];
gateway = [ "fe80::1" ];
};
};
};
}

View file

@ -1,74 +0,0 @@
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]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2024-08-27T09:48:17Z"
mac: ENC[AES256_GCM,data:XBL1szDu+Mw7A/D31BJt4rD5a4ic1EuTmUefMYoMdL4kTl5fi7Ckk9EIV6MI5nKhF8ejR4cN94ih2cILzLodj/e89Xf74d0o8RX5PlUzqFsHoKV/yy9QVVtDDqnwo87sGZztUUcjlJX427SfPwdcMlNAuCoEZ/3SOQgcz5yoMB8=,iv:+WOJuSpSwB74brg3/SZ4Yu2WVtE4YOOiGfwlencLWps=,tag:YchYDy1eKXmTbK0Jb1Ewjg==,type:str]
pgp:
- created_at: "2024-08-20T22:33:06Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdA059TryQI438sM8HUkXawVy/b05ZXpRuhJwe7y7nwEjgw
+weY4cgFW4vA4dboZfh1ZNTCkqtRFdeOEe7PoP0cAlafqOs4zZu2sgHlcPKYDeJN
hF4Dub78fMESoMASAQdA9f8/bT94aLGvEBuNn11BhGjsTWyU0mKJugMQRCo55HYw
d/h7PEKHl2GZWydF3lWTKx0cfLDpywmMBary7PtVK4lFYuDdlXodWC85I6UPe8wp
hF4DM6AcvgVUx2MSAQdA4AKcSfXJei4vmFQ4DF7xzAuA530Cb7rWpK4AE38ByRow
jFako55pUboMSdXtnC/bzy2cFeuRxT0mGMXgLbDri02/nxG+vljeFYJyozb6UXNp
1GYBCQIQYmT27KaMqjQq6zFSr1zKEO+PjBH9rCZTBpsCULNxqOMn+3IE7XoYtdPv
WVU7zZYaK21JRTbnWDjikdvJe60bSRxExIJX35vH3hczc3WP3V/LqQy6X8Fd81pw
pcbiSfWOTXU=
=y7H/
-----END PGP MESSAGE-----
fp: 6CD375BD0741F67E5A289BC333A01CBE0554C763
- created_at: "2024-08-20T22:33:06Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4Dub78fMESoMASAQdA1W7CmVHBJD/yJWyGvT6lGEXIhsC/gp0XCoHu672OfTMw
OBqitpHTrHyIN7qmexL9YpGsfPtwRGu6hb6lUsWj2+gJ1Pynk6iGM8kwUxGPnj8C
1GYBCQIQnO/cJgEhybp/i1E6l4i9IG7cbWupNTp6uJ7Ag8EB6cvUqAYN5QHpM2/D
FYMJRh4skIB2LzG2lxPyOOR5F5FQ2j/Rtf7SoCeEidWOBhGPQPBSNQOTE+43zwKo
Z0pnq864C0c=
=btUj
-----END PGP MESSAGE-----
fp: 0C8AF4B4320A511384DF6B5BB9BEFC7CC112A0C0
- created_at: "2024-08-20T22:33:06Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hF4DLHeEFiC484ASAQdAsGJfau7e9h38vm5srU1s9vdvYrCUJanDhM6aTjVQU3Uw
jplWFk/1aNsEAeA2yIydiyw/wzY8h+QGrcfDTNViw6Zwq2kRvVp5t9IW1k1IteO3
1GYBCQIQWrU3Y1SLCA6tV0xLCUeyZbUrgnCgJNUceRHmSV0oi3jMLEv0YUfbf+Hl
VIDfM6RZQeaY0WVLAuFnIEYFJ1RhXgv9nFo/3txZw3WYx3kjKPPRacmoHMturD+1
Ay5oemXyWMo=
=dfVv
-----END PGP MESSAGE-----
fp: 403215E0F99D2582C7055C512C77841620B8F380
- created_at: "2024-08-20T22:33:06Z"
enc: |-
-----BEGIN PGP MESSAGE-----
hQIMA3FYa3pMDBplARAAjkLNlHDhqSgxY2IbP10Rx+KlATMRBqzDq2Wx+gdBuWB6
uwGX0Lk1FbcqnhGtUYdtiQBU+7y08oSZ0iFv+tOxTBEGjVBcdUQBjYJa0x1X0kcM
xSfY86bxuJAlvBQJWv7iqdwHPks3DhkePqg8sNwSXUA4wk/L8/JAVnkhbqJ9Am9x
VLJk5xjlFsJwyRMoGui8SDogdc6Voe7zValQXVU5b93Z9klO67dFBEL9nfkUNqhr
mwu0QNRMZGQYE9OYlt41kVRy9x8lATm9J9j12MsEnr9R/8viJyBURHwx+DerRsa9
tJCf3UgJjcK1F54DTGg/ethCOtYDAGF//U0rU9Fcgwff9axZr6fDqUVHIeeE0GAX
7cs+yR5Gp+szfEshm4rSTZPOjZB7xVciCUEIKhlXm2y3dL43idWWYj/+50BMUt1p
HhizkrbsyA+JiAYSE4T4uwOLVoU/jOpecQnn25hrSHX8OoSIIUiaLWFnNMvwobcq
3ummmjAUQ6nxhuO6NQMogrihyqOusidxlBcT7FcP3+V4seo3Co3IlmsCi1w0HmSf
SzLPtJoIaDcDCSVgnlINzfPT9dvDeTOppgUjHMZjbTZDGdUc+jEXb3P/IIqgjrJi
XYtvleP3aoQ84GI3SMvpqwqUfd8kkzvVatGrjA55knQq9HA2o+oq5k9nJnOwEjHS
VgFz6zGoYcr62vaAiBVaSR8ozVQpGjNpq9iC0VR3wpz2J7k9Y8XM+5e3amR15Fm7
lPV3ZBl7OUxTURxnfUdECdmf+19gObsJsiu5WTsVNYsqMIG8nDR/
=pbOT
-----END PGP MESSAGE-----
fp: 1f18a57e1d4e6716aed0e0cd71586b7a4c0c1a65
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -1,118 +0,0 @@
# 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

@ -1,148 +0,0 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ lib, pkgs, ... }:
let
guests = {
ci-runner = {
mac = "42:80:00:00:00:02";
v4 = "10.80.32.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";
};
};
# port forwarding for IPv4
portForwards = {
tcp = { };
udp = { };
};
in
{
sbruder.restic = {
enable = true;
backups.vm-image = {
enable = true;
lvm.lvs = [
"hiroshi"
];
};
};
virtualisation.libvirtd = {
enable = true;
qemu.package = pkgs.qemu_kvm;
};
boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true;
"net.ipv6.conf.all.forwarding" = true;
};
systemd.network = {
enable = true;
netdevs = {
br-virt = {
netdevConfig = {
Name = "br-virt";
Kind = "bridge";
};
};
};
networks = {
br-virt = {
name = "br-virt";
address = [ "10.80.32.1/24" "2a01:4f9:3051:39c6:1::1/80" ];
};
};
};
services.resolved.enable = false;
services.dnsmasq = {
enable = true;
settings = {
interface = [ "br-virt" ];
bind-interfaces = true; # do not bind to the wildcard interface
bogus-priv = true; # do not forward revese lookups of internal addresses
dhcp-fqdn = true; # only insert qualified names of DHCP clients into DNS
domain-needed = true; # do not forward names without domain
no-hosts = true; # do not resolve hosts from /etc/hosts
no-resolv = true; # only use explicitly configured resolvers
domain = [ "koyomi.sbruder.de" ];
enable-ra = true; # required to tell clients to use DHCPv6
# Force static configuration
dhcp-range = [
"10.80.32.0,static,255.255.255.0"
"2a01:4f9:3051:39c6:1::,static,80"
];
dhcp-host = lib.flatten (lib.mapAttrsToList
(name: { mac, v4, v6 }: [
"${mac},${v4},${name}"
"${mac},[${v6}],${name}"
])
guests);
# Hetzner recursive name servers
# https://docs.hetzner.com/dns-console/dns/general/recursive-name-servers/
server = [
"185.12.64.1"
"185.12.64.2"
"2a01:4ff:ff00::add:1"
"2a01:4ff:ff00::add:2"
];
};
};
networking.firewall = {
allowedTCPPorts = map lib.toInt (lib.attrNames portForwards.tcp);
allowedUDPPorts = map lib.toInt (lib.attrNames portForwards.udp);
interfaces.br-virt = {
allowedTCPPorts = [ 53 ]; # EDNS
allowedUDPPorts = [ 53 67 547 ]; # DNS / DHCP / DHCPv6
};
};
networking.nftables = {
enable = true;
ruleset = ''
# only IPv4
table ip hypervisor-nat {
chain postrouting {
type nat hook postrouting priority filter; policy accept
oifname eth0 masquerade
}
chain prerouting {
type nat hook prerouting priority dstnat; policy accept
${lib.concatStrings (lib.mapAttrsToList (port: guest: ''
iifname eth0 tcp dport ${port} dnat to ${guests.${guest}.v4}
'') portForwards.tcp)}
${lib.concatStrings (lib.mapAttrsToList (port: guest: ''
iifname eth0 udp dport ${port} dnat to ${guests.${guest}.v4}
'') portForwards.udp)}
}
}
table inet hypervisor-filter {
chain forward {
type filter hook forward priority filter; policy drop
iifname br-virt oifname eth0 counter accept
iifname eth0 oifname br-virt counter accept
}
}
'';
};
}

View file

@ -18,14 +18,11 @@
}; };
gui.enable = true; gui.enable = true;
media-proxy.enable = true; media-proxy.enable = true;
podman.enable = true; mullvad.enable = true;
restic = { restic.system = {
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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2021-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -45,8 +45,6 @@
}; };
}; };
services.prometheus.exporters.smartctl.devices = [ "/dev/nvme0n1" ];
powerManagement = { powerManagement = {
cpuFreqGovernor = "schedutil"; cpuFreqGovernor = "schedutil";
}; };

View file

@ -13,13 +13,10 @@
sbruder = { sbruder = {
gui.enable = true; gui.enable = true;
restic = { restic.system = {
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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later

View file

@ -9,6 +9,7 @@
./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,15 +18,18 @@
./services/hedgedoc.nix ./services/hedgedoc.nix
./services/invidious ./services/invidious
./services/matrix ./services/matrix
./services/murmur.nix
./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 = { restic.system = {
enable = true; enable = true;
backups.system.enable = true; prune = true;
}; };
wireguard.home.enable = true; wireguard.home.enable = true;
infovhost.enable = true; infovhost.enable = true;

View file

@ -2,8 +2,10 @@ 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]
murmur-superuser: ENC[AES256_GCM,data:hPuMK8wbqD/3qKXQbOActq/VJZ+6jFlddQ==,iv:68ZhkpkfxakCOYxFXkCSP/sBamETeSs4CGTRaoBS6co=,tag:5UuYCxDiJ6e2CXjDV5/5yA==,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]
@ -14,8 +16,8 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-10-08T20:39:38Z" lastmodified: "2024-01-10T18:29:17Z"
mac: ENC[AES256_GCM,data:tgrvHkBsuxvkOe65YUkA/7iOcuwE3Vd6l46wLRSXK2DVED2FAdvO/cXvwsUKzIRKjrs/QXUl4T+lWGQC024Wiy6gXQB3edjxDT6aiGSzXWQAOmTI8/oLzxNTeuysTKNtIAxbz5x6d88JFx5PswtuYUb8x60xMPp3LTJbKnao/LI=,iv:l48P6gmEyeqSOHotLRCmYb7aZgnANceUvveVvGgpAyE=,tag:X5fFIxDxW9sIO4yF4B0C5Q==,type:str] mac: ENC[AES256_GCM,data:jsYCPL7/AFxg9mRM/mKhwiy4eH6ZGMyCCSBu+jSfIk/T8RSd9zh0AZ/p5rAwfbW20AzetivzRB4bSgcymLIcCr900EQLdPIuaZgxeGcbZ80N/7I0zF4u8K8oa1pKhyr1UUj48XjL55IdvVOsyvfq/I/KSbIbO7+fBHeQ51crCeo=,iv:CNmKwvZ61PdeyOvGP7elm/yvokll//fiKxdWFe2cfPo=,tag:PVQRV0G3VtBsD0tk34DHig==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:10Z" - created_at: "2024-01-22T00:20:10Z"
enc: |- enc: |-

View file

@ -3,7 +3,20 @@
# 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;
@ -11,13 +24,8 @@
root = pkgs.element-web; root = pkgs.element-web;
# https://github.com/vector-im/element-web#configuration-best-practices extraConfig = mkSecurityHeaders true;
extraConfig = '' locations."/usercontent/".extraConfig = mkSecurityHeaders false;
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

@ -1,29 +0,0 @@
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

@ -1,4 +0,0 @@
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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2021-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -17,7 +17,6 @@
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,12 +41,6 @@
use_pubsub_feeds = true; use_pubsub_feeds = true;
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
# when this service is re-deployed on a host with state version ≥ 24.05
db.user = "invidious";
}; };
extraSettingsFile = config.sops.secrets.invidious-extra-settings.path; extraSettingsFile = config.sops.secrets.invidious-extra-settings.path;
}; };
@ -65,6 +58,7 @@
''; '';
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

@ -8,9 +8,4 @@
./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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2021-2022 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -25,8 +25,6 @@
channelname = ''[ \\-=\\w\\#\\[\\]\\{\\}\\(\\)\\@\\|]+''; channelname = ''[ \\-=\\w\\#\\[\\]\\{\\}\\(\\)\\@\\|]+'';
}; };
}; };
# upstream (out-of-tree) does not define this, but nixpkgs wants (🥁) it
systemd.services.murmur.wants = [ "network-online.target" ];
services.nginx.virtualHosts."mumble.sbruder.de" = { services.nginx.virtualHosts."mumble.sbruder.de" = {
enableACME = true; enableACME = true;

View file

@ -8,12 +8,6 @@ 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 = {
@ -81,22 +75,12 @@ in
"shinobu.vpn.sbruder.de:9100" "shinobu.vpn.sbruder.de:9100"
"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"
"hiroshi.vpn.sbruder.de:9100"
]; ];
relabel_configs = lib.singleton relabelVpnConfig; relabel_configs = lib.singleton {
} target_label = "instance";
{ source_labels = lib.singleton "__address__";
job_name = "smartctl"; regex = "(.*)\\.vpn\\.sbruder\\.de:9100";
static_configs = mkStaticTargets [ };
"fuuko.vpn.sbruder.de:9633"
"mayushii.vpn.sbruder.de:9633"
"nunotaba.vpn.sbruder.de:9633"
"hitagi.vpn.sbruder.de:9633"
"shinobu.vpn.sbruder.de:9633"
"koyomi.vpn.sbruder.de:9633"
];
relabel_configs = lib.singleton relabelVpnConfig;
} }
{ {
job_name = "qbittorrent"; job_name = "qbittorrent";
@ -104,7 +88,11 @@ 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 relabelVpnConfig; relabel_configs = lib.singleton {
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:9561";
};
} }
( (
let let
@ -123,7 +111,10 @@ 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 relabelVpnConfig; relabel_configs = lib.singleton {
target_label = "instance";
replacement = "shinobu";
};
} }
{ {
job_name = "hcloud"; job_name = "hcloud";
@ -150,7 +141,11 @@ 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 relabelVpnConfig; relabel_configs = lib.singleton {
target_label = "instance";
source_labels = lib.singleton "__address__";
regex = "(.*)\\.vpn\\.sbruder\\.de:9433";
};
} }
{ {
job_name = "snmp"; job_name = "snmp";
@ -176,13 +171,6 @@ in
} }
]; ];
} }
{
job_name = "haproxy";
static_configs = mkStaticTargets [
"koyomi.vpn.sbruder.de:8404"
];
relabel_configs = lib.singleton relabelVpnConfig;
}
]; ];
rules = rules =

View file

@ -0,0 +1,63 @@
# 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,6 +5,10 @@
{ 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";
@ -41,6 +45,13 @@
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,29 +1,47 @@
<!-- <!--
SPDX-FileCopyrightText: 2022-2024 Simon Bruder <simon@sbruder.de> SPDX-FileCopyrightText: 2022-2023 Simon Bruder <simon@sbruder.de>
SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-License-Identifier: CC-BY-SA-4.0
--> -->
## End of life On this domain, the following services are currently available:
Because of the increasing hostility of YouTube, * [Invidious](https://iv.sbruder.xyz)
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**.
This information site is scheduled to be deleted in late Q4 2024. They are all semi-public instances.
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 publicly available: Previously, the following services were also 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 Twitter (which no longer exists in its previous form), Reddit, and YouTube as both Twitter (which no longer exists in its previous form) and Reddit
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.
@ -32,10 +50,40 @@ 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

@ -0,0 +1,48 @@
# 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,4 +1,3 @@
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]
@ -8,8 +7,8 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-08-26T18:50:19Z" lastmodified: "2023-08-08T09:43:37Z"
mac: ENC[AES256_GCM,data:k26ZEKuFtS0GLMqFIbY0QiVfHvmpxt3JgLvZIhEHcC3wQ80OhRNeyKocZhua1T5iSfhfvlckXYZl6tTZkCEh4fj3NmYMtQ9vwpoexdYWwx5ylPT3rpByfBbO+foHgQ3JXk6Kyt2R9ULjghMU3/lEcsG4AuGU1XMomsTzrdigXY8=,iv:ls3nIFIwTM//tSvee/aHj6Qv2nn/gZMKgGF+aQWNxeg=,tag:l58uHLpvPfIkbUn9gl+lzg==,type:str] mac: ENC[AES256_GCM,data:lxoKzGyPwdfeI5Dlmgx9K9SBhfRIaokvum+dJWABUoGtIMtrhp4K4ZRF1Rjja8oTi4w3b+s9aUBpxt8TLu9vJZFsUkhY2gqW5bX3Ub/3xMAR9YSG3LtijRSMuKkdVlAkdjB6Guz9aHNVBG3fTZ+SfTlyOQdImW6bK4tydbGHKgY=,iv:6kVR4zZfHnqhcOT3N2tClGST8h7FLjIseXDu2xS2DEY=,tag:rd/f7cHSoxLT3O7HluVWLA==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:19Z" - created_at: "2024-01-22T00:20:19Z"
enc: |- enc: |-
@ -80,4 +79,4 @@ sops:
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 28677f2e3584b39f528a779caf445ebb39c882b7 fp: 28677f2e3584b39f528a779caf445ebb39c882b7
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.8.1 version: 3.7.3

View file

@ -1,15 +0,0 @@
# 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-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -26,65 +26,32 @@ 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 in
interfaceIdentifier; {
in
rec {
vlan = { vlan = {
lan = { lan = {
id = 10; id = 10;
subnet = mkSubnet "10.80.1.0/24" "2001:470:73b9:1::/64"; subnet = mkSubnet "10.80.1.0/24" "fd00:80: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" "2001:470:73b9:2::/64"; subnet = mkSubnet "10.80.2.0/24" "fd00:80: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" "2001:470:73b9:3::/64"; subnet = mkSubnet "10.80.3.0/24" "fd00:80: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" "2001:470:73b9:4::/64"; subnet = mkSubnet "10.80.4.0/24" "fd00:80: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 = {
@ -156,15 +123,4 @@ rec {
} }
]; ];
}; };
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-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -31,14 +31,11 @@ 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;
@ -109,20 +106,6 @@ 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 = {
@ -145,13 +128,6 @@ 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,11 +5,6 @@
{ 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 = {
@ -56,23 +51,9 @@ 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-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -17,12 +17,7 @@ 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,90 +4,34 @@
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 $WAN_IFACES counter accept iifname $NAT_LAN_IFACES oifname $NAT_WAN_IFACES counter accept
iifname $WAN_IFACES oifname $NAT_LAN_IFACES ct state established,related counter accept iifname $NAT_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 $WAN_IFACES oifname "br-iot" ct state established,related counter accept iifname $NAT_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 ip nat { table inet 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 {
@ -116,7 +60,7 @@ table inet restrict-wan {
} }
# Traffic control # Traffic control
# Needs output and prerouting to match packets from localhost and lan # Neets 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,6 +9,5 @@
enable = true; enable = true;
listenAddress = config.sbruder.wireguard.home.address; listenAddress = config.sbruder.wireguard.home.address;
configurationPath = "${pkgs.prometheus-snmp-exporter.src}/snmp.yml"; configurationPath = "${pkgs.prometheus-snmp-exporter.src}/snmp.yml";
enableConfigCheck = false; # otherwise module fails to evaluate
}; };
} }

View file

@ -9,17 +9,14 @@
./hardware-configuration.nix ./hardware-configuration.nix
../../modules ../../modules
./services/fuuko-proxy.nix # FIXME!
./services/media.nix ./services/media.nix
./services/murmur.nix
./services/restic.nix ./services/restic.nix
]; ];
sbruder = { sbruder = {
nginx.hardening.enable = true; nginx.hardening.enable = true;
restic = { restic.system.enable = true;
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,5 +1,4 @@
media-sb-proxy-auth: ENC[AES256_GCM,data:TFAS1PXu+jSt/orjYI1ffPbiCMCZgc22tU4coz9eEi7CyEaMvaKuQpgIPwZDBoL3r1yhXd+USya/PjEL9g3SCpuva5EXiJVYjV+mYaTxgrLx,iv:a5da4EuduMVVwEy0p2sz3XuAwdYFt+D9WgOs4oqQg6s=,tag:2BTqxnXIK+sWj/8RXVrYDg==,type:str] media-sb-proxy-auth: ENC[AES256_GCM,data:TFAS1PXu+jSt/orjYI1ffPbiCMCZgc22tU4coz9eEi7CyEaMvaKuQpgIPwZDBoL3r1yhXd+USya/PjEL9g3SCpuva5EXiJVYjV+mYaTxgrLx,iv:a5da4EuduMVVwEy0p2sz3XuAwdYFt+D9WgOs4oqQg6s=,tag:2BTqxnXIK+sWj/8RXVrYDg==,type:str]
murmur-superuser: ENC[AES256_GCM,data:D7EjnKZGSmx8ykVeKqSIAdV4Vql7ZkfEUw==,iv:I8SgiZrlCpyqNeBMJlzttFUJFGqQp5vHu6pMUz/0LoE=,tag:G6QMUh3v2QjxtoXUSoRqcA==,type:str]
restic-htpasswd: ENC[AES256_GCM,data:om9v+FXOEsOPP7LVntiwyqEKmiCLCwcmMgWBeHxcrlosYT4cElX3MHlu+NQAI0TPwc0mAog1tJyRcTfqK7uYszIzd75/Ig==,iv:7UBHmyqt/2hW9Aw1oRMZtZdOij5mjGF/8nmr3PAq/EI=,tag:TNcECUAdGtch8/bHbOJeNw==,type:str] restic-htpasswd: ENC[AES256_GCM,data:om9v+FXOEsOPP7LVntiwyqEKmiCLCwcmMgWBeHxcrlosYT4cElX3MHlu+NQAI0TPwc0mAog1tJyRcTfqK7uYszIzd75/Ig==,iv:7UBHmyqt/2hW9Aw1oRMZtZdOij5mjGF/8nmr3PAq/EI=,tag:TNcECUAdGtch8/bHbOJeNw==,type:str]
restic-rclone-ssh-key: ENC[AES256_GCM,data:fefY4sVBp786LeUNdLA1CZ83YGZsxP9yvoIx647fVM47jGBfJWcU8PDwbPGfp4ae5aKnuRi/+OpRQHQIuBWa8XH8mWQ0YLs3JzKavmtNqf8mh9hyiEGLSYBbokEkgSPFBxH8CuhNbzrou0cCO7ACXkXnq4Cf0jjkYR2StjsISiJ11nEnle0tchHMFPSho0W7Ph8UZvT6x1naJjBqMrZKepLMCrT4oM3gqgA3R0cvCxQyIY5BHweopDXxuZDVlIiYjG61qt6OKL7O+lt/Kfvd38i6L1CAsloFVQOv4pQwz5b/jNjH+Kg8+tbbksXz2Dm5PU7HBXyav48MqriTqVCeWpmEsbo9j/zEravtNaC/gvpc7v4H/3lqhyY181g2Fxzu3YCjheSwjhtSuLCtXCD4UdW5Ctkb5TDZrMY+NAQdeXqgCawYggN05x6s+UdSitXXHLBjvyIV5ES/7p43zjWDnddAsFQEgILffQRobA9y8VZ+Igj7wo+HJLdNnmJtcqL/j6CM4MOT4hvj1CLhhBdr,iv:zYgnXzxGU2XJcjeclQT5bX6M1r5WG+Z0pZI7R4qpUU0=,tag:CbBUooyhUCkmKp+N6j4ySw==,type:str] restic-rclone-ssh-key: ENC[AES256_GCM,data:fefY4sVBp786LeUNdLA1CZ83YGZsxP9yvoIx647fVM47jGBfJWcU8PDwbPGfp4ae5aKnuRi/+OpRQHQIuBWa8XH8mWQ0YLs3JzKavmtNqf8mh9hyiEGLSYBbokEkgSPFBxH8CuhNbzrou0cCO7ACXkXnq4Cf0jjkYR2StjsISiJ11nEnle0tchHMFPSho0W7Ph8UZvT6x1naJjBqMrZKepLMCrT4oM3gqgA3R0cvCxQyIY5BHweopDXxuZDVlIiYjG61qt6OKL7O+lt/Kfvd38i6L1CAsloFVQOv4pQwz5b/jNjH+Kg8+tbbksXz2Dm5PU7HBXyav48MqriTqVCeWpmEsbo9j/zEravtNaC/gvpc7v4H/3lqhyY181g2Fxzu3YCjheSwjhtSuLCtXCD4UdW5Ctkb5TDZrMY+NAQdeXqgCawYggN05x6s+UdSitXXHLBjvyIV5ES/7p43zjWDnddAsFQEgILffQRobA9y8VZ+Igj7wo+HJLdNnmJtcqL/j6CM4MOT4hvj1CLhhBdr,iv:zYgnXzxGU2XJcjeclQT5bX6M1r5WG+Z0pZI7R4qpUU0=,tag:CbBUooyhUCkmKp+N6j4ySw==,type:str]
rspamd-worker-controller: ENC[AES256_GCM,data:STf4vgVsYu6+WfpISKC0L69ixlM+cOiefO4qvHY2gYbV9FirRGxlUIRkmPwk+I6gYxKSC6D8ZTO3Bi2drEuWd8Yhuwjj9Rc1ja7b5UxaT5Q591Iof8S5RbXZKvaWMAQXVeAz4qkBaA==,iv:RzB3EHnzybbYO9E95ianu/Yl+chH7IPomvWG89mIGYU=,tag:yFSx97r/vkf3gVhIxMwcNw==,type:str] rspamd-worker-controller: ENC[AES256_GCM,data:STf4vgVsYu6+WfpISKC0L69ixlM+cOiefO4qvHY2gYbV9FirRGxlUIRkmPwk+I6gYxKSC6D8ZTO3Bi2drEuWd8Yhuwjj9Rc1ja7b5UxaT5Q591Iof8S5RbXZKvaWMAQXVeAz4qkBaA==,iv:RzB3EHnzybbYO9E95ianu/Yl+chH7IPomvWG89mIGYU=,tag:yFSx97r/vkf3gVhIxMwcNw==,type:str]
@ -11,8 +10,8 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-06-01T12:03:28Z" lastmodified: "2023-04-29T10:17:21Z"
mac: ENC[AES256_GCM,data:KFlisFD6k06XqF6SoQTaMNFpIPYtOgHDFArQueGBcTgjfxzdaxA8AVH1ZBeyFeEFlf4EFfduYcfnqAaGWScOvVW+jVhN/InsNkGf7alPyJ2ifzUD9yhe2/gcOF+eZqPvbTfXsdyfyqkbK7kkRyoYC61T3KPnPzTWqDk/3Chm4k8=,iv:lUbhG5/o5iepukcXHs2FYfue04EJdAbfhX1N0e1C9eA=,tag:EvPEDPoRiLXzbWeHAjTMoQ==,type:str] mac: ENC[AES256_GCM,data:UfLbX+4uDg9Kp8v9lnq9RktT4ltpJYwOHBBPRhO79a1AmLXkp6GilaoMJYjkj0foL92vTUK10wIw547omySwJeY52pTGAvw1IXVaxNp395KLlMPl3EwLS3xj4c0bhzcVEyFl/fxG2gk6BJOzvQXaMYo4COEzDdK6ZDGZKZVKEAM=,iv:mR9Nq+s7wHeZdP6/gW9+zJd/wa1Y4Q5saACwnMOFOZQ=,tag:yYYF8/mKnbxzmPa6nWIGbA==,type:str]
pgp: pgp:
- created_at: "2024-01-22T00:20:08Z" - created_at: "2024-01-22T00:20:08Z"
enc: |- enc: |-
@ -83,4 +82,4 @@ sops:
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 4EA330328CD0D3076E90960194DFA4953D8729DE fp: 4EA330328CD0D3076E90960194DFA4953D8729DE
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.8.1 version: 3.7.3

View file

@ -0,0 +1,27 @@
# 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

@ -15,10 +15,7 @@
sbruder = { sbruder = {
nginx.hardening.enable = true; nginx.hardening.enable = true;
full = false; full = false;
wireguard = { wireguard.home.enable = true;
he.enable = true;
home.enable = true;
};
infovhost.enable = true; infovhost.enable = true;
}; };

View file

@ -1,4 +1,3 @@
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]
sops: sops:
kms: [] kms: []
@ -6,8 +5,8 @@ sops:
azure_kv: [] azure_kv: []
hc_vault: [] hc_vault: []
age: [] age: []
lastmodified: "2024-08-28T13:24:49Z" lastmodified: "2024-01-02T22:37:47Z"
mac: ENC[AES256_GCM,data:fKT7rZ1Vid/oo0GRaoTd07Fdq3XqhM8godEck+x0gee9DTdl+kbVJEXejNS1aeyx7WveudrUCTm1y5s0mvRoClyPSgkAXT+UvZ6L+8MxZeInKMT0c5bKNDzJVlzXdNLJ6oQ4Oa1dkhs6dElkkyevb2KT02PRmGYB8hQki3YqdJM=,iv:fZYIDSROMeYj/D6hjiS8vZP566X3m8wcPdMzA+OQyxw=,tag:KqNu8I3AloRvqMnJIQy+zg==,type:str] mac: ENC[AES256_GCM,data:oBfM/DF/TfWJIW1VlvZ4Z+vBQxCmHm8J83pjILtHFBwU14f1H09iIsswY1xyAwO9wO3cttf4xjrSa6mGGUyQFqLdEzj8z/JkCm1vwpLZQW+j8FpRjH1ryyE6G/3eS5tboUZgmAwBPDsulJr3NBi121RHhZvWf1dv2T/J5IcZMxI=,iv://TpDpO8tNaibh8ABqE1AT6CPK62rtUZiFmYP9ST3MA=,tag:5SErG/jDycIdxX3ABOcsow==,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://www.youtube.com/watch?v=ojToYs6nCnk&t=1684'"; locations."~ .*".return = "303 'https://iv.sbruder.xyz/watch?v=ojToYs6nCnk&t=1684'";
}; };
"www.brennende.autos" = { "www.brennende.autos" = {
enableACME = true; enableACME = true;
@ -18,10 +18,6 @@
globalRedirect = "https://brennende.autos/"; globalRedirect = "https://brennende.autos/";
}; };
"share.sbruder.de".locations."= /".extraConfig = ''
autoindex off;
'';
}; };
sbruder.static-webserver.vhosts = { sbruder.static-webserver.vhosts = {
@ -49,29 +45,10 @@
"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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later

View file

@ -1,64 +1,36 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2022 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
let let
printersPerServer = { gutenprintWithVersion = "gutenprint.${lib.versions.majorMinor (lib.getVersion pkgs.gutenprint)}";
fuuko = [
{
name = "etikettierviech";
deviceUri = "usb://SII/SLP650?serial=32152867B0";
model = "seiko/siislp650.ppd.gz";
}
];
};
in in
{ lib.mkIf config.sbruder.gui.enable {
options.sbruder.printing = { services = {
server.enable = lib.mkEnableOption "printing server"; printing = {
client.enable = (lib.mkEnableOption "printing client") // { default = config.sbruder.gui.enable; };
};
config = lib.mkMerge [
(lib.mkIf (config.sbruder.printing.client.enable || config.sbruder.printing.server.enable) {
services.printing = {
enable = true; enable = true;
drivers = with pkgs; [ drivers = with pkgs; [
cups-sii-slp-400-600
gutenprint gutenprint
]; ] ++ lib.optional config.sbruder.unfree.allowSoftware (cups-kyocera-ecosys-m552x-p502x.override {
# in Kyocera terms, EU means duplex enabled by default
region = "EU";
});
}; };
}) avahi.enable = true;
(lib.mkIf config.sbruder.printing.server.enable {
services.printing = {
stateless = true;
startWhenNeeded = false; # cups.socket interferes with cups.service (cups.socket binds to IPv4, so cups.service can only bind to IPv6)
listenAddresses = [ "*:631" ];
allowFrom = [ "all" ];
openFirewall = true;
defaultShared = true;
extraConf = ''
ServerAlias fuuko.lan.shinonome-lab.de
'';
}; };
hardware.printers.ensurePrinters = printersPerServer.${config.networking.hostName};
})
(lib.mkIf config.sbruder.printing.client.enable {
services.avahi.enable = true;
hardware.printers.ensurePrinters = [ hardware.printers.ensurePrinters = [
{ {
name = "etikettierviech"; name = "ich_drucke_nicht";
model = "everywhere"; deviceUri = "socket://192.168.178.26";
deviceUri = "ipps://fuuko.lan.shinonome-lab.de:631/printers/etikettierviech"; model = "${gutenprintWithVersion}://bjc-TS3100-series/expert";
description = "SII SLP 650";
} }
] ++ lib.optionals config.sbruder.unfree.allowSoftware [
{ {
name = "bro"; name = "elma";
model = "everywhere"; deviceUri = "socket://elma.fritz.box";
deviceUri = "ipps://bro.printer.shinonome-lab.de"; model = "Kyocera/Kyocera ECOSYS P5021cdn.PPD";
description = "brother DCP-L2660DW";
} }
]; ];
})
];
} }

View file

@ -33,6 +33,7 @@
./ausweisapp.nix ./ausweisapp.nix
./authoritative-dns.nix ./authoritative-dns.nix
./cups.nix ./cups.nix
./docker.nix
./fancontrol.nix ./fancontrol.nix
./flatpak.nix ./flatpak.nix
./fonts.nix ./fonts.nix
@ -41,12 +42,12 @@
./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
./media-mount.nix ./media-mount.nix
./media-proxy.nix ./media-proxy.nix
./mullvad
./network-manager.nix ./network-manager.nix
./nginx-interactive-index ./nginx-interactive-index
./nginx.nix ./nginx.nix
@ -54,9 +55,7 @@
./nix.nix ./nix.nix
./office.nix ./office.nix
./pipewire.nix ./pipewire.nix
./podman.nix
./prometheus/node_exporter.nix ./prometheus/node_exporter.nix
./prometheus/smartctl_exporter.nix
./pubkeys.nix ./pubkeys.nix
./qbittorrent ./qbittorrent
./restic ./restic
@ -81,11 +80,9 @@
git-lfs # not so essential, but required to clone config git-lfs # not so essential, but required to clone config
htop htop
tmux tmux
vim
]; ];
programs.nano.enable = false;
programs.vim.defaultEditor = true;
# Clean temporary files on boot # Clean temporary files on boot
boot.tmp.cleanOnBoot = true; boot.tmp.cleanOnBoot = true;
@ -113,8 +110,6 @@
# Support for exotic file systems # Support for exotic file systems
boot.supportedFilesystems = lib.optional config.sbruder.full "ntfs"; boot.supportedFilesystems = lib.optional config.sbruder.full "ntfs";
programs.ssh.startAgent = lib.mkDefault (!config.sbruder.gui.enable);
# When this is set to true (default), routing everything through a # When this is set to true (default), routing everything through a
# wireguard tunnel does not work. # wireguard tunnel does not work.
networking.firewall.checkReversePath = false; networking.firewall.checkReversePath = false;
@ -166,8 +161,8 @@
(lib.mkIf (!config.sbruder.machine.isVm) { (lib.mkIf (!config.sbruder.machine.isVm) {
# Hard drive monitoring # Hard drive monitoring
services.smartd.enable = lib.mkDefault true; services.smartd.enable = lib.mkDefault true;
# Firmware updates (only work on EFI systems, so enable only when using systemd-boot) # Firmware updates
services.fwupd.enable = lib.mkDefault (config.boot.loader.systemd-boot.enable); services.fwupd.enable = lib.mkDefault true;
}) })
(lib.mkIf (!config.sbruder.full) { (lib.mkIf (!config.sbruder.full) {
documentation.enable = lib.mkDefault false; documentation.enable = lib.mkDefault false;

47
modules/docker.nix Normal file
View file

@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: 2020-2021 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
{
# This uses a custom option (instead of `virtualisation.docker.enable`) since
# `virtualisation.oci-containers` conditionally sets
# `virtualisation.docker.enable` and therefore causes an infinite recursion.
options.sbruder.docker.enable = lib.mkEnableOption "docker with ipv6nat";
config = lib.mkIf config.sbruder.docker.enable {
environment.systemPackages = with pkgs; [
docker-compose
docker-credential-helpers
docker-ls
];
virtualisation = {
docker = {
enable = true;
logDriver = "journald";
extraOptions = lib.concatStringsSep " " [
"--ipv6"
"--fixed-cidr-v6=fd00:d0ce:d0ce:d0ce::/64"
];
};
oci-containers.containers.ipv6nat = {
image = "robbertkl/ipv6nat";
volumes = [
"/var/run/docker.sock:/var/run/docker.sock:ro"
];
extraOptions = [
"--network=host"
"--cap-drop=ALL"
"--cap-add=NET_ADMIN"
"--cap-add=NET_RAW"
"--cap-add=SYS_MODULE"
];
};
};
environment.etc."modules-load.d/ipv6nat.conf".text = "ip6_tables\n";
};
}

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -9,15 +9,15 @@ let
family = "Iosevka sbruder"; family = "Iosevka sbruder";
spacing = "term"; spacing = "term";
serifs = "sans"; serifs = "sans";
noCvSs = false; no-cv-ss = false;
exportGlyphNames = true; export-glyph-names = true;
variants = { variants = {
inherits = "ss20"; inherits = "ss20";
design = { design = {
capital-g = "toothless-rounded-serifless-hooked"; capital-g = "toothless-rounded-serifless-hooked";
four = "closed-serifless"; four = "closed";
six = "closed-contour"; six = "closed-contour";
nine = "closed-contour"; nine = "closed-contour";
number-sign = "upright-tall"; number-sign = "upright-tall";

View file

@ -1,32 +0,0 @@
# 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,12 +69,6 @@ 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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2021-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -38,13 +38,7 @@ lib.mkIf cfg.enable {
Spam = { specialUse = "Junk"; auto = "subscribe"; }; Spam = { specialUse = "Junk"; auto = "subscribe"; };
}; };
mailPlugins.perProtocol = { sieveScripts = {
imap.enable = [ "imap_sieve" ];
lmtp.enable = [ "sieve" ];
};
sieve = {
scripts = {
before = pkgs.writeText "spam.sieve" '' before = pkgs.writeText "spam.sieve" ''
require "fileinto"; require "fileinto";
@ -53,44 +47,6 @@ lib.mkIf cfg.enable {
} }
''; '';
}; };
extensions = [ "fileinto" ];
pipeBins = lib.mkIf cfg.spam.enable [
"${pkgs.rspamd}/bin/rspamc"
];
};
imapsieve.mailbox = lib.mkIf cfg.spam.enable [
{
name = "Spam";
causes = [ "COPY" ];
before = pkgs.writeText "learn-spam.sieve" ''
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_spam"];
'';
}
{
name = "*";
from = "Spam";
causes = [ "COPY" ];
before = pkgs.writeText "learn-ham.sieve" ''
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "''${1}";
}
if string "''${mailbox}" "Trash" {
stop;
}
pipe :copy "rspamc" ["learn_ham"];
'';
}
];
pluginSettings = {
sieve = "file:/var/lib/sieve/%d/%n/scripts;active=/var/lib/sieve/%d/%n/active.sieve";
};
extraConfig = '' extraConfig = ''
# generated 2021-02-04, Mozilla Guideline v5.6, Dovecot 2.3.13, OpenSSL 1.1.1i, intermediate configuration # generated 2021-02-04, Mozilla Guideline v5.6, Dovecot 2.3.13, OpenSSL 1.1.1i, intermediate configuration
@ -100,6 +56,14 @@ lib.mkIf cfg.enable {
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl_prefer_server_ciphers = no ssl_prefer_server_ciphers = no
protocol imap {
mail_plugins = $mail_plugins imap_sieve
}
protocol lmtp {
mail_plugins = $mail_plugins sieve
}
service imap-login { service imap-login {
inet_listener imap { inet_listener imap {
} }
@ -134,6 +98,25 @@ lib.mkIf cfg.enable {
lda_mailbox_autosubscribe = yes lda_mailbox_autosubscribe = yes
lda_mailbox_autocreate = yes lda_mailbox_autocreate = yes
plugin {
sieve_plugins = sieve_imapsieve sieve_extprograms
sieve = file:/var/lib/sieve/%d/%n/scripts;active=/var/lib/sieve/%d/%n/active.sieve
${lib.optionalString cfg.spam.enable ''
imapsieve_mailbox1_name = Spam
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/var/lib/dovecot/sieve/learn-spam.sieve
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Spam
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/var/lib/dovecot/sieve/learn-ham.sieve
sieve_pipe_bin_dir = ${pkgs.symlinkJoin { name = "sieve-pipe-bin-dir"; paths = with pkgs; [ rspamd ]; } }/bin
''}
sieve_global_extensions = +vnd.dovecot.pipe
}
service managesieve-login { service managesieve-login {
inet_listener sieve { inet_listener sieve {
port = 4190 port = 4190
@ -144,6 +127,33 @@ lib.mkIf cfg.enable {
systemd.services.dovecot2 = { systemd.services.dovecot2 = {
wants = [ "acme-finished-${cfg.fqdn}.target" ]; wants = [ "acme-finished-${cfg.fqdn}.target" ];
after = [ "acme-finished-${cfg.fqdn}.target" ]; after = [ "acme-finished-${cfg.fqdn}.target" ];
preStart = lib.mkIf cfg.spam.enable
(lib.mkAfter
(lib.concatStrings
(lib.mapAttrsToList
(name: content: ''
cp ${pkgs.writeText name content} /var/lib/dovecot/sieve/${name}
'')
{
"learn-spam.sieve" = ''
require ["vnd.dovecot.pipe", "copy", "imapsieve"];
pipe :copy "rspamc" ["learn_spam"];
'';
"learn-ham.sieve" = ''
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "''${1}";
}
if string "''${mailbox}" "Trash" {
stop;
}
pipe :copy "rspamc" ["learn_ham"];
'';
})));
}; };
networking.firewall.allowedTCPPorts = [ networking.firewall.allowedTCPPorts = [

View file

@ -39,11 +39,10 @@ let
cfg.cleanHeaders); cfg.cleanHeaders);
in in
lib.mkIf cfg.enable { lib.mkIf cfg.enable {
security.dhparams.params.postfix = { };
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)
@ -56,20 +55,6 @@ 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 = {
@ -102,21 +87,6 @@ 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";
@ -138,6 +108,8 @@ lib.mkIf cfg.enable {
"DHE-RSA-AES256-GCM-SHA384" "DHE-RSA-AES256-GCM-SHA384"
]; ];
tls_preempt_cipherlist = "no"; tls_preempt_cipherlist = "no";
smtpd_tls_dh1024_param_file = config.security.dhparams.params.postfix.path;
}; };
# plain/STARTTLS (forced with smtpd_tls_security_level) # plain/STARTTLS (forced with smtpd_tls_security_level)
@ -156,7 +128,9 @@ lib.mkIf cfg.enable {
"reject" "reject"
]; ];
smtpd_sender_restrictions = "$submission_sender_restrictions"; smtpd_sender_restrictions = listToString [
"reject_sender_login_mismatch"
];
cleanup_service_name = "submission-header-cleanup"; cleanup_service_name = "submission-header-cleanup";
}; };

View file

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -23,7 +23,6 @@ in
# otherwise name resolution fails # otherwise name resolution fails
systemd.services.nginx.after = [ "network-online.target" ]; systemd.services.nginx.after = [ "network-online.target" ];
systemd.services.nginx.wants = [ "network-online.target" ];
services.nginx = { services.nginx = {
enable = true; enable = true;
commonHttpConfig = '' commonHttpConfig = ''

View file

@ -0,0 +1,66 @@
# SPDX-FileCopyrightText: 2021-2022 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
let
relays = builtins.fromJSON (builtins.readFile ./relays.json);
cfg = config.sbruder.mullvad;
relayConfigs = lib.mapAttrs'
(name: configuration: lib.nameValuePair "mlv-${name}.conf" (with configuration; ''
[Interface]
DNS = ${cfg.dnsServer}
[Peer]
Endpoint = ${if cfg.ipVersion == 4 then endpoint4 else endpoint6}:${toString cfg.port}
PublicKey = ${pubkey}
AllowedIPs = 0.0.0.0/0,::0/0
''))
relays;
# Creating 100+ files in a separate derivation each has too much overhead
relayConfigFiles = pkgs.runCommandNoCC "etc-wireguard-mullvad" { } (''
mkdir $out
'' + (lib.concatStringsSep
"\n"
(lib.mapAttrsToList
(name: content: ''
cat > $out/${lib.escapeShellArg name} << EOF
${content}
EOF
'')
relayConfigs)));
in
{
options.sbruder.mullvad = {
enable = lib.mkEnableOption "wg-quick compatible configuration files in /etc/wireguard for Mullvad VPN";
dnsServer = lib.mkOption {
type = lib.types.str;
default = "193.138.218.74";
};
ipVersion = lib.mkOption {
type = lib.types.enum [ 4 6 ];
default = 4;
};
port = lib.mkOption {
type = lib.types.port;
default = 51820;
};
};
config = lib.mkIf cfg.enable {
environment = {
etc = builtins.listToAttrs
(map
(name: lib.nameValuePair "wireguard/${name}" { source = "${relayConfigFiles}/${name}"; })
(lib.attrNames relayConfigs));
systemPackages = lib.singleton (pkgs.runCommandNoCC "mullvad-on-demand" { } ''
install -D ${./mullvad.sh} $out/bin/mullvad
install -D ${./mullvad-fzf.sh} $out/bin/mullvad-fzf
'');
};
};
}

7
modules/mullvad/mullvad-fzf.sh Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2022 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
mullvad $(find /etc/wireguard -name "mlv-*.conf" -printf "%f\n" | sed 's/mlv-\(.*\)\.conf/\1/' | fzf)

65
modules/mullvad/mullvad.sh Executable file
View file

@ -0,0 +1,65 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2021-2022 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# This reads wg-quick compatible configuration files from
# /etc/wireguard/mlv-LOCATION.conf
#
# Since they are autogenerated by nix and therefore world-readable, they do not
# include secrets like the private key and client address. Instead, they are
# manually added after wg-quick set up the tunnel by retrieving them with
# pass(1) from web/mullvad.net/wireguard.
#
# Format of pass entry:
# PrivateKey: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=
# Address4: 10.0.0.1/32
# Address6: fd00::1/128
set -euo pipefail
if (( $# < 1 )); then
echo "USAGE: $0 LOCATION|off" >&2
exit 1
fi
INTERFACE="mlv-$1"
cmd() {
echo "[#] $*" >&2
sudo "$@"
}
for interface in /sys/class/net/*; do
interface="${interface#/sys/class/net/}"
[[ $interface =~ ^mlv-(v6-)?[a-z]{2}(-[a-z]{3}-)?[0-9]*$ ]] && cmd wg-quick down "$interface"
done
if [ "$1" != "off" ]; then
# Make sure gpg-agent is unlocked so the period where the interface exists but
# no private key is set is minised.
pass web/mullvad.net/wireguard >/dev/null
cmd wg-quick up "$INTERFACE"
pass web/mullvad.net/wireguard | while read -r line; do
key="${line%%: *}"
value="${line#*: }"
case "$key" in
PrivateKey)
cmd wg set "$INTERFACE" private-key /dev/stdin <<< "$value"
continue
;;
Address4)
cmd ip -4 address add "$value" dev "$INTERFACE"
continue
;;
Address6)
cmd ip -6 address add "$value" dev "$INTERFACE"
continue
;;
*)
echo "Invalid key '$key'"
exit 1
esac
done
fi

2077
modules/mullvad/relays.json Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2021-2023 Mullvad VPN AB
SPDX-License-Identifier: CC0-1.0

17
modules/mullvad/update.sh Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: 2021-2022 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# This gets the current wireguard relay list from mullvads API and transforms
# it into a format that takes up less space than the original response.
set -euo pipefail
curl -s 'https://api.mullvad.net/www/relays/wireguard/' | jq '. | map({
key: (if .hostname | endswith("-wireguard") then .hostname | split("-")[0] else .hostname | sub("-wg-"; "-") end),
value: {
endpoint4: .ipv4_addr_in,
endpoint6: .ipv6_addr_in,
pubkey: .pubkey
}
}) | from_entries' > relays.json

View file

@ -11,14 +11,6 @@ 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 [
@ -35,12 +27,9 @@ in
''; '';
}) })
(lib.mkIf cfg.privacy.enable { (lib.mkIf cfg.privacy.enable {
services.nginx = { services.nginx.commonHttpConfig = ''
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 = {
@ -50,22 +39,5 @@ 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

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
@ -25,12 +25,16 @@ let
in in
{ {
nix = { nix = {
channel.enable = false;
registry = with inputs; { registry = with inputs; {
nixpkgs.flake = nixpkgs;
nixpkgs-unstable.flake = nixpkgs-unstable; nixpkgs-unstable.flake = nixpkgs-unstable;
}; };
nixPath = [
"nixpkgs=${inputs.nixpkgs}"
"nixpkgs-overlays=${overlaysCompat}"
];
settings = { settings = {
# Make sudoers trusted nix users # Make sudoers trusted nix users
trusted-users = [ "@wheel" ]; trusted-users = [ "@wheel" ];
@ -39,13 +43,6 @@ in
auto-optimise-store = true; auto-optimise-store = true;
experimental-features = "nix-command flakes"; experimental-features = "nix-command flakes";
# nix.nixPath does not work when nix.channel.enable == false (for some reason)
nix-path = [
"nixpkgs-overlays=${overlaysCompat}"
"nixpkgs=flake:nixpkgs"
"nixpkgs-unstable=flake:nixpkgs-unstable"
];
} // (lib.optionalAttrs config.sbruder.full { } // (lib.optionalAttrs config.sbruder.full {
# Keep output of derivations with gc root # Keep output of derivations with gc root
keep-outputs = true; keep-outputs = true;

View file

@ -1,30 +0,0 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, pkgs, ... }:
{
options.sbruder.podman.enable = lib.mkEnableOption "podman";
config = lib.mkIf config.sbruder.podman.enable {
boot.enableContainers = false; # FIXME: this only needs to be set for some stateVersions
environment.systemPackages = with pkgs; [
buildah
passt # required by buildah by default
podman-compose
skopeo
];
virtualisation = {
podman = {
enable = true;
dockerSocket.enable = true;
defaultNetwork.settings = {
ipv6_enabled = true;
};
};
};
};
}

View file

@ -1,22 +0,0 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
{ config, lib, ... }:
lib.mkIf (config.sbruder.wireguard.home.enable && !config.sbruder.machine.isVm) {
services.prometheus.exporters.smartctl = {
enable = true;
listenAddress = config.sbruder.wireguard.home.address;
# devices need to be specified for all systems that use NVMe
# https://github.com/NixOS/nixpkgs/issues/210041
};
systemd.services.prometheus-smartctl-exporter = {
after = [ "wireguard-wg-home.service" ];
serviceConfig = {
IPAddressAllow = lib.singleton config.sbruder.wireguard.home.subnet;
IPAddressDeny = "any";
};
};
}

View file

@ -12,6 +12,10 @@ 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
@ -21,6 +25,9 @@ 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,139 +1,9 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2021 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

@ -1,11 +1,14 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2023 Simon Bruder <simon@sbruder.de>
# #
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
{ pkgs, config, lib, ... }: { pkgs, config, lib, ... }:
let let
cfg = config.sbruder.restic.backups.system; cfg = config.sbruder.restic.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/"
@ -25,8 +28,6 @@ let
"/home/*/mounts" "/home/*/mounts"
# Docker (state should be kept somewhere else) # Docker (state should be kept somewhere else)
"/home/*/.local/share/containers" # podman
"/var/lib/containers/"
"/var/lib/docker/" "/var/lib/docker/"
# Static configuration (generated from this repository) # Static configuration (generated from this repository)
@ -34,6 +35,14 @@ 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.
@ -54,8 +63,8 @@ let
''; '';
in in
{ {
options.sbruder.restic.backups.system = { options.sbruder.restic.system = {
enable = lib.mkEnableOption "restic system backup"; enable = lib.mkEnableOption "restic";
timerConfig = lib.mkOption { timerConfig = lib.mkOption {
type = with lib.types; attrsOf str; type = with lib.types; attrsOf str;
default = { default = {
@ -76,10 +85,20 @@ 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 = !(isNull cfg.uploadLimit); }; qos = (lib.mkEnableOption "QoS marking (DSCP AF12) of outgoing packets") // { default = !(lib.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;
@ -98,14 +117,13 @@ 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;
@ -113,5 +131,32 @@ 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

@ -1,84 +0,0 @@
# 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,6 +26,7 @@
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";
@ -86,21 +87,5 @@
hostNames = [ "[yuzuru.sbruder.de]:2222" ]; hostNames = [ "[yuzuru.sbruder.de]:2222" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAcvbbHSK7x9t0Jpr4L55RTC4WRNJIgKZ1B+99PhpSX8"; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAcvbbHSK7x9t0Jpr4L55RTC4WRNJIgKZ1B+99PhpSX8";
}; };
koyomi = {
hostNames = [ "koyomi" "koyomi.sbruder.de" "koyomi.vpn.sbruder.de" ];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP6KAN4FJoCLciJ14W9dSbfsObc8GLIP/dhG5kHiHm8B";
};
koyomi-initrd = {
hostNames = [ "[koyomi.sbruder.de]:2222" ];
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

@ -48,7 +48,6 @@
dmidecode # hardware information dmidecode # hardware information
hdparm # hard drive management hdparm # hard drive management
lm_sensors # temperature sensors lm_sensors # temperature sensors
nvme-cli # NVMe management
parted # partition manager parted # partition manager
pciutils # lspci pciutils # lspci
(reptyr.overrideAttrs (o: o // { doCheck = false; })) # move process to current terminal # tests fail on qemu-user-aarch64 (TODO 24.05: remove) (reptyr.overrideAttrs (o: o // { doCheck = false; })) # move process to current terminal # tests fail on qemu-user-aarch64 (TODO 24.05: remove)

View file

@ -1,10 +1,9 @@
# SPDX-FileCopyrightText: 2020-2024 Simon Bruder <simon@sbruder.de> # SPDX-FileCopyrightText: 2020-2023 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
]; ];

View file

@ -1,120 +0,0 @@
# 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

@ -48,14 +48,6 @@ let
address = "10.80.0.16"; address = "10.80.0.16";
publicKey = "sRTAhbGVfxLqYaWr6uwnPJPphu6Cikpj2aXwNrhV5DU="; publicKey = "sRTAhbGVfxLqYaWr6uwnPJPphu6Cikpj2aXwNrhV5DU=";
}; };
koyomi = {
address = "10.80.0.17";
publicKey = "fvQDGqmkcFUvfUFmkSagJZy6pGIP6ewZrzTQfaz+mmE=";
};
hiroshi = {
address = "10.80.0.18";
publicKey = "eXbRmOcRRJpcgGb0Ztuw6t83K6QKtd+exWTbKCjmXQw=";
};
}; };
cfg = config.sbruder.wireguard.home; cfg = config.sbruder.wireguard.home;

View file

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

Binary file not shown.

View file

@ -24,7 +24,6 @@
./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
{ lib, nixosConfig, pkgs, ... }: { nixosConfig, pkgs, ... }:
{ {
programs.gpg = { programs.gpg = {
@ -18,9 +18,9 @@
services.gpg-agent = rec { services.gpg-agent = rec {
enable = true; enable = true;
enableZshIntegration = true; enableZshIntegration = true;
enableSshSupport = lib.mkDefault nixosConfig.sbruder.gui.enable; enableSshSupport = true;
pinentryPackage = if nixosConfig.sbruder.gui.enable then pkgs.pinentry-qt else pkgs.pinentry-curses; pinentryFlavor = if nixosConfig.sbruder.gui.enable then "gnome3" else "curses";
defaultCacheTtl = 300; defaultCacheTtl = 300;
defaultCacheTtlSsh = defaultCacheTtl; defaultCacheTtlSsh = defaultCacheTtl;

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