Compare commits

...

225 Commits

Author SHA1 Message Date
Oystein Kristoffer Tveit 5242d99260
bekkalokk/gitea: add gpg signing key 2024-11-24 03:23:54 +01:00
Fredrik Robertsen c60597dc5a Merge pull request 'Let smartd send mail notification' (!92) from add-mail-to-smartd into main
Reviewed-on: #92
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>

Closes #92
2024-11-24 01:09:58 +01:00
Fredrik Robertsen 69462bf486 let smartd send mail notification 2024-11-24 01:01:55 +01:00
Oystein Kristoffer Tveit 7d4ccf1972 Merge pull request 'Add user frero' (!91) from add-user-frero into main
Reviewed-on: #91
2024-11-23 22:40:43 +01:00
Fredrik Robertsen c87a81eeee users: add `frero` 2024-11-23 22:39:53 +01:00
Daniel Lovbrotte Olsen 3bdfb4c297 Add function to make paths from flake root
No more ../../../../../../
2024-11-17 00:08:02 +01:00
Felix Albrigtsen 8285d91401 Merge pull request 'Ildkule: Move monitoring state directories to data volume' (!88) from ildkule-data-volume into main
Reviewed-on: #88
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-11-10 02:30:11 +01:00
Alf Helge Jakobsen b07cd5fbf6 systemd hardening for pvv-nettsiden-gallery-update.service (!90)
#133

Reviewed-on: #90
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
Co-authored-by: Alf Helge Jakobsen <alfhj@stud.ntnu.no>
Co-committed-by: Alf Helge Jakobsen <alfhj@stud.ntnu.no>
2024-11-09 22:22:09 +01:00
Felix Albrigtsen 2d52ebce52 Ildkule: hardware-config: use UUIDs 2024-11-09 21:42:44 +01:00
Oystein Kristoffer Tveit 464576e856
flake.lock: bump greg-ng 2024-11-09 19:43:07 +01:00
Oystein Kristoffer Tveit df35715978 Merge pull request 'Add alfhj.nix' (!89) from newusersconfig into main
Reviewed-on: #89
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-11-09 19:40:03 +01:00
Alf Helge Jakobsen 165ff56948 Add alfhj.nix 2024-11-09 19:35:19 +01:00
Felix Albrigtsen 11f6ef0572 Ildkule: Move monitoring state directories to data volume 2024-11-09 15:21:12 +01:00
Oystein Kristoffer Tveit 815f48c30d
flake.lock: bump greg-ng 2024-10-22 19:50:29 +02:00
Oystein Kristoffer Tveit 4985bac3ba
flake.lock: bump greg-ng 2024-10-20 23:18:35 +02:00
Oystein Kristoffer Tveit 9e41c3374d Merge pull request 'bekkalokk/nginx: host `.well-known`' (!79) from move-well-known-to-bekkalokk into main
Reviewed-on: #79
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-10-20 01:35:22 +02:00
Oystein Kristoffer Tveit f39fee4213
bekkalokk/nginx: host `.well-known` 2024-10-20 01:34:41 +02:00
Oystein Kristoffer Tveit 4c77c9fc67 Merge pull request 'greg-ng 🎉' (!86) from greg-ng-working-branch into main
Reviewed-on: #86
Reviewed-by: Felix Albrigtsen <felixalb@pvv.ntnu.no>
2024-10-20 01:30:26 +02:00
Oystein Kristoffer Tveit 7938e8135f
flake.lock: bump 2024-10-19 23:31:29 +02:00
Oystein Kristoffer Tveit cbc3490882
modules/grzegorz: use greg-ng 2024-10-19 23:31:28 +02:00
Daniel Lovbrotte Olsen 47ed79986c bicep/matrix: use sops templates for appservice registrations 2024-10-14 15:46:58 +02:00
Daniel Lovbrotte Olsen 5aed665cc8 flake update 2024-10-14 00:24:29 +02:00
Daniel Lovbrotte Olsen 2c86a2d812 bicep/matrix/hookshot: More configuration 2024-10-14 00:13:15 +02:00
Daniel Lovbrotte Olsen d4fd3f8332 bicep/matrix/hookshot: add nginx 2024-10-13 06:03:26 +02:00
Joakim Pettersvold c1833eb07c bicep/matrix/hookshot: Configure matrix-hookshot
Co-authored-by: Daniel Olsen <daniel.olsen99@gmail.com>
2024-10-13 05:50:22 +02:00
Finn Landweber 5ee23ef2e2 bicep/matrix/hookshot: Backported from nixpkgs
Co-authored-by: Joakim Pettersvold <joakimpokemeg@hotmail.no>
2024-10-13 05:50:22 +02:00
Oystein Kristoffer Tveit f5c16f46f1 Merge pull request 'disable-postgres-on-bekkalokk' (!85) from disable-postgres-on-bekkalokk into main
Reviewed-on: #85
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-10-13 02:34:45 +02:00
Oystein Kristoffer Tveit aa71d497f1
bekkalokk/roundcube: add postgres password 2024-10-12 23:57:27 +02:00
Daniel Lovbrotte Olsen c56d157c3f add registration secret 2024-10-12 23:49:10 +02:00
fredrikr79 4fbd823be6 bekkalokk/roundcube: add `database.host` 2024-10-12 22:53:42 +02:00
Daniel Lovbrotte Olsen 6c9e651e59 bekkalokk/gitea: Add important emoji reactions 2024-10-12 22:42:59 +02:00
Adrian Gunnar Lauterer f56e73548c base: openssh fix 2024-10-12 22:32:18 +02:00
Adrian Gunnar Lauterer c62ea129ed Merge pull request 'base openssh added sleipner ssh keys' (!83) from sleipner-authorised-keys into main
Reviewed-on: #83
2024-10-12 21:48:08 +02:00
Adrian Gunnar Lauterer 4b41ddcf5d base: openssh added sleipner ssh keys 2024-10-12 21:47:31 +02:00
Daniel Lovbrotte Olsen abec66b287 users/danio: add to wheel 2024-10-08 14:08:17 +02:00
Felix Albrigtsen aa884353c7 Merge pull request 'Add ipv6 gateway' (!82) from ipv6-fix into main
Reviewed-on: #82
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-09-28 21:44:55 +02:00
Felix Albrigtsen 2147b56864 Add ipv6 gateway 2024-09-28 21:35:57 +02:00
Daniel Lovbrotte Olsen a7fe2aabc5 bicep/matrix/coturn: disable ipv6 to fix the service running at all
coturn is just fundamentally broken, look at trying eturnal instead
2024-09-27 07:30:48 +02:00
Daniel Lovbrotte Olsen cd23e35aac bicep/matrix: update module and remove deprecated options 2024-09-27 06:38:12 +02:00
Peder Bergebakken Sundt 06668cda79 Merge pull request 'flake.lock: Update' (!81) from sounding into main
Reviewed-on: #81
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-09-21 22:19:36 +02:00
Peder Bergebakken Sundt 2861f939b7 Merge pull request 'auto-upgrade: store flake input refs' (!80) from retain-flake-inputs into main
Reviewed-on: #80
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-09-21 22:19:18 +02:00
Peder Bergebakken Sundt 166b80988a flake.lock: Update
Flake lock file updates:

• Updated input 'grzegorz':
    'github:Programvareverkstedet/grzegorz/0481aef6553ae9aee86e4edb4ca0ed4f2eba2058' (2024-05-18)
  → 'git+https://git.pvv.ntnu.no/Projects/grzegorz.git?ref=refs/heads/master&rev=d10db19d7df5c5c2cd2dcb878376d5d681f6c2f2' (2024-09-20)
• Updated input 'grzegorz/fix-python':
    'github:GuillaumeDesforges/fix-python/f7f4b33e22414071fc1f9cbf68072c413c3a7fdf' (2024-04-23)
  → 'github:GuillaumeDesforges/fix-python/2926402234c3f99aa8e4608c51d9ffa73ea403c0' (2024-09-04)
• Updated input 'grzegorz-clients':
    'github:Programvareverkstedet/grzegorz-clients/b9444658fbb39cd1bf1c61ee5a1d5f0641c49abe' (2024-05-19)
  → 'git+https://git.pvv.ntnu.no/Projects/grzegorz-clients.git?ref=refs/heads/master&rev=546d921ec46735dbf876e36f4af8df1064d09432' (2024-09-20)
2024-09-20 22:49:19 +02:00
Peder Bergebakken Sundt 4913b22ab9 auto-upgrade: store flake input refs 2024-09-16 02:51:20 +02:00
Peder Bergebakken Sundt 4e81647fb6 auto-upgrade: `--update-input` -> `--override-input` 2024-09-15 19:14:03 +02:00
Felix Albrigtsen 5a76b62700 Merge pull request 'add gitea metrics' (!78) from gitea-metric into main
Reviewed-on: #78
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-09-14 20:33:28 +02:00
Felix Albrigtsen 0f77a42e34 Grafana: Add Gitea Dashbaord [sic] 2024-09-14 20:28:35 +02:00
Felix Albrigtsen c64d28fc26 Prometheus: Monitor gitea metrics 2024-09-14 20:21:12 +02:00
Dung-Bai Yen 179d0743ce gitea: export metric issue #101 2024-09-14 19:26:25 +02:00
Daniel Lovbrotte Olsen 47fa3759c3 buskerud: remove
This is now a proxmox machine :grr:
2024-09-05 18:00:42 +02:00
Daniel Lovbrotte Olsen 3a37fefd4d fixup! Merge pull request 'Fix Ildkule/Openstack networking' (!75) from fix-openstack-networking into main 2024-09-05 14:24:40 +02:00
Daniel Lovbrotte Olsen 47d7b88a05 ildkule/prometheus: consolidate scrape jobs and label with hostname for base info 2024-09-05 14:14:28 +02:00
Daniel Lovbrotte Olsen 78456063ba Merge pull request 'Fix Ildkule/Openstack networking' (!75) from fix-openstack-networking into main
Reviewed-on: #75
2024-09-05 01:58:50 +02:00
Felix Albrigtsen ca287b95c9 Ildkule/openstack: fix networking
Removes systemd-networkd, and configures proper ipv4 and ipv6 in
openstack.
2024-09-05 00:24:22 +02:00
Daniel Lovbrotte Olsen 7e95b77e15 grzegorz: follow stable nix channel
It broke because sanic
2024-09-03 13:28:13 +02:00
Daniel Lovbrotte Olsen 669733309b ildkule: get systemd stats from more machines 2024-09-03 13:10:36 +02:00
Daniel Lovbrotte Olsen 4ed12573ff ildkule: fix system activation by disabling smartd 2024-09-03 13:07:58 +02:00
Daniel Lovbrotte Olsen 8418cc016c fix biceps systemd units failing on activation 2024-09-03 13:00:12 +02:00
Daniel Lovbrotte Olsen b4c602e31c metrics: install systemd exporter 2024-09-02 23:12:24 +02:00
Daniel Lovbrotte Olsen 3a0b8e270d bekkalokk/idp: Disallow bots 2024-09-02 23:11:44 +02:00
Daniel Lovbrotte Olsen 9505223dc9 justfile: fix flake input updating 2024-09-02 19:33:15 +02:00
Daniel Lovbrotte Olsen 201784fa21 bluemap on bekkalokk 💀 2024-09-02 15:11:32 +02:00
Daniel Lovbrotte Olsen ccefcb01fa flake.lock update 2024-09-02 14:12:39 +02:00
Daniel Lovbrotte Olsen f7e2c74f89 base: enable rebuilding nixos-config without updating the channels used 2024-09-01 22:10:58 +02:00
Felix Albrigtsen 161265d346 Bekkalokk/Nettsiden: deploy #78 2024-09-01 20:13:56 +02:00
Oystein Kristoffer Tveit f85d18769f
common: clean `/tmp` on boot by default 2024-09-01 03:29:46 +02:00
Oystein Kristoffer Tveit b47a626427
common/openssh: socket activate 2024-09-01 03:21:13 +02:00
Oystein Kristoffer Tveit 4d65b9fd1d
common/sudo: misc config 2024-09-01 03:17:15 +02:00
Oystein Kristoffer Tveit f3e094520e
common/postfix: init 2024-09-01 03:13:18 +02:00
Oystein Kristoffer Tveit 69f98933a4
common/smartd: add `smartctl` to environment packages 2024-09-01 01:55:38 +02:00
Oystein Kristoffer Tveit bf2959c68d
common/nix: flesh out 2024-09-01 01:44:59 +02:00
Oystein Kristoffer Tveit 17f0268d12
common/irqbalance: init 2024-09-01 01:39:35 +02:00
Oystein Kristoffer Tveit ebce0eb67a
common/smartd: init 2024-09-01 01:23:15 +02:00
Oystein Kristoffer Tveit b48230e811
bekkalokk/btrfs: scrubbalubba dubdub 2024-09-01 01:04:28 +02:00
Daniel Lovbrotte Olsen 914eb35c5a add a route for /_synapse/admin, point mjolnir at it
This is whitelisted to just bicep

As a side-effect it's also much easier to use synapse-admin now
2024-09-01 00:34:42 +02:00
Oystein Kristoffer Tveit 8610a59f35
base.nix: split into multiple files 2024-08-31 22:28:17 +02:00
Oystein Kristoffer Tveit bd42412b94 bekkalokk/gitea/import-users: refactor + add members to groups 2024-08-27 22:07:29 +02:00
Daniel Lovbrotte Olsen ef3b146b58 bekkalokk/gitea: don't autowatch all members to all projects 2024-08-27 09:26:00 +02:00
Oystein Kristoffer Tveit bb4662b345 modules/snakeoil-certs: fix lmao 2024-08-26 20:43:34 +02:00
Oystein Kristoffer Tveit 5b1c04e4b8 bicep/postgres: use snakeoil certs 2024-08-26 20:43:34 +02:00
Oystein Kristoffer Tveit 3fa7f67027 bekkalokk/gitea-web: host pages 2024-08-26 20:36:03 +02:00
Oystein Kristoffer Tveit b0f555667c bekkalokk/gitea: set up gitea-web sync units 2024-08-26 20:36:03 +02:00
Oystein Kristoffer Tveit ef418bf125
base/logrotate: systemd hardening + more 2024-08-22 23:00:45 +02:00
Oystein Kristoffer Tveit 945d53cdb4
bekkalokk/vaultwarden: systemd hardening 2024-08-22 22:59:32 +02:00
Oystein Kristoffer Tveit cf3b62e01e
bekkalokk/phpfpm-*: systemd hardening 2024-08-22 22:58:48 +02:00
Oystein Kristoffer Tveit c12a47cee0
flake.nix: bump calendar bot 2024-08-17 01:19:46 +02:00
Oystein Kristoffer Tveit b9ef27565f
Bump calendar-bot 2024-08-16 09:16:26 +02:00
Oystein Kristoffer Tveit f5c99b58c8
bicep/calendar-bot: reactivate 2024-08-15 23:22:50 +02:00
Peder Bergebakken Sundt c780f7954c Merge pull request 'justfile: add recipe `run-vm`' (!64) from run-vm into main
Reviewed-on: #64
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-15 21:14:29 +02:00
Oystein Kristoffer Tveit d64d8edd68 bekkalokk/gitea: add some extra tabs 2024-08-14 17:36:19 +02:00
Peder Bergebakken Sundt 4de7bd09bd Merge pull request 'enable thermald on physical machines' (!61) from thermald into main
Reviewed-on: #61
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-14 17:31:44 +02:00
Peder Bergebakken Sundt 0f5c48902b Merge pull request 'users: disable password login for users in @wheel' (!62) from fix-deploy into main
Reviewed-on: #62
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-14 17:31:08 +02:00
Peder Bergebakken Sundt 2ff69dfec6 justfile: add recipe `run-vm` 2024-08-14 17:25:55 +02:00
Peder Bergebakken Sundt 36a8868f94 users: disable password login for users in @wheel 2024-08-11 03:42:26 +02:00
Peder Bergebakken Sundt fe3e5d6a3d enable thermald on physical machines 2024-08-10 23:55:29 +02:00
Peder Bergebakken Sundt 2f3bcaf124 shell.nix: fix typo 2024-08-10 18:15:31 +02:00
Peder Bergebakken Sundt c6684d5146 Merge pull request 'justfile: init' (!56) from justfile into main
Reviewed-on: #56
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-07 12:22:04 +02:00
Peder Bergebakken Sundt f6cb934ffb Merge pull request 'flake.nix: simplify allMachines' (!59) from attrnames into main
Reviewed-on: #59
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-08-04 23:44:54 +02:00
Peder Bergebakken Sundt 9625258942 Merge pull request 'flake.nix: export snakeoil-certs and snappymail nixos modules' (!58) from export-modules into main
Reviewed-on: #58
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-08-04 23:44:19 +02:00
Peder Bergebakken Sundt 34637e383a justfile: add update-inputs recipe 2024-08-04 17:19:40 +02:00
Peder Bergebakken Sundt 0bfa6ac329 flake.nix: export inputs 2024-08-04 17:19:33 +02:00
Peder Bergebakken Sundt 2c3261de74 flake.nix: simplify allMachines 2024-08-04 17:11:21 +02:00
Peder Bergebakken Sundt c2e6f294ea flake.nix: export snakeoil-certs and snappymail nixos modules 2024-08-04 16:48:21 +02:00
Peder Bergebakken Sundt 41e94695f0 Merge pull request 'editorconfig' (!55) from editorconfig into main
Reviewed-on: #55
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 16:20:23 +02:00
Peder Bergebakken Sundt c6b4ea9929 add .git-blame-ignore-revs 2024-08-04 04:39:17 +02:00
Peder Bergebakken Sundt 9dbf5d56f5 fix whitespacing issues 2024-08-04 04:37:23 +02:00
Peder Bergebakken Sundt 64b5bb548b editorconfig: init 2024-08-04 04:35:25 +02:00
Peder Bergebakken Sundt 261c8e0811 Merge pull request 'Run statix' (!54) from statix into main
Reviewed-on: #54
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-08-04 04:26:23 +02:00
Peder Bergebakken Sundt 4476cdcbbc justfile: init 2024-08-04 03:28:17 +02:00
Peder Bergebakken Sundt f475243b94 Merge pull request 'sops: add pederbs' (!51) from pederbs-sops into main
Reviewed-on: #51
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:56:31 +02:00
Peder Bergebakken Sundt f382109b4a Merge pull request 'users: add pederbs' (!49) from user-pederbs into main
Reviewed-on: #49
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:46:59 +02:00
Peder Bergebakken Sundt e5e3100639 Merge pull request 'direnv: yes' (!50) from direnv into main
Reviewed-on: #50
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:46:18 +02:00
Peder Bergebakken Sundt 5853e42c1b Merge pull request 'SimpleSamlPHP: use concatLines' (!53) from concatlines into main
Reviewed-on: #53
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:46:01 +02:00
Peder Bergebakken Sundt d59aa08986 Merge pull request 'shell.nix: remove cc' (!52) from shell-cc into main
Reviewed-on: #52
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:44:52 +02:00
Oystein Kristoffer Tveit 95a5603f27
secrets: run `sops updatekeys` on everything 2024-08-04 02:04:29 +02:00
Peder Bergebakken Sundt 1714681532 `statix fix` 2024-08-04 01:46:00 +02:00
Peder Bergebakken Sundt 314c7960d1 statix: init 2024-08-04 01:45:20 +02:00
Peder Bergebakken Sundt 43d353190c SimpleSamlPHP: use concatLines 2024-08-04 01:42:32 +02:00
Peder Bergebakken Sundt eb74d011db shell.nix: remove cc 2024-08-04 01:30:02 +02:00
Peder Bergebakken Sundt b52de48455 sops: add pederbs 2024-08-04 01:24:54 +02:00
Peder Bergebakken Sundt 510f385f4a direnv: yes 2024-08-04 01:19:22 +02:00
Peder Bergebakken Sundt e25ba96096 users: add pederbs 2024-08-04 00:58:11 +02:00
Oystein Kristoffer Tveit 53040bada1
flake.lock: update pvv-nettsiden 2024-08-04 00:09:32 +02:00
Felix Albrigtsen 2030d4de39 fix-openstack-networking (!47)
Fix networking in Openstack.

This rewrites the systemd-networkd config, fixing both dhcp and manual address/route configurations.
Now, everything should behave predictably, routing NTNU-internal and NTNU-global addresses separately and properly across both ipv4 and ipv6.

Reviewed-on: #47
2024-07-31 11:23:00 +02:00
Felix Albrigtsen c7797bdd04 Merge pull request 'SimpleSAMLPHP/MediaWiki: Update deprecated --replace' (!48) from fix-replace-warn into main
Reviewed-on: #48
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-07-28 23:30:44 +02:00
Felix Albrigtsen 615b5fc1f1 SimpleSAMLPHP/MediaWiki: Update deprecated --replace 2024-07-28 23:28:33 +02:00
Oystein Kristoffer Tveit a0a837e26d Merge pull request 'bekkalokk/gitea: direct non-logged-in users to the explore tab' (!46) from gitea-explore into main
Reviewed-on: #46
Reviewed-by: Felix Albrigtsen <felixalb@pvv.ntnu.no>
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-07-28 23:10:38 +02:00
Daniel Lovbrotte Olsen 8f3013dc00 bekkalokk/gitea: direct non-logged-in users to the explore tab
This is a much more interesting page rather than trying to sell gitea
2024-07-19 21:19:06 +02:00
Daniel Lovbrotte Olsen 78caceddce flake: remove nettsiden from output function scope
This is referred to by inputs anyways
2024-07-18 16:24:42 +02:00
Oystein Kristoffer Tveit 868764e0cd bekkalokk/mediawiki: misc configuration 2024-07-10 19:04:55 +02:00
Oystein Kristoffer Tveit 7c3ff2068d bekkalokk/mediawiki: add some more extensions 2024-07-10 19:04:36 +02:00
Oystein Kristoffer Tveit 9d3f1381bf packages/mediawiki-extensions: refactor 2024-07-10 18:59:16 +02:00
Oystein Kristoffer Tveit f3a29429aa bekkalokk/gitea: set default email notification preference to 'onmention' 2024-07-10 00:18:01 +02:00
Oystein Kristoffer Tveit 1591fdb7cc bekkalokk/mediawiki: re-enable DeleteBatch extension 2024-07-08 19:56:43 +02:00
Oystein Kristoffer Tveit ed28ba28f3 bekkalokk/mediawiki: leave togglable debug flags for future use 2024-07-08 19:55:52 +02:00
Oystein Kristoffer Tveit 52b46667b1 packages/mediawiki-extensions: use fetchgit 2024-07-08 19:54:42 +02:00
Oystein Kristoffer Tveit d0f63b2fc8 packages/mediawiki-extensions: bump all 2024-07-08 16:55:01 +02:00
Oystein Kristoffer Tveit 0301691b1c
gitea: enable notification mails 2024-07-04 20:41:46 +02:00
Oystein Kristoffer Tveit 946555e408
gitea: add subject prefix to mail 2024-07-04 20:36:44 +02:00
Oystein Kristoffer Tveit e02062417a
gitea: move state back to /var/lib 2024-07-04 20:31:51 +02:00
Oystein Kristoffer Tveit b2806d78af
gitea: enable lfs 2024-07-04 20:30:55 +02:00
Oystein Kristoffer Tveit de2c7ea6f1
gitea: install custom images to correct dir 2024-07-04 20:29:50 +02:00
Felix Albrigtsen 106081c967 Merge pull request 'all: Update to nixos-24.05' (!43) from 24.05-for-real into main
Reviewed-on: #43
2024-06-30 01:55:41 +02:00
Felix Albrigtsen ca2deed668 WIP: all: Update to nixos-24.05 2024-06-30 01:55:25 +02:00
Oystein Kristoffer Tveit bb2f7899db Merge pull request 'bekkalokk/gitea: set default licenses and repo units' (!44) from gitea-set-misc-repo-settings into main
Reviewed-on: #44
2024-06-29 23:16:17 +02:00
Oystein Kristoffer Tveit c2b35a7ae4
bekkalokk/gitea: set default licenses and repo units 2024-06-29 23:14:41 +02:00
Felix Albrigtsen c88c3f87e0 buskerud: add libvirtd 2024-06-22 17:36:30 +02:00
Felix Albrigtsen c5bad75edc bekkalokk/nettsiden: Update nettsiden to disable recurring events 2024-06-19 22:15:36 +02:00
Felix Albrigtsen 71479d5ca0 quickfix: bekkalokk/mediawiki: remove DeleteBatch 2024-05-27 11:02:35 +02:00
Felix Albrigtsen cf01792269 bekkalokk/vaultarden: Add kTLS 2024-05-26 10:50:29 +02:00
Felix Albrigtsen afae0da0b6 Merge pull request 'bekkalokk: add vaultwarden' (!40) from bekkalokk-vaultwarden into main
Reviewed-on: #40
2024-05-26 04:21:28 +02:00
Felix Albrigtsen 35d745b156 bekkalokk: add vaultwarden 2024-05-26 04:19:17 +02:00
Oystein Kristoffer Tveit 218ee776c7 Merge pull request 'packages/mediawiki-extensions: use stable url' (!35) from fix-mediawiki-extensions-url into main
Reviewed-on: #35
2024-05-26 02:45:04 +02:00
Oystein Kristoffer Tveit 3a972f03f7
flake: move mediawiki-extensions back to packages 2024-05-26 02:42:31 +02:00
Daniel Lovbrotte Olsen 96024efa28
flake: move mediawiki-extensions to legacyPackages 2024-05-26 02:42:31 +02:00
Daniel Lovbrotte Olsen af54cc2df4
packages/mediawiki/pluggable-auth: fix typo 2024-05-26 02:42:31 +02:00
Oystein Kristoffer Tveit 6f6721ce07
packages/mediawiki-extensions: use stable url 2024-05-26 02:42:28 +02:00
Felix Albrigtsen 1c35da0295 Merge pull request 'bekkalokk: add snappymail' (!39) from bekkalokk-snappymail into main
Reviewed-on: #39
2024-05-26 01:52:17 +02:00
Felix Albrigtsen 5fb1b805a8 bekkalokk: add snappymail 2024-05-26 01:07:27 +02:00
Oystein Kristoffer Tveit a38a12c429
flake.lock: update pvv-nettsiden 2024-05-19 22:27:59 +02:00
Daniel Lovbrotte Olsen 898e362a9f Merge pull request 'bekkalokk/website: add sp metadata for all domains' (!34) from add-sp-metadata-for-all-website-domains into main
Reviewed-on: #34
2024-05-14 05:27:44 +02:00
Daniel Lovbrotte Olsen c267820426 overlays/nginx-test: drop 2024-05-13 07:04:00 +02:00
Oystein Kristoffer Tveit a57b5f07f9 Merge pull request 'gitea: setup mail' (!38) from gitea-setup-mail into main
Reviewed-on: #38
2024-05-12 02:27:37 +02:00
Oystein Kristoffer Tveit bcf2ceed32
gitea: setup mail 2024-05-12 02:26:13 +02:00
Daniel Lovbrotte Olsen 0a3d1e3696 overlays/nginx-test
just start replacing shit, we're not even testing the actual config now
This sucks
nginx should make a proper validation tool that doesnt do DNS request on every hostname mentioned in the config file.
Not to mention trying to actually listen on the ip-address and port
Why?? Why is TEST failing because it can't bind to the SAME address nginx is probably in production listening on already??
2024-05-12 02:22:12 +02:00
Daniel Lovbrotte Olsen 45eea1a791 update flake.lock 2024-05-12 02:22:12 +02:00
Oystein Kristoffer Tveit 200224d2c1 Merge pull request 'bekkalokk: misc gitea cleanup' (!33) from misc-gitea-cleanup into main
Reviewed-on: #33
2024-05-12 02:12:55 +02:00
Daniel Lovbrotte Olsen dcf29b76b8 bicep/matrix: allow global address of new ildkule to access metrics
Eval nix flake / evals (push) Successful in 1h30m46s Details
2024-04-24 03:03:53 +02:00
Felix Albrigtsen 55e8f01d1d Upgrade ildkule (!36)
Eval nix flake / evals (push) Failing after 3h12m29s Details
This PR is made while moving Ildkule from PVE on joshua, to Openstack on stack.it.ntnu.no.

- The main monitoring dashboard is moved from https://ildkule.pvv.ntnu.no to https://grafana.pvv.ntnu.no.
- A new service is added: uptime-kuma on https://uptime.pvv.ntnu.no.
- The (hardware) configuration for ildkule is updated to fit the new virtualization environment, boot loader, network interfaces, etc.
- Metrics exporters on other hosts should be updated to allow connections from the new host

As this is the first proper server running on openstack, and therefore outside our main IP range, we might discover challenges in our network structure. For example, the database servers usually only allow connections from this range, so Ildkule can no longer access it. This should be explored, documented and/or fixed as we move more services.

Reviewed-on: #36
Co-authored-by: Felix Albrigtsen <felix@albrigtsen.it>
Co-committed-by: Felix Albrigtsen <felix@albrigtsen.it>
2024-04-21 23:36:25 +02:00
Oystein Kristoffer Tveit b7b1c73bfa
bekkalokk/gitea: use systemd unit for gitea customization
Eval nix flake / evals (pull_request) Failing after 47s Details
Eval nix flake / evals (push) Failing after 14m41s Details
2024-04-16 01:02:21 +02:00
Oystein Kristoffer Tveit 19d5ddc688 Merge pull request 'bekkalokk: remove keycloak' (!30) from bekkalokk-remove-keycloak into main
Eval nix flake / evals (push) Failing after 1m49s Details
Reviewed-on: #30
2024-04-15 00:00:17 +02:00
Oystein Kristoffer Tveit 6851879a03
bekkalokk: remove keycloak
Eval nix flake / evals (pull_request) Failing after 1m39s Details
Eval nix flake / evals (push) Failing after 1m41s Details
2024-04-14 23:59:46 +02:00
Oystein Kristoffer Tveit 70603145cf
bekkalokk/website: add sp metadata for all domains
Eval nix flake / evals (pull_request) Failing after 1m49s Details
Eval nix flake / evals (push) Failing after 41s Details
2024-04-14 17:06:01 +02:00
Felix Albrigtsen 1e4195ea9d bekkalokk: pvv-nettsiden-gallery: Improve thumbnail generation
Eval nix flake / evals (push) Failing after 1m46s Details
2024-04-14 02:04:45 +02:00
Daniel Lovbrotte Olsen ee335e3712 bicep/synapse: fix registering users via smtp
Eval nix flake / evals (push) Failing after 2m0s Details
2024-04-14 01:52:17 +02:00
Daniel Lovbrotte Olsen ffbf855f24 update flake for grzegorz
Eval nix flake / evals (push) Failing after 1m52s Details
2024-04-12 02:35:49 +02:00
Daniel Lovbrotte Olsen 28e7a63d33 update flake lock and remove non-derivations from flake ouput
Eval nix flake / evals (push) Failing after 1m47s Details
2024-04-12 00:42:29 +02:00
Daniel Lovbrotte Olsen 01f0e63a49 use getExe' to silence errors 2024-04-12 00:41:57 +02:00
Daniel Lovbrotte Olsen ae4ace9fa2 Merge pull request 'treewide: run nginx -t on all nginx config files' (!32) from test-nginx-overlay into main
Eval nix flake / evals (push) Failing after 1m46s Details
Reviewed-on: #32
2024-04-11 23:39:42 +02:00
Daniel Lovbrotte Olsen 8c72088d9c dynamically get configured acme certs for nginx test
Eval nix flake / evals (push) Failing after 1m44s Details
Eval nix flake / evals (pull_request) Failing after 1m51s Details
2024-04-11 23:29:05 +02:00
Daniel Lovbrotte Olsen 0056029da7 treewide: bubblewrap nginx test 2024-04-11 23:28:54 +02:00
Daniel Lovbrotte Olsen 9b4fbd847f treewide: run nginx -t on all nginx config files 2024-04-11 23:28:54 +02:00
Oystein Kristoffer Tveit 5bed292a01
bekkalokk/gitea: move user import stuff to separate nix file 2024-04-11 21:47:44 +02:00
Oystein Kristoffer Tveit 36b7087a3f
base.nix: hotfix for hotfix for nginx on bicep (3352e48f)
Eval nix flake / evals (push) Failing after 1m49s Details
Turns out the settings were in biceps local nginx config
2024-04-11 20:41:02 +02:00
Oystein Kristoffer Tveit 1919da7a1c bicep/matrix: remove SAML authentication
Eval nix flake / evals (push) Failing after 1m50s Details
2024-04-11 19:55:10 +02:00
Oystein Kristoffer Tveit 0950fedf98 bekkalokk/website: fix some nginx location directives
Eval nix flake / evals (push) Failing after 1m50s Details
2024-04-11 13:21:11 +02:00
Oystein Kristoffer Tveit 614c2d624c
bekkalokk/webmail: add redirects for old webmail locations
Eval nix flake / evals (push) Failing after 1m45s Details
2024-04-11 10:47:13 +02:00
Oystein Kristoffer Tveit 3352e48f47
base.nix: hotfix for nginx on bicep
Eval nix flake / evals (push) Failing after 1m51s Details
the matrix-synapse-next module seems to already add some of the nginx
options we set in base.nix, making it fail. These should only be set if
they're not already set by this module
2024-04-11 10:30:14 +02:00
Daniel Lovbrotte Olsen db211c2304 bekkalokk/website: don't try to listen for ntnu.org
Eval nix flake / evals (push) Failing after 1m48s Details
2024-04-11 05:31:33 +02:00
Felix Albrigtsen 4f322ec0b1 Merge pull request 'finalize-www-migration' (!31) from finalize-www-migration into main
Eval nix flake / evals (push) Failing after 1m40s Details
Reviewed-on: #31
2024-04-11 00:57:20 +02:00
Felix Albrigtsen 79bf307ef2 bekkalokk: Reconfigure www ingress
Eval nix flake / evals (push) Failing after 1m46s Details
Eval nix flake / evals (pull_request) Failing after 1m52s Details
2024-04-11 00:48:07 +02:00
Felix Albrigtsen 4d50efc6db Finalize www/idp/webmail migration from spikkjeposche to bekkalokk
Eval nix flake / evals (push) Failing after 1m48s Details
2024-04-10 23:31:04 +02:00
Felix Albrigtsen 145a840a2c Merge pull request 'Setup pvv-nettsiden on www2.pvv.ntnu.no' (!27) from www2 into main
Eval nix flake / evals (push) Failing after 1m47s Details
Reviewed-on: #27
2024-04-10 23:05:37 +02:00
Felix Albrigtsen 2bbc851e0e Point inputs/nettsiden to master after Projects/nettsiden#53
Eval nix flake / evals (push) Failing after 1m48s Details
Eval nix flake / evals (pull_request) Failing after 1m48s Details
2024-04-10 23:04:20 +02:00
Oystein Kristoffer Tveit 9577477460 bekkalokk/nettsiden: add secrets 2024-04-10 23:04:20 +02:00
Felix Albrigtsen fc19a8f1e1 bekkalokk: Automatically unpack pvv-nettsiden/gallery and generate thumbnails 2024-04-10 23:04:20 +02:00
Oystein Kristoffer Tveit 8657e77514 bekkalokk: set up pvv-nettsiden 2024-04-10 23:04:18 +02:00
Felix Albrigtsen 03c9638098 Merge pull request 'treewide: nginx optimizations' (!29) from treewide-nginx-optimizations into main
Eval nix flake / evals (push) Failing after 1m47s Details
Reviewed-on: #29
2024-04-10 22:54:39 +02:00
Oystein Kristoffer Tveit 065992620e treewide: nginx optimizations
Eval nix flake / evals (push) Failing after 1m47s Details
Eval nix flake / evals (pull_request) Failing after 1m54s Details
2024-04-10 22:06:44 +02:00
Adrian Gunnar Lauterer e22c7d5b4d added terminfo for foot to adriangl
Eval nix flake / evals (push) Failing after 1m46s Details
2024-04-09 20:46:14 +02:00
Oystein Kristoffer Tveit 4fcc1fd5e9 flake.lock: update nix-gitea-themes
Eval nix flake / evals (push) Failing after 1m47s Details
2024-04-09 20:33:38 +02:00
Oystein Kristoffer Tveit 05a1f049dc Merge pull request 'gitea: add theming module' (!28) from init-gitea-themes into main
Eval nix flake / evals (push) Failing after 2m13s Details
Reviewed-on: #28
2024-04-09 20:32:29 +02:00
Oystein Kristoffer Tveit fbbc54328b gitea: add theming module
Eval nix flake / evals (push) Failing after 1m51s Details
Eval nix flake / evals (pull_request) Failing after 1m54s Details
2024-04-09 01:52:57 +02:00
Adrian Gunnar Lauterer d8e13ff67c Update users/adriangl.nix
Eval nix flake / evals (push) Failing after 1m50s Details
2024-04-08 21:21:24 +02:00
Oystein Kristoffer Tveit 42fd371c3b
mediawiki: restart phpfpm on updated secrets
Eval nix flake / evals (push) Failing after 2m11s Details
2024-04-06 23:57:37 +02:00
Oystein Kristoffer Tveit f25a4e5c02 Merge pull request 'mediawiki: add VisualEditor' (#26) from mediawiki-add-visual-editor into main
Eval nix flake / evals (push) Failing after 1m47s Details
Reviewed-on: #26
2024-04-06 21:19:41 +02:00
Oystein Kristoffer Tveit 6e1b06731f bekkalokk: add VisualEditor to mediawiki extensions
Eval nix flake / evals (push) Failing after 1m53s Details
Eval nix flake / evals (pull_request) Failing after 1m42s Details
2024-04-06 21:09:01 +02:00
Oystein Kristoffer Tveit 161ef284be packages: add mediawiki-extensions.VisualEditor 2024-04-06 21:08:32 +02:00
Felix Albrigtsen 2cb7e06369
bekkalokk/mediawiki: fix path, upgrade security
Eval nix flake / evals (push) Failing after 1m54s Details
2024-04-03 08:29:19 +02:00
Oystein Kristoffer Tveit a55c908fe7
bekkalokk/mediawiki: change domain from wiki2 to wiki
Eval nix flake / evals (push) Failing after 1m48s Details
2024-04-02 19:54:28 +02:00
Oystein Kristoffer Tveit 06bd93e5d1 Merge pull request 'bekkalokk: set up idp + mediawiki' (#25) from mediawiki-on-bekkalokk into main
Eval nix flake / evals (push) Failing after 1m56s Details
Reviewed-on: #25
2024-04-02 00:00:24 +02:00
Oystein Kristoffer Tveit d531419f35 bekkalokk: init mediawiki
Eval nix flake / evals (pull_request) Failing after 1m46s Details
Eval nix flake / evals (push) Failing after 1m53s Details
Co-authored-by: Jørn Åne <yorinad@pvv.ntnu.no>
2024-04-01 23:57:39 +02:00
Oystein Kristoffer Tveit 806b18ede8 bekkalokk: init idp-simplesamlphp 2024-04-01 23:57:39 +02:00
Oystein Kristoffer Tveit c612975b60 base/nginx: 444 requests to nonexistent virtualhosts 2024-04-01 23:57:39 +02:00
Oystein Kristoffer Tveit 9495682f57 bekkalokk: package mediawiki extensions outside of module 2024-04-01 00:39:12 +02:00
Oystein Kristoffer Tveit d39047b8cb packages: init simplesamlphp 2024-04-01 00:38:51 +02:00
Oystein Kristoffer Tveit 266ce9ed08 bekkalokk: set up kerberos client 2024-04-01 00:38:49 +02:00
Felix Albrigtsen 07c480d004 base: add ripgrep
Eval nix flake / evals (push) Failing after 1m53s Details
2024-03-30 21:07:00 +01:00
Oystein Kristoffer Tveit 64c7e3e365 flake.nix: fix usage of common nixos module/overlay list 2024-03-29 01:51:37 +01:00
Daniel Lovbrotte Olsen fe4dd21acb add eirikwit to sops
Eval nix flake / evals (push) Failing after 1m44s Details
2024-03-16 22:38:16 +01:00
Daniel Lovbrotte Olsen 0336744124 flake update: matrix module bug fix
Eval nix flake / evals (push) Failing after 1m55s Details
2024-03-13 07:41:12 +01:00
Daniel Lovbrotte Olsen b4d6e00622 Update flake.lock to get new matrix module
Eval nix flake / evals (push) Failing after 1m51s Details
2024-03-13 06:33:43 +01:00
Daniel Lovbrotte Olsen 7c6d4d31c7 bicep/matrix/element: update room directories
Eval nix flake / evals (push) Failing after 1m44s Details
2024-03-05 05:52:31 +01:00
Daniel Lovbrotte Olsen 9f46be1ca1 bicep/matrix: update element lab flags and room directoriy listings
Eval nix flake / evals (push) Failing after 1m44s Details
2024-03-05 05:28:23 +01:00
Jo Vassbotn Remvik 545583cf04 bekkalokk/gitea: Do not change the user visibility
Eval nix flake / evals (push) Failing after 1m55s Details
2024-03-03 00:29:24 +01:00
Felix Albrigtsen 62b269637a bekkalokk/gitea: unset visibility when updating users
Eval nix flake / evals (push) Failing after 1m50s Details
2024-02-12 11:24:14 +01:00
132 changed files with 10275 additions and 1312 deletions

10
.editorconfig Normal file
View File

@ -0,0 +1,10 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.nix]
indent_style = space
indent_size = 2

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

1
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1 @@
e00008da1afe0d760badd34bbeddff36bb08c475

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
result* result*
/configuration.nix /configuration.nix
/.direnv/
*.qcow2

View File

@ -3,10 +3,14 @@ keys:
- &user_danio age17tagmpwqjk3mdy45rfesrfey6h863x8wfq38wh33tkrlrywxducs0k6tpq - &user_danio age17tagmpwqjk3mdy45rfesrfey6h863x8wfq38wh33tkrlrywxducs0k6tpq
- &user_felixalb age1mrnldl334l2nszuta6ywvewng0fswv2dz9l5g4qcwe3nj4yxf92qjskdx6 - &user_felixalb age1mrnldl334l2nszuta6ywvewng0fswv2dz9l5g4qcwe3nj4yxf92qjskdx6
- &user_oysteikt F7D37890228A907440E1FD4846B9228E814A2AAC - &user_oysteikt F7D37890228A907440E1FD4846B9228E814A2AAC
- &user_eirikwit age1ju7rd26llahz3g8tz7cy5ld52swj8gsmg0flrmrxngc0nj0avq3ssh0sn5
- &user_pederbs_sopp age1hmpdk4h69wxpwqk9tkud39f66hprhehxtzhgw97r6dvr7v0mx5jscsuhkn
- &user_pederbs_nord age1wrssr4z4g6vl3fd3qme5cewchmmhm0j2xe6wf2meu4r6ycn37anse98mfs
- &user_pederbs_bjarte age1zhxul786an743u0fascv4wtc5xduu7qfy803lfs539yzhgmlq5ds2lznt5
# Hosts # Hosts
- &host_jokum age1gp8ye4g2mmw3may5xg0zsy7mm04glfz3788mmdx9cvcsdxs9hg0s0cc9kt - &host_jokum age1gp8ye4g2mmw3may5xg0zsy7mm04glfz3788mmdx9cvcsdxs9hg0s0cc9kt
- &host_ildkule age1hn45n46ypyrvypv0mwfnpt9ddrlmw34dwlpf33n8v67jexr3lucq6ahc9x - &host_ildkule age1x28hmzvuv6f2n66c0jtqcca3h9rput8d7j5uek6jcpx8n9egd52sqpejq0
- &host_bekkalokk age12nj59tguy9wg882updc2vjdusx5srnxmjyfaqve4zx6jnnsaw3qsyjq6zd - &host_bekkalokk age12nj59tguy9wg882updc2vjdusx5srnxmjyfaqve4zx6jnnsaw3qsyjq6zd
- &host_bicep age1sl43gc9cw939z5tgha2lpwf0xxxgcnlw7w4xem4sqgmt2pt264vq0dmwx2 - &host_bicep age1sl43gc9cw939z5tgha2lpwf0xxxgcnlw7w4xem4sqgmt2pt264vq0dmwx2
@ -18,6 +22,10 @@ creation_rules:
- *host_jokum - *host_jokum
- *user_danio - *user_danio
- *user_felixalb - *user_felixalb
- *user_eirikwit
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp: pgp:
- *user_oysteikt - *user_oysteikt
@ -29,6 +37,9 @@ creation_rules:
- *host_bekkalokk - *host_bekkalokk
- *user_danio - *user_danio
- *user_felixalb - *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp: pgp:
- *user_oysteikt - *user_oysteikt
@ -38,6 +49,9 @@ creation_rules:
- *host_jokum - *host_jokum
- *user_danio - *user_danio
- *user_felixalb - *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp: pgp:
- *user_oysteikt - *user_oysteikt
@ -47,6 +61,9 @@ creation_rules:
- *host_ildkule - *host_ildkule
- *user_danio - *user_danio
- *user_felixalb - *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp: pgp:
- *user_oysteikt - *user_oysteikt
@ -56,5 +73,8 @@ creation_rules:
- *host_bicep - *host_bicep
- *user_danio - *user_danio
- *user_felixalb - *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp: pgp:
- *user_oysteikt - *user_oysteikt

View File

@ -26,10 +26,14 @@ Det er sikkert lurt å lage en PR først om du ikke er vandt til nix enda.
Innen 24h skal alle systemene hente ned den nye konfigurasjonen og deploye den. Innen 24h skal alle systemene hente ned den nye konfigurasjonen og deploye den.
Du kan tvinge en maskin til å oppdatere seg før dette ved å kjøre: Du kan tvinge en maskin til å oppdatere seg før dette ved å kjøre:
`nixos-rebuild switch --update-input nixpkgs --update-input nixpkgs-unstable --no-write-lock-file --refresh --flake git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git --upgrade` `nixos-rebuild switch --update-input nixpkgs --update-input nixpkgs-unstable --no-write-lock-file --refresh --upgrade --flake git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git`
som root på maskinen. som root på maskinen.
Hvis du ikke har lyst til å oppdatere alle pakkene (og kanskje måtte vente en stund!) kan du kjøre
`nixos-rebuild switch --override-input nixpkgs nixpkgs --override-input nixpkgs-unstable nixpkgs-unstable --flake git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git`
## Seksjonen for hemmeligheter ## Seksjonen for hemmeligheter
For at hemmeligheter ikke skal deles med hele verden i git - eller å være world For at hemmeligheter ikke skal deles med hele verden i git - eller å være world

View File

@ -1,86 +0,0 @@
{ config, lib, pkgs, inputs, values, ... }:
{
imports = [
./users
];
networking.domain = "pvv.ntnu.no";
networking.useDHCP = false;
# networking.search = [ "pvv.ntnu.no" "pvv.org" ];
# networking.nameservers = lib.mkDefault [ "129.241.0.200" "129.241.0.201" ];
# networking.tempAddresses = lib.mkDefault "disabled";
# networking.defaultGateway = values.hosts.gateway;
systemd.network.enable = true;
services.resolved = {
enable = lib.mkDefault true;
dnssec = "false"; # Supposdly this keeps breaking and the default is to allow downgrades anyways...
};
time.timeZone = "Europe/Oslo";
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "no";
};
system.autoUpgrade = {
enable = true;
flake = "git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git";
flags = [
"--update-input" "nixpkgs"
"--update-input" "nixpkgs-unstable"
"--no-write-lock-file"
];
};
nix.gc.automatic = true;
nix.gc.options = "--delete-older-than 2d";
nix.settings.experimental-features = [ "nix-command" "flakes" ];
/* This makes commandline tools like
** nix run nixpkgs#hello
** and nix-shell -p hello
** use the same channel the system
** was built with
*/
nix.registry = {
nixpkgs.flake = inputs.nixpkgs;
};
nix.nixPath = [ "nixpkgs=${inputs.nixpkgs}" ];
environment.systemPackages = with pkgs; [
file
git
gnupg
htop
nano
rsync
screen
tmux
vim
wget
kitty.terminfo
];
programs.zsh.enable = true;
users.groups."drift".name = "drift";
# Trusted users on the nix builder machines
users.groups."nix-builder-users".name = "nix-builder-users";
services.openssh = {
enable = true;
extraConfig = ''
PubkeyAcceptedAlgorithms=+ssh-rsa
'';
settings.PermitRootLogin = "yes";
};
}

60
base/default.nix Normal file
View File

@ -0,0 +1,60 @@
{ pkgs, lib, fp, ... }:
{
imports = [
(fp /users)
(fp /modules/snakeoil-certs.nix)
./networking.nix
./nix.nix
./services/acme.nix
./services/auto-upgrade.nix
./services/irqbalance.nix
./services/logrotate.nix
./services/nginx.nix
./services/openssh.nix
./services/postfix.nix
./services/smartd.nix
./services/thermald.nix
];
boot.tmp.cleanOnBoot = lib.mkDefault true;
time.timeZone = "Europe/Oslo";
i18n.defaultLocale = "en_US.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "no";
};
environment.systemPackages = with pkgs; [
file
git
gnupg
htop
nano
ripgrep
rsync
screen
tmux
vim
wget
kitty.terminfo
];
programs.zsh.enable = true;
security.sudo.execWheelOnly = true;
security.sudo.extraConfig = ''
Defaults lecture = never
'';
users.groups."drift".name = "drift";
# Trusted users on the nix builder machines
users.groups."nix-builder-users".name = "nix-builder-users";
}

13
base/networking.nix Normal file
View File

@ -0,0 +1,13 @@
{ lib, values, ... }:
{
systemd.network.enable = true;
networking.domain = "pvv.ntnu.no";
networking.useDHCP = false;
# The rest of the networking configuration is usually sourced from /values.nix
services.resolved = {
enable = lib.mkDefault true;
dnssec = "false"; # Supposdly this keeps breaking and the default is to allow downgrades anyways...
};
}

34
base/nix.nix Normal file
View File

@ -0,0 +1,34 @@
{ inputs, ... }:
{
nix = {
gc = {
automatic = true;
options = "--delete-older-than 2d";
};
settings = {
allow-dirty = true;
auto-optimise-store = true;
builders-use-substitutes = true;
experimental-features = [ "nix-command" "flakes" ];
log-lines = 50;
use-xdg-base-directories = true;
};
/* This makes commandline tools like
** nix run nixpkgs#hello
** and nix-shell -p hello
** use the same channel the system
** was built with
*/
registry = {
"nixpkgs".flake = inputs.nixpkgs;
"nixpkgs-unstable".flake = inputs.nixpkgs-unstable;
"pvv-nix".flake = inputs.self;
};
nixPath = [
"nixpkgs=${inputs.nixpkgs}"
"unstable=${inputs.nixpkgs-unstable}"
];
};
}

15
base/services/acme.nix Normal file
View File

@ -0,0 +1,15 @@
{ ... }:
{
security.acme = {
acceptTerms = true;
defaults.email = "drift@pvv.ntnu.no";
};
# Let's not spam LetsEncrypt in `nixos-rebuild build-vm` mode:
virtualisation.vmVariant = {
security.acme.defaults.server = "https://127.0.0.1";
security.acme.preliminarySelfsigned = true;
users.users.root.initialPassword = "root";
};
}

View File

@ -0,0 +1,26 @@
{ inputs, pkgs, lib, ... }:
{
system.autoUpgrade = {
enable = true;
flake = "git+https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git";
flags = [
# --update-input is deprecated since nix 2.22, and removed in lix 2.90
# https://git.lix.systems/lix-project/lix/issues/400
"--refresh"
"--override-input" "nixpkgs" "github:nixos/nixpkgs/nixos-24.05-small"
"--override-input" "nixpkgs-unstable" "github:nixos/nixpkgs/nixos-unstable-small"
"--no-write-lock-file"
];
};
# workaround for https://github.com/NixOS/nix/issues/6895
# via https://git.lix.systems/lix-project/lix/issues/400
environment.etc."current-system-flake-inputs.json".source
= pkgs.writers.writeJSON "flake-inputs.json" (
lib.flip lib.mapAttrs inputs (name: input:
# inputs.*.sourceInfo sans outPath, since writeJSON will otherwise serialize sourceInfo like a derivation
lib.removeAttrs (input.sourceInfo or {}) [ "outPath" ]
// { store-path = input.outPath; } # comment this line if you don't want to retain a store reference to the flake inputs
)
);
}

View File

@ -0,0 +1,4 @@
{ ... }:
{
services.irqbalance.enable = true;
}

View File

@ -0,0 +1,42 @@
{ ... }:
{
# source: https://github.com/logrotate/logrotate/blob/main/examples/logrotate.service
systemd.services.logrotate = {
documentation = [ "man:logrotate(8)" "man:logrotate.conf(5)" ];
unitConfig.RequiresMountsFor = "/var/log";
serviceConfig = {
Nice = 19;
IOSchedulingClass = "best-effort";
IOSchedulingPriority = 7;
ReadWritePaths = [ "/var/log" ];
AmbientCapabilities = [ "" ];
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true; # disable for third party rotate scripts
PrivateDevices = true;
PrivateNetwork = true; # disable for mail delivery
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true; # disable for userdir logs
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "full";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true; # disable for creating setgid directories
SocketBindDeny = [ "any" ];
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
];
};
};
}

44
base/services/nginx.nix Normal file
View File

@ -0,0 +1,44 @@
{ config, lib, ... }:
{
# nginx return 444 for all nonexistent virtualhosts
systemd.services.nginx.after = [ "generate-snakeoil-certs.service" ];
environment.snakeoil-certs = lib.mkIf config.services.nginx.enable {
"/etc/certs/nginx" = {
owner = "nginx";
group = "nginx";
};
};
networking.firewall.allowedTCPPorts = lib.mkIf config.services.nginx.enable [ 80 443 ];
services.nginx = {
recommendedTlsSettings = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
appendConfig = ''
pcre_jit on;
worker_processes auto;
worker_rlimit_nofile 100000;
'';
eventsConfig = ''
worker_connections 2048;
use epoll;
multi_accept on;
'';
};
systemd.services.nginx.serviceConfig = lib.mkIf config.services.nginx.enable {
LimitNOFILE = 65536;
};
services.nginx.virtualHosts."_" = lib.mkIf config.services.nginx.enable {
sslCertificate = "/etc/certs/nginx.crt";
sslCertificateKey = "/etc/certs/nginx.key";
addSSL = true;
extraConfig = "return 444;";
};
}

21
base/services/openssh.nix Normal file
View File

@ -0,0 +1,21 @@
{ ... }:
{
services.openssh = {
enable = true;
startWhenNeeded = true;
extraConfig = ''
PubkeyAcceptedAlgorithms=+ssh-rsa
Match Group wheel
PasswordAuthentication no
Match All
'';
settings.PermitRootLogin = "yes";
};
users.users."root".openssh.authorizedKeys.keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqVt4LCe0YIttr9swFxjkjn37ZDY9JxwVC+2gvfSINDJorOCtqPjDOTD2fTS1Gz08QCwpnLWq2kyvRchu6WgriAbSACpbZZBgxRaF/FVh3oiMVFGnNKGnv6/fdo/vZtu8mUVuqtmTrgLYpZdbR4oD3XiBlDKs7Cv5hPqt95lnP6MNFvE8mICCfd1PwhsABd2IQ5laz3u77/RXhNFJL0Kf2/+6gk9awcLuwHrPdvq7c3BxRHbc9UMRQENyjyQPa7aLe+uJBFLKP51I8VBuDpDacuibQx7nMt6N2UJ2KWI0JxRMHuJNq4S5jidR82aOw9gzGbTv30SKNLMqsZ0xj4LtdqCXDiZF6Lr09PsJYsvnBUFWa14HGcThKDtgwQwBryNViYmfv//0h9+RLZiU0ab+NEwSs7Zh5iAD+vhx64QqNX3tR7Le4SWXh8W0eShU9N78qYdSkiC3Ui7htxeqOocXM/P4AwbnHsLELIvkHdvgchCPvl8ygZa4WJTEWv16+ICskJcAKWGuqjvXAFuwjJJmPp9xLW9O0DFfQhMELiGamQR9wK07yYQVr34iah6qZO7cwhSKyEPFrVPIaNtfDhsjED639F7vmktf26SWNJHWfW0wOHILjI6TgqUvy0JDd8W8w0CHlAfz6Fs2l99NNgNF8dB3vBASbxS0hu/y0PVu/xQ== openstack-sleipner"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICCbgJ0Uwh9VSVhfId7l9i5/jk4CvAK5rbkiab8R+moF root@sleipner"
];
}

23
base/services/postfix.nix Normal file
View File

@ -0,0 +1,23 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.postfix;
in
{
services.postfix = {
enable = true;
hostname = "${config.networking.hostName}.pvv.ntnu.no";
domain = "pvv.ntnu.no";
relayHost = "smtp.pvv.ntnu.no";
relayPort = 465;
config = {
smtp_tls_wrappermode = "yes";
smtp_tls_security_level = "encrypt";
};
# Nothing should be delivered to this machine
destination = [ ];
};
}

18
base/services/smartd.nix Normal file
View File

@ -0,0 +1,18 @@
{ config, pkgs, lib, ... }:
{
services.smartd = {
enable = lib.mkDefault true;
notifications = {
mail = {
enable = true;
sender = "root@pvv.ntnu.no";
recipient = "root@pvv.ntnu.no";
};
wall.enable = false;
};
};
environment.systemPackages = lib.optionals config.services.smartd.enable (with pkgs; [
smartmontools
]);
}

View File

@ -0,0 +1,8 @@
{ config, lib, ... }:
{
# Let's not thermal throttle
services.thermald.enable = lib.mkIf (lib.all (x: x) [
(config.nixpkgs.system == "x86_64-linux")
(!config.boot.isContainer or false)
]) true;
}

View File

@ -7,11 +7,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1702569759, "lastModified": 1731746438,
"narHash": "sha256-Ze3AdEEsVZBRJ4wn13EZpV1Uubkzi59TkC4j2G9xoFI=", "narHash": "sha256-f3SSp1axoOk0NAI7oFdRzbxG2XPBSIXC+/DaAXnvS1A=",
"owner": "nix-community", "owner": "nix-community",
"repo": "disko", "repo": "disko",
"rev": "98ab91109716871f50ea8cb0e0ac7cc1e1e14714", "rev": "cb64993826fa7a477490be6ccb38ba1fa1e18fa8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -20,24 +20,25 @@
"type": "github" "type": "github"
} }
}, },
"grzegorz": { "greg-ng": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs"
] ],
"rust-overlay": "rust-overlay"
}, },
"locked": { "locked": {
"lastModified": 1696346665, "lastModified": 1730249639,
"narHash": "sha256-J6Tf6a/zhFZ8SereluHLrvgPsIVm2CGHHA8wrbhZB3Y=", "narHash": "sha256-G3URSlqCcb+GIvGyki+HHrDM5ZanX/dP9BtppD/SdfI=",
"owner": "Programvareverkstedet", "ref": "refs/heads/main",
"repo": "grzegorz", "rev": "80e0447bcb79adad4f459ada5610f3eae987b4e3",
"rev": "9b9c3ac7d408ac7c6d67544b201e6b169afacb03", "revCount": 34,
"type": "github" "type": "git",
"url": "https://git.pvv.ntnu.no/Projects/greg-ng.git"
}, },
"original": { "original": {
"owner": "Programvareverkstedet", "type": "git",
"repo": "grzegorz", "url": "https://git.pvv.ntnu.no/Projects/greg-ng.git"
"type": "github"
} }
}, },
"grzegorz-clients": { "grzegorz-clients": {
@ -47,96 +48,121 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1693864994, "lastModified": 1726861934,
"narHash": "sha256-oLDiWdCKDtEfeGzfAuDTq+n9VWp6JCo67PEESEZ3y8E=", "narHash": "sha256-lOzPDwktd+pwszUTbpUdQg6iCzInS11fHLfkjmnvJrM=",
"owner": "Programvareverkstedet", "ref": "refs/heads/master",
"repo": "grzegorz-clients", "rev": "546d921ec46735dbf876e36f4af8df1064d09432",
"rev": "a38a0b0fb31ad0ad78a91458cb2c7f77f686468f", "revCount": 78,
"type": "github" "type": "git",
"url": "https://git.pvv.ntnu.no/Projects/grzegorz-clients.git"
}, },
"original": { "original": {
"owner": "Programvareverkstedet", "type": "git",
"repo": "grzegorz-clients", "url": "https://git.pvv.ntnu.no/Projects/grzegorz-clients.git"
"type": "github"
} }
}, },
"matrix-next": { "matrix-next": {
"inputs": { "inputs": {
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs": [
"nixpkgs"
]
}, },
"locked": { "locked": {
"lastModified": 1701507532, "lastModified": 1727410897,
"narHash": "sha256-Zzv8OFB7iilzDGe6z2t/j8qRtR23TN3N8LssGsvRWEA=", "narHash": "sha256-tWsyxvf421ieWUJYgjV7m1eTdr2ZkO3vId7vmtvfFpQ=",
"owner": "dali99", "owner": "dali99",
"repo": "nixos-matrix-modules", "repo": "nixos-matrix-modules",
"rev": "046194cdadc50d81255a9c57789381ed1153e2b1", "rev": "ff787d410cba17882cd7b6e2e22cc88d4064193c",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "dali99", "owner": "dali99",
"ref": "v0.6.1",
"repo": "nixos-matrix-modules", "repo": "nixos-matrix-modules",
"type": "github" "type": "github"
} }
}, },
"minecraft-data": {
"locked": {
"lastModified": 1725277886,
"narHash": "sha256-Fw4VbbE3EfypQWSgPDFfvVH47BHeg3ptsO715NlUM8Q=",
"ref": "refs/heads/master",
"rev": "1b4087bd3322a2e2ba84271c8fcc013e6b641a58",
"revCount": 2,
"type": "git",
"url": "https://git.pvv.ntnu.no/Drift/minecraft-data.git"
},
"original": {
"type": "git",
"url": "https://git.pvv.ntnu.no/Drift/minecraft-data.git"
}
},
"nix-gitea-themes": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1714416973,
"narHash": "sha256-aZUcvXjdETUC6wVQpWDVjLUzwpDAEca8yR0ITDeK39o=",
"ref": "refs/heads/main",
"rev": "2b23c0ba8aae68d3cb6789f0f6e4891cef26cc6d",
"revCount": 6,
"type": "git",
"url": "https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git"
},
"original": {
"type": "git",
"url": "https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1702601832, "lastModified": 1731663789,
"narHash": "sha256-z+GyetKtwj7ZVZrRcI73N8Xy1B3JGAqDyPniBFRpIgo=", "narHash": "sha256-x07g4NcqGP6mQn6AISXJaks9sQYDjZmTMBlKIvajvyc=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "dff64d4ba6e9dc3f0a4ef8737f372a528d5bc8d1", "rev": "035d434d48f4375ac5d3a620954cf5fda7dd7c36",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "owner": "NixOS",
"ref": "nixos-23.11-small", "ref": "nixos-24.05-small",
"type": "indirect" "repo": "nixpkgs",
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1673743903,
"narHash": "sha256-sloY6KYyVOozJ1CkbgJPpZ99TKIjIvM+04V48C04sMQ=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "7555e2dfcbac1533f047021f1744ac8871150f9f",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1702148972, "lastModified": 1730602179,
"narHash": "sha256-h2jODFP6n+ABrUWcGRSVPRFfLOkM9TJ2pO+h+9JcaL0=", "narHash": "sha256-efgLzQAWSzJuCLiCaQUCDu4NudNlHdg2NzGLX5GYaEY=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "b8f33c044e51de6dde3ad80a9676945e0e4e3227", "rev": "3c2f1c4ca372622cb2f9de8016c9a0b1cbd0f37c",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "release-23.05", "ref": "release-24.05",
"repo": "nixpkgs", "repo": "nixpkgs",
"type": "github" "type": "github"
} }
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1702635820, "lastModified": 1731745710,
"narHash": "sha256-rClms9NTmSL/WIN5VmEccVhUExMkjCrRNswxU9QGNNo=", "narHash": "sha256-SVeiClbgqL071JpAspOu0gCkPSAL51kSIRwo4C/pghA=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "02357adddd0889782362d999628de9d309d202dc", "rev": "dfaa4cb76c2d450d8f396bb6b9f43cede3ade129",
"type": "github" "type": "github"
}, },
"original": { "original": {
"id": "nixpkgs", "owner": "NixOS",
"ref": "nixos-unstable-small", "ref": "nixos-unstable-small",
"type": "indirect" "repo": "nixpkgs",
"type": "github"
} }
}, },
"pvv-calendar-bot": { "pvv-calendar-bot": {
@ -146,11 +172,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1693136143, "lastModified": 1723850344,
"narHash": "sha256-amHprjftc3y/bg8yf4hITCLa+ez5HIi0yGfR7TU6UIc=", "narHash": "sha256-aT37O9l9eclWEnqxASVNBL1dKwDHZUOqdbA4VO9DJvw=",
"ref": "refs/heads/main", "ref": "refs/heads/main",
"rev": "a32894b305f042d561500f5799226afd1faf5abb", "rev": "38b66677ab8c01aee10cd59e745af9ce3ea88092",
"revCount": 9, "revCount": 19,
"type": "git", "type": "git",
"url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git" "url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git"
}, },
@ -159,18 +185,62 @@
"url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git" "url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git"
} }
}, },
"pvv-nettsiden": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1725212759,
"narHash": "sha256-yZBsefIarFUEhFRj+rCGMp9Zvag3MCafqV/JfGVRVwc=",
"ref": "refs/heads/master",
"rev": "e7b66b4bc6a89bab74bac45b87e9434f5165355f",
"revCount": 473,
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/nettsiden.git"
},
"original": {
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/nettsiden.git"
}
},
"root": { "root": {
"inputs": { "inputs": {
"disko": "disko", "disko": "disko",
"grzegorz": "grzegorz", "greg-ng": "greg-ng",
"grzegorz-clients": "grzegorz-clients", "grzegorz-clients": "grzegorz-clients",
"matrix-next": "matrix-next", "matrix-next": "matrix-next",
"minecraft-data": "minecraft-data",
"nix-gitea-themes": "nix-gitea-themes",
"nixpkgs": "nixpkgs", "nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable", "nixpkgs-unstable": "nixpkgs-unstable",
"pvv-calendar-bot": "pvv-calendar-bot", "pvv-calendar-bot": "pvv-calendar-bot",
"pvv-nettsiden": "pvv-nettsiden",
"sops-nix": "sops-nix" "sops-nix": "sops-nix"
} }
}, },
"rust-overlay": {
"inputs": {
"nixpkgs": [
"greg-ng",
"nixpkgs"
]
},
"locked": {
"lastModified": 1729391507,
"narHash": "sha256-as0I9xieJUHf7kiK2a9znDsVZQTFWhM1pLivII43Gi0=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "784981a9feeba406de38c1c9a3decf966d853cca",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"sops-nix": { "sops-nix": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -179,11 +249,11 @@
"nixpkgs-stable": "nixpkgs-stable" "nixpkgs-stable": "nixpkgs-stable"
}, },
"locked": { "locked": {
"lastModified": 1702177193, "lastModified": 1731748189,
"narHash": "sha256-J2409SyXROoUHYXVy9h4Pj0VU8ReLuy/mzBc9iK4DBg=", "narHash": "sha256-Zd/Uukvpcu26M6YGhpbsgqm6LUSLz+Q8mDZ5LOEGdiE=",
"owner": "Mic92", "owner": "Mic92",
"repo": "sops-nix", "repo": "sops-nix",
"rev": "d806e546f96c88cd9f7d91c1c19ebc99ba6277d9", "rev": "d2bd7f433b28db6bc7ae03d5eca43564da0af054",
"type": "github" "type": "github"
}, },
"original": { "original": {

103
flake.nix
View File

@ -2,8 +2,8 @@
description = "PVV System flake"; description = "PVV System flake";
inputs = { inputs = {
nixpkgs.url = "nixpkgs/nixos-23.11-small"; nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05-small"; # remember to also update the url in base/services/auto-upgrade.nix
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-small"; nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable-small";
sops-nix.url = "github:Mic92/sops-nix"; sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs"; sops-nix.inputs.nixpkgs.follows = "nixpkgs";
@ -11,15 +11,24 @@
disko.url = "github:nix-community/disko"; disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs"; disko.inputs.nixpkgs.follows = "nixpkgs";
pvv-nettsiden.url = "git+https://git.pvv.ntnu.no/Projects/nettsiden.git";
pvv-nettsiden.inputs.nixpkgs.follows = "nixpkgs";
pvv-calendar-bot.url = "git+https://git.pvv.ntnu.no/Projects/calendar-bot.git"; pvv-calendar-bot.url = "git+https://git.pvv.ntnu.no/Projects/calendar-bot.git";
pvv-calendar-bot.inputs.nixpkgs.follows = "nixpkgs"; pvv-calendar-bot.inputs.nixpkgs.follows = "nixpkgs";
matrix-next.url = "github:dali99/nixos-matrix-modules"; matrix-next.url = "github:dali99/nixos-matrix-modules/v0.6.1";
matrix-next.inputs.nixpkgs.follows = "nixpkgs";
grzegorz.url = "github:Programvareverkstedet/grzegorz"; nix-gitea-themes.url = "git+https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git";
grzegorz.inputs.nixpkgs.follows = "nixpkgs-unstable"; nix-gitea-themes.inputs.nixpkgs.follows = "nixpkgs";
grzegorz-clients.url = "github:Programvareverkstedet/grzegorz-clients";
greg-ng.url = "git+https://git.pvv.ntnu.no/Projects/greg-ng.git";
greg-ng.inputs.nixpkgs.follows = "nixpkgs";
grzegorz-clients.url = "git+https://git.pvv.ntnu.no/Projects/grzegorz-clients.git";
grzegorz-clients.inputs.nixpkgs.follows = "nixpkgs"; grzegorz-clients.inputs.nixpkgs.follows = "nixpkgs";
minecraft-data.url = "git+https://git.pvv.ntnu.no/Drift/minecraft-data.git";
}; };
outputs = { self, nixpkgs, nixpkgs-unstable, sops-nix, disko, ... }@inputs: outputs = { self, nixpkgs, nixpkgs-unstable, sops-nix, disko, ... }@inputs:
@ -30,8 +39,8 @@
"aarch64-linux" "aarch64-linux"
"aarch64-darwin" "aarch64-darwin"
]; ];
forAllSystems = f: nixlib.genAttrs systems (system: f system); forAllSystems = f: nixlib.genAttrs systems f;
allMachines = nixlib.mapAttrsToList (name: _: name) self.nixosConfigurations; allMachines = builtins.attrNames self.nixosConfigurations;
importantMachines = [ importantMachines = [
"bekkalokk" "bekkalokk"
"bicep" "bicep"
@ -40,28 +49,32 @@
"ildkule" "ildkule"
]; ];
in { in {
inherit inputs;
nixosConfigurations = let nixosConfigurations = let
unstablePkgs = nixpkgs-unstable.legacyPackages.x86_64-linux;
nixosConfig = nixpkgs: name: config: nixpkgs.lib.nixosSystem (nixpkgs.lib.recursiveUpdate nixosConfig = nixpkgs: name: config: nixpkgs.lib.nixosSystem (nixpkgs.lib.recursiveUpdate
rec { rec {
system = "x86_64-linux"; system = "x86_64-linux";
specialArgs = { specialArgs = {
inherit nixpkgs-unstable inputs; inherit unstablePkgs inputs;
values = import ./values.nix; values = import ./values.nix;
fp = path: ./${path};
}; };
modules = [ modules = [
./hosts/${name}/configuration.nix ./hosts/${name}/configuration.nix
sops-nix.nixosModules.sops sops-nix.nixosModules.sops
]; ] ++ config.modules or [];
pkgs = import nixpkgs { pkgs = import nixpkgs {
inherit system; inherit system;
overlays = [ overlays = [
inputs.pvv-calendar-bot.overlays.${system}.default # Global overlays go here
]; ] ++ config.overlays or [ ];
}; };
} }
config (removeAttrs config [ "modules" "overlays" ])
); );
stableNixosConfig = nixosConfig nixpkgs; stableNixosConfig = nixosConfig nixpkgs;
@ -69,19 +82,31 @@
in { in {
bicep = stableNixosConfig "bicep" { bicep = stableNixosConfig "bicep" {
modules = [ modules = [
./hosts/bicep/configuration.nix
sops-nix.nixosModules.sops
inputs.matrix-next.nixosModules.default inputs.matrix-next.nixosModules.default
inputs.pvv-calendar-bot.nixosModules.default inputs.pvv-calendar-bot.nixosModules.default
]; ];
overlays = [
inputs.pvv-calendar-bot.overlays.x86_64-linux.default
];
};
bekkalokk = stableNixosConfig "bekkalokk" {
overlays = [
(final: prev: {
heimdal = unstablePkgs.heimdal;
mediawiki-extensions = final.callPackage ./packages/mediawiki-extensions { };
simplesamlphp = final.callPackage ./packages/simplesamlphp { };
bluemap = final.callPackage ./packages/bluemap.nix { };
})
inputs.nix-gitea-themes.overlays.default
inputs.pvv-nettsiden.overlays.default
];
modules = [
inputs.nix-gitea-themes.nixosModules.default
inputs.pvv-nettsiden.nixosModules.default
];
}; };
bekkalokk = stableNixosConfig "bekkalokk" { };
bob = stableNixosConfig "bob" { bob = stableNixosConfig "bob" {
modules = [ modules = [
./hosts/bob/configuration.nix
sops-nix.nixosModules.sops
disko.nixosModules.disko disko.nixosModules.disko
{ disko.devices.disk.disk1.device = "/dev/vda"; } { disko.devices.disk.disk1.device = "/dev/vda"; }
]; ];
@ -92,28 +117,27 @@
brzeczyszczykiewicz = stableNixosConfig "brzeczyszczykiewicz" { brzeczyszczykiewicz = stableNixosConfig "brzeczyszczykiewicz" {
modules = [ modules = [
./hosts/brzeczyszczykiewicz/configuration.nix
sops-nix.nixosModules.sops
inputs.grzegorz.nixosModules.grzegorz-kiosk
inputs.grzegorz-clients.nixosModules.grzegorz-webui inputs.grzegorz-clients.nixosModules.grzegorz-webui
inputs.greg-ng.nixosModules.default
];
overlays = [
inputs.greg-ng.overlays.default
]; ];
}; };
georg = stableNixosConfig "georg" { georg = stableNixosConfig "georg" {
modules = [ modules = [
./hosts/georg/configuration.nix
sops-nix.nixosModules.sops
inputs.grzegorz.nixosModules.grzegorz-kiosk
inputs.grzegorz-clients.nixosModules.grzegorz-webui inputs.grzegorz-clients.nixosModules.grzegorz-webui
inputs.greg-ng.nixosModules.default
];
overlays = [
inputs.greg-ng.overlays.default
]; ];
}; };
buskerud = stableNixosConfig "buskerud" { };
modules = [
./hosts/buskerud/configuration.nix nixosModules = {
sops-nix.nixosModules.sops snakeoil-certs = ./modules/snakeoil-certs.nix;
]; snappymail = ./modules/snappymail.nix;
};
}; };
devShells = forAllSystems (system: { devShells = forAllSystems (system: {
@ -129,7 +153,16 @@
(nixlib.getAttrs importantMachines self.packages.x86_64-linux); (nixlib.getAttrs importantMachines self.packages.x86_64-linux);
all-machines = pkgs.linkFarm "all-machines" all-machines = pkgs.linkFarm "all-machines"
(nixlib.getAttrs allMachines self.packages.x86_64-linux); (nixlib.getAttrs allMachines self.packages.x86_64-linux);
} // nixlib.genAttrs allMachines
simplesamlphp = pkgs.callPackage ./packages/simplesamlphp { };
} //
(nixlib.pipe null [
(_: pkgs.callPackage ./packages/mediawiki-extensions { })
(nixlib.flip builtins.removeAttrs ["override" "overrideDerivation"])
(nixlib.mapAttrs' (name: nixlib.nameValuePair "mediawiki-${name}"))
])
// nixlib.genAttrs allMachines
(machine: self.nixosConfigurations.${machine}.config.system.build.toplevel); (machine: self.nixosConfigurations.${machine}.config.system.build.toplevel);
}; };
}; };

View File

@ -1,22 +1,25 @@
{ pkgs, values, ... }: { fp, pkgs, values, ... }:
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../../base.nix (fp /base)
../../misc/metrics-exporters.nix (fp /misc/metrics-exporters.nix)
#./services/keycloak.nix ./services/bluemap/default.nix
# TODO: set up authentication for the following:
# ./services/website.nix
./services/nginx
./services/gitea/default.nix ./services/gitea/default.nix
./services/idp-simplesamlphp
./services/kerberos
./services/mediawiki
./services/nginx.nix
./services/phpfpm.nix
./services/vaultwarden.nix
./services/webmail ./services/webmail
# ./services/mediawiki.nix ./services/website
./services/well-known
]; ];
sops.defaultSopsFile = ../../secrets/bekkalokk/bekkalokk.yaml; sops.defaultSopsFile = fp /secrets/bekkalokk/bekkalokk.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.age.keyFile = "/var/lib/sops-nix/key.txt"; sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true; sops.age.generateKey = true;
@ -24,8 +27,6 @@
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true; boot.loader.efi.canTouchEfiVariables = true;
virtualisation.podman.enable = true;
networking.hostName = "bekkalokk"; networking.hostName = "bekkalokk";
systemd.network.networks."30-enp2s0" = values.defaultNetworkConfig // { systemd.network.networks."30-enp2s0" = values.defaultNetworkConfig // {
@ -33,6 +34,8 @@
address = with values.hosts.bekkalokk; [ (ipv4 + "/25") (ipv6 + "/64") ]; address = with values.hosts.bekkalokk; [ (ipv4 + "/25") (ipv6 + "/64") ];
}; };
services.btrfs.autoScrub.enable = true;
# Do not change, even during upgrades. # Do not change, even during upgrades.
# See https://search.nixos.org/options?show=system.stateVersion # See https://search.nixos.org/options?show=system.stateVersion
system.stateVersion = "22.11"; system.stateVersion = "22.11";

View File

@ -0,0 +1,83 @@
{ config, lib, pkgs, inputs, ... }:
let
vanillaSurvival = "/var/lib/bluemap/vanilla_survival_world";
in {
imports = [
./module.nix # From danio, pending upstreaming
];
disabledModules = [ "services/web-servers/bluemap.nix" ];
sops.secrets."bluemap/ssh-key" = { };
sops.secrets."bluemap/ssh-known-hosts" = { };
services.bluemap = {
enable = true;
eula = true;
onCalendar = "*-*-* 05:45:00"; # a little over an hour after auto-upgrade
host = "minecraft.pvv.ntnu.no";
maps = {
"verden" = {
settings = {
world = vanillaSurvival;
sorting = 0;
ambient-light = 0.1;
cave-detection-ocean-floor = -5;
marker-sets = inputs.minecraft-data.map-markers.vanillaSurvival.verden;
};
};
"underverden" = {
settings = {
world = "${vanillaSurvival}/DIM-1";
sorting = 100;
sky-color = "#290000";
void-color = "#150000";
ambient-light = 0.6;
world-sky-light = 0;
remove-caves-below-y = -10000;
cave-detection-ocean-floor = -5;
cave-detection-uses-block-light = true;
max-y = 90;
marker-sets = inputs.minecraft-data.map-markers.vanillaSurvival.underverden;
};
};
"enden" = {
settings = {
world = "${vanillaSurvival}/DIM1";
sorting = 200;
sky-color = "#080010";
void-color = "#080010";
ambient-light = 0.6;
world-sky-light = 0;
remove-caves-below-y = -10000;
cave-detection-ocean-floor = -5;
};
};
};
};
services.nginx.virtualHosts."minecraft.pvv.ntnu.no" = {
enableACME = true;
forceSSL = true;
};
# TODO: render somewhere else lmao
systemd.services."render-bluemap-maps" = {
preStart = ''
mkdir -p /var/lib/bluemap/world
${pkgs.rsync}/bin/rsync \
-e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" \
-avz --no-owner --no-group \
root@innovation.pvv.ntnu.no:/ \
${vanillaSurvival}
'';
serviceConfig = {
LoadCredential = [
"sshkey:${config.sops.secrets."bluemap/ssh-key".path}"
"ssh-known-hosts:${config.sops.secrets."bluemap/ssh-known-hosts".path}"
];
};
};
}

View File

@ -0,0 +1,343 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.bluemap;
format = pkgs.formats.hocon { };
coreConfig = format.generate "core.conf" cfg.coreSettings;
webappConfig = format.generate "webapp.conf" cfg.webappSettings;
webserverConfig = format.generate "webserver.conf" cfg.webserverSettings;
storageFolder = pkgs.linkFarm "storage"
(lib.attrsets.mapAttrs' (name: value:
lib.nameValuePair "${name}.conf"
(format.generate "${name}.conf" value))
cfg.storage);
mapsFolder = pkgs.linkFarm "maps"
(lib.attrsets.mapAttrs' (name: value:
lib.nameValuePair "${name}.conf"
(format.generate "${name}.conf" value.settings))
cfg.maps);
webappConfigFolder = pkgs.linkFarm "bluemap-config" {
"maps" = mapsFolder;
"storages" = storageFolder;
"core.conf" = coreConfig;
"webapp.conf" = webappConfig;
"webserver.conf" = webserverConfig;
"packs" = cfg.resourcepacks;
"addons" = cfg.resourcepacks; # TODO
};
renderConfigFolder = name: value: pkgs.linkFarm "bluemap-${name}-config" {
"maps" = pkgs.linkFarm "maps" {
"${name}.conf" = (format.generate "${name}.conf" value.settings);
};
"storages" = storageFolder;
"core.conf" = coreConfig;
"webapp.conf" = format.generate "webapp.conf" (cfg.webappSettings // { "update-settings-file" = false; });
"webserver.conf" = webserverConfig;
"packs" = value.resourcepacks;
"addons" = cfg.resourcepacks; # TODO
};
inherit (lib) mkOption;
in {
options.services.bluemap = {
enable = lib.mkEnableOption "bluemap";
eula = mkOption {
type = lib.types.bool;
description = ''
By changing this option to true you confirm that you own a copy of minecraft Java Edition,
and that you agree to minecrafts EULA.
'';
default = false;
};
defaultWorld = mkOption {
type = lib.types.path;
description = ''
The world used by the default map ruleset.
If you configure your own maps you do not need to set this.
'';
example = lib.literalExpression "\${config.services.minecraft.dataDir}/world";
};
enableRender = mkOption {
type = lib.types.bool;
description = "Enable rendering";
default = true;
};
webRoot = mkOption {
type = lib.types.path;
default = "/var/lib/bluemap/web";
description = "The directory for saving and serving the webapp and the maps";
};
enableNginx = mkOption {
type = lib.types.bool;
default = true;
description = "Enable configuring a virtualHost for serving the bluemap webapp";
};
host = mkOption {
type = lib.types.str;
default = "bluemap.${config.networking.domain}";
defaultText = lib.literalExpression "bluemap.\${config.networking.domain}";
description = "Domain to configure nginx for";
};
onCalendar = mkOption {
type = lib.types.str;
description = ''
How often to trigger rendering the map,
in the format of a systemd timer onCalendar configuration.
See {manpage}`systemd.timer(5)`.
'';
default = "*-*-* 03:10:00";
};
coreSettings = mkOption {
type = lib.types.submodule {
freeformType = format.type;
options = {
data = mkOption {
type = lib.types.path;
description = "Folder for where bluemap stores its data";
default = "/var/lib/bluemap";
};
metrics = lib.mkEnableOption "Sending usage metrics containing the version of bluemap in use";
};
};
description = "Settings for the core.conf file, [see upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/core.conf).";
};
webappSettings = mkOption {
type = lib.types.submodule {
freeformType = format.type;
};
default = {
enabled = true;
webroot = cfg.webRoot;
};
defaultText = lib.literalExpression ''
{
enabled = true;
webroot = config.services.bluemap.webRoot;
}
'';
description = "Settings for the webapp.conf file, see [upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/webapp.conf).";
};
webserverSettings = mkOption {
type = lib.types.submodule {
freeformType = format.type;
options = {
enabled = mkOption {
type = lib.types.bool;
description = ''
Enable bluemap's built-in webserver.
Disabled by default in nixos for use of nginx directly.
'';
default = false;
};
};
};
default = { };
description = ''
Settings for the webserver.conf file, usually not required.
[See upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/webserver.conf).
'';
};
maps = mkOption {
type = lib.types.attrsOf (lib.types.submodule {
options = {
resourcepacks = mkOption {
type = lib.types.path;
default = cfg.resourcepacks;
defaultText = lib.literalExpression "config.services.bluemap.resourcepacks";
description = "A set of resourcepacks/mods to extract models from loaded in alphabetical order";
};
settings = mkOption {
type = (lib.types.submodule {
freeformType = format.type;
options = {
world = mkOption {
type = lib.types.path;
description = "Path to world folder containing the dimension to render";
};
};
});
description = ''
Settings for files in `maps/`.
See the default for an example with good options for the different world types.
For valid values [consult upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/maps/map.conf).
'';
};
};
});
default = {
"overworld".settings = {
world = "${cfg.defaultWorld}";
ambient-light = 0.1;
cave-detection-ocean-floor = -5;
};
"nether".settings = {
world = "${cfg.defaultWorld}/DIM-1";
sorting = 100;
sky-color = "#290000";
void-color = "#150000";
ambient-light = 0.6;
world-sky-light = 0;
remove-caves-below-y = -10000;
cave-detection-ocean-floor = -5;
cave-detection-uses-block-light = true;
max-y = 90;
};
"end".settings = {
world = "${cfg.defaultWorld}/DIM1";
sorting = 200;
sky-color = "#080010";
void-color = "#080010";
ambient-light = 0.6;
world-sky-light = 0;
remove-caves-below-y = -10000;
cave-detection-ocean-floor = -5;
};
};
defaultText = lib.literalExpression ''
{
"overworld".settings = {
world = "''${cfg.defaultWorld}";
ambient-light = 0.1;
cave-detection-ocean-floor = -5;
};
"nether".settings = {
world = "''${cfg.defaultWorld}/DIM-1";
sorting = 100;
sky-color = "#290000";
void-color = "#150000";
ambient-light = 0.6;
world-sky-light = 0;
remove-caves-below-y = -10000;
cave-detection-ocean-floor = -5;
cave-detection-uses-block-light = true;
max-y = 90;
};
"end".settings = {
world = "''${cfg.defaultWorld}/DIM1";
sorting = 200;
sky-color = "#080010";
void-color = "#080010";
ambient-light = 0.6;
world-sky-light = 0;
remove-caves-below-y = -10000;
cave-detection-ocean-floor = -5;
};
};
'';
description = ''
map-specific configuration.
These correspond to views in the webapp and are usually
different dimension of a world or different render settings of the same dimension.
If you set anything in this option you must configure all dimensions yourself!
'';
};
storage = mkOption {
type = lib.types.attrsOf (lib.types.submodule {
freeformType = format.type;
options = {
storage-type = mkOption {
type = lib.types.enum [ "FILE" "SQL" ];
description = "Type of storage config";
default = "FILE";
};
};
});
description = ''
Where the rendered map will be stored.
Unless you are doing something advanced you should probably leave this alone and configure webRoot instead.
[See upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/tree/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/storages)
'';
default = {
"file" = {
root = "${cfg.webRoot}/maps";
};
};
defaultText = lib.literalExpression ''
{
"file" = {
root = "''${config.services.bluemap.webRoot}/maps";
};
}
'';
};
resourcepacks = mkOption {
type = lib.types.path;
default = pkgs.linkFarm "resourcepacks" { };
description = ''
A set of resourcepacks/mods to extract models from loaded in alphabetical order.
Can be overriden on a per-map basis with `services.bluemap.maps.<name>.resourcepacks`.
'';
};
};
config = lib.mkIf cfg.enable {
assertions =
[ { assertion = config.services.bluemap.eula;
message = ''
You have enabled bluemap but have not accepted minecraft's EULA.
You can achieve this through setting `services.bluemap.eula = true`
'';
}
];
services.bluemap.coreSettings.accept-download = cfg.eula;
systemd.services."render-bluemap-maps" = lib.mkIf cfg.enableRender {
serviceConfig = {
Type = "oneshot";
Group = "nginx";
UMask = "026";
};
script = lib.strings.concatStringsSep "\n" ((lib.attrsets.mapAttrsToList
(name: value: "${lib.getExe pkgs.bluemap} -c ${renderConfigFolder name value} -r")
cfg.maps) ++ [ "${lib.getExe pkgs.bluemap} -c ${webappConfigFolder} -gs" ]);
};
systemd.timers."render-bluemap-maps" = lib.mkIf cfg.enableRender {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = cfg.onCalendar;
Persistent = true;
Unit = "render-bluemap-maps.service";
};
};
services.nginx.virtualHosts = lib.mkIf cfg.enableNginx {
"${cfg.host}" = {
root = config.services.bluemap.webRoot;
locations = {
"~* ^/maps/[^/]*/tiles/".extraConfig = ''
error_page 404 = @empty;
'';
"@empty".return = "204";
};
};
};
};
meta = {
maintainers = with lib.maintainers; [ dandellion h7x4 ];
};
}

View File

@ -15,9 +15,9 @@ let
enable = true; enable = true;
name = "git-runner-${name}"; url = "https://git.pvv.ntnu.no"; name = "git-runner-${name}"; url = "https://git.pvv.ntnu.no";
labels = [ labels = [
"debian-latest:docker://node:18-bullseye" "debian-latest:docker://node:18-bullseye"
"ubuntu-latest:docker://node:18-bullseye" "ubuntu-latest:docker://node:18-bullseye"
]; ];
tokenFile = config.sops.secrets."gitea/runners/${name}".path; tokenFile = config.sops.secrets."gitea/runners/${name}".path;
}; };
}; };
@ -27,4 +27,5 @@ lib.mkMerge [
(mkRunner "alpha") (mkRunner "alpha")
(mkRunner "beta") (mkRunner "beta")
(mkRunner "epsilon") (mkRunner "epsilon")
{ virtualisation.podman.enable = true; }
] ]

View File

@ -1,4 +1,4 @@
{ config, values, pkgs, ... }: { config, values, fp, pkgs, lib, ... }:
let let
cfg = config.services.gitea; cfg = config.services.gitea;
domain = "git.pvv.ntnu.no"; domain = "git.pvv.ntnu.no";
@ -6,6 +6,9 @@ let
in { in {
imports = [ imports = [
./ci.nix ./ci.nix
./gpg.nix
./import-users
./web-secret-provider
]; ];
sops.secrets = { sops.secrets = {
@ -13,41 +16,119 @@ in {
owner = "gitea"; owner = "gitea";
group = "gitea"; group = "gitea";
}; };
"gitea/passwd-ssh-key" = { }; "gitea/email-password" = {
"gitea/ssh-known-hosts" = { }; owner = "gitea";
"gitea/import-user-env" = { }; group = "gitea";
};
}; };
services.gitea = { services.gitea = {
enable = true; enable = true;
stateDir = "/data/gitea";
appName = "PVV Git"; appName = "PVV Git";
database = { database = {
type = "postgres"; type = "postgres";
host = "postgres.pvv.ntnu.no"; host = "postgres.pvv.ntnu.no";
port = config.services.postgresql.port; port = config.services.postgresql.settings.port;
passwordFile = config.sops.secrets."gitea/database".path; passwordFile = config.sops.secrets."gitea/database".path;
createDatabase = false; createDatabase = false;
}; };
mailerPasswordFile = config.sops.secrets."gitea/email-password".path;
# https://docs.gitea.com/administration/config-cheat-sheet
settings = { settings = {
server = { server = {
DOMAIN = domain; DOMAIN = domain;
ROOT_URL = "https://${domain}/"; ROOT_URL = "https://${domain}/";
PROTOCOL = "http+unix"; PROTOCOL = "http+unix";
SSH_PORT = sshPort; SSH_PORT = sshPort;
START_SSH_SERVER = true; START_SSH_SERVER = true;
START_LFS_SERVER = true;
LANDING_PAGE = "explore";
};
mailer = {
ENABLED = true;
FROM = "gitea@pvv.ntnu.no";
PROTOCOL = "smtp";
SMTP_ADDR = "smtp.pvv.ntnu.no";
SMTP_PORT = 587;
USER = "gitea@pvv.ntnu.no";
SUBJECT_PREFIX = "[pvv-git]";
};
metrics = {
ENABLED = true;
ENABLED_ISSUE_BY_LABEL = true;
ENABLED_ISSUE_BY_REPOSITORY = true;
}; };
indexer.REPO_INDEXER_ENABLED = true; indexer.REPO_INDEXER_ENABLED = true;
service.DISABLE_REGISTRATION = true; service = {
DISABLE_REGISTRATION = true;
ENABLE_NOTIFY_MAIL = true;
AUTO_WATCH_NEW_REPOS = false;
};
admin.DEFAULT_EMAIL_NOTIFICATIONS = "onmention";
session.COOKIE_SECURE = true; session.COOKIE_SECURE = true;
database.LOG_SQL = false; database.LOG_SQL = false;
repository = {
PREFERRED_LICENSES = lib.concatStringsSep "," [
"AGPL-3.0-only"
"AGPL-3.0-or-later"
"Apache-2.0"
"BSD-3-Clause"
"CC-BY-4.0"
"CC-BY-NC-4.0"
"CC-BY-NC-ND-4.0"
"CC-BY-NC-SA-4.0"
"CC-BY-ND-4.0"
"CC-BY-SA-4.0"
"CC0-1.0"
"GPL-2.0-only"
"GPL-3.0-only"
"GPL-3.0-or-later"
"LGPL-3.0-linking-exception"
"LGPL-3.0-only"
"LGPL-3.0-or-later"
"MIT"
"MPL-2.0"
"Unlicense"
];
DEFAULT_REPO_UNITS = lib.concatStringsSep "," [
"repo.code"
"repo.issues"
"repo.pulls"
"repo.releases"
];
};
picture = { picture = {
DISABLE_GRAVATAR = true; DISABLE_GRAVATAR = true;
ENABLE_FEDERATED_AVATAR = false; ENABLE_FEDERATED_AVATAR = false;
}; };
actions.ENABLED = true; actions.ENABLED = true;
ui = {
REACTIONS = lib.concatStringsSep "," [
"+1"
"-1"
"laugh"
"confused"
"heart"
"hooray"
"rocket"
"eyes"
"100"
"anger"
"astonished"
"no_good"
"ok_hand"
"pensive"
"pizza"
"point_up"
"sob"
"skull"
"upside_down_face"
"shrug"
];
};
"ui.meta".DESCRIPTION = "Bokstavelig talt programvareverkstedet"; "ui.meta".DESCRIPTION = "Bokstavelig talt programvareverkstedet";
}; };
}; };
@ -57,49 +138,54 @@ in {
services.nginx.virtualHosts."${domain}" = { services.nginx.virtualHosts."${domain}" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
locations."/" = { kTLS = true;
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}"; locations = {
recommendedProxySettings = true; "/" = {
extraConfig = '' proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
client_max_body_size 512M; extraConfig = ''
''; client_max_body_size 512M;
'';
};
"/metrics" = {
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
extraConfig = ''
allow ${values.hosts.ildkule.ipv4}/32;
deny all;
'';
};
}; };
}; };
networking.firewall.allowedTCPPorts = [ sshPort ]; networking.firewall.allowedTCPPorts = [ sshPort ];
# Automatically import users # Extra customization
systemd.services.gitea-import-users = {
enable = true;
preStart=''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /tmp/passwd-import'';
serviceConfig = {
ExecStart = pkgs.writers.writePython3 "gitea-import-users" { libraries = [ pkgs.python3Packages.requests ]; } (builtins.readFile ./gitea-import-users.py);
LoadCredential=[
"sshkey:${config.sops.secrets."gitea/passwd-ssh-key".path}"
"ssh-known-hosts:${config.sops.secrets."gitea/ssh-known-hosts".path}"
];
DynamicUser="yes";
EnvironmentFile=config.sops.secrets."gitea/import-user-env".path;
};
};
systemd.timers.gitea-import-users = { services.gitea-themes.monokai = pkgs.gitea-theme-monokai;
requires = [ "gitea.service" ];
after = [ "gitea.service" ];
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 02:00:00";
Persistent = true;
Unit = "gitea-import-users.service";
};
};
system.activationScripts.linkGiteaLogo.text = let systemd.services.install-gitea-customization = {
logo-svg = ../../../../assets/logo_blue_regular.svg; description = "Install extra customization in gitea's CUSTOM_DIR";
logo-png = ../../../../assets/logo_blue_regular.png; wantedBy = [ "gitea.service" ];
in '' requiredBy = [ "gitea.service" ];
install -Dm444 ${logo-svg} ${cfg.stateDir}/custom/public/img/logo.svg
install -Dm444 ${logo-png} ${cfg.stateDir}/custom/public/img/logo.png serviceConfig = {
install -Dm444 ${./loading.apng} ${cfg.stateDir}/custom/public/img/loading.png Type = "oneshot";
''; User = cfg.user;
Group = cfg.group;
};
script = let
logo-svg = fp /assets/logo_blue_regular.svg;
logo-png = fp /assets/logo_blue_regular.png;
extraLinks = pkgs.writeText "gitea-extra-links.tmpl" ''
<a class="item" href="https://www.pvv.ntnu.no/">PVV</a>
<a class="item" href="https://wiki.pvv.ntnu.no/">Wiki</a>
<a class="item" href="https://git.pvv.ntnu.no/Drift/-/projects/4">Tokyo Drift Issues</a>
'';
in ''
install -Dm444 ${logo-svg} ${cfg.customDir}/public/assets/img/logo.svg
install -Dm444 ${logo-png} ${cfg.customDir}/public/assets/img/logo.png
install -Dm444 ${./loading.apng} ${cfg.customDir}/public/assets/img/loading.png
install -Dm444 ${extraLinks} ${cfg.customDir}/templates/custom/extra_links.tmpl
'';
};
} }

View File

@ -1,94 +0,0 @@
import requests
import secrets
import os
EMAIL_DOMAIN = os.getenv('EMAIL_DOMAIN')
if EMAIL_DOMAIN is None:
EMAIL_DOMAIN = 'pvv.ntnu.no'
API_TOKEN = os.getenv('API_TOKEN')
if API_TOKEN is None:
raise Exception('API_TOKEN not set')
GITEA_API_URL = os.getenv('GITEA_API_URL')
if GITEA_API_URL is None:
GITEA_API_URL = 'https://git.pvv.ntnu.no/api/v1'
BANNED_SHELLS = [
"/usr/bin/nologin",
"/usr/sbin/nologin",
"/sbin/nologin",
"/bin/false",
"/bin/msgsh",
]
existing_users = {}
# This function should only ever be called when adding users
# from the passwd file
def add_user(username, name):
user = {
"full_name": name,
"username": username,
"login_name": username,
"visibility": "public",
"source_id": 1, # 1 = SMTP
}
if username not in existing_users:
user["password"] = secrets.token_urlsafe(32)
user["must_change_password"] = False
user["visibility"] = "private"
user["email"] = username + '@' + EMAIL_DOMAIN
r = requests.post(GITEA_API_URL + '/admin/users', json=user,
headers={'Authorization': 'token ' + API_TOKEN})
if r.status_code != 201:
print('ERR: Failed to create user ' + username + ': ' + r.text)
return
print('Created user ' + username)
existing_users[username] = user
else:
r = requests.patch(GITEA_API_URL + f'/admin/users/{username}',
json=user,
headers={'Authorization': 'token ' + API_TOKEN})
if r.status_code != 200:
print('ERR: Failed to update user ' + username + ': ' + r.text)
return
print('Updated user ' + username)
def main():
# Fetch existing users
r = requests.get(GITEA_API_URL + '/admin/users',
headers={'Authorization': 'token ' + API_TOKEN})
if r.status_code != 200:
raise Exception('Failed to get users: ' + r.text)
for user in r.json():
existing_users[user['login']] = user
# Read the file, add each user
with open("/tmp/passwd-import", 'r') as f:
for line in f.readlines():
uid = int(line.split(':')[2])
if uid < 1000:
continue
shell = line.split(':')[-1]
if shell in BANNED_SHELLS:
continue
username = line.split(':')[0]
name = line.split(':')[4].split(',')[0]
add_user(username, name)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,38 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.gitea;
GNUPGHOME = "${config.users.users.gitea.home}/gnupg";
in
{
sops.secrets."gitea/gpg-signing-key" = {
owner = cfg.user;
inherit (cfg) group;
};
systemd.services.gitea.environment = { inherit GNUPGHOME; };
systemd.tmpfiles.settings."20-gitea-gnugpg".${GNUPGHOME}.d = {
inherit (cfg) user group;
mode = "700";
};
systemd.services.gitea-ensure-gnupg-homedir = {
description = "Import gpg key for gitea";
environment = { inherit GNUPGHOME; };
serviceConfig = {
Type = "oneshot";
User = cfg.user;
PrivateNetwork = true;
};
script = ''
${lib.getExe pkgs.gnupg} --import ${config.sops.secrets."gitea/gpg-signing-key".path}
'';
};
services.gitea.settings."repository.signing" = {
SIGNING_KEY = "0549C43374D2253C";
SIGNING_NAME = "PVV Git";
SIGNING_EMAIL = "gitea@git.pvv.ntnu.no";
INITIAL_COMMIT = "always";
};
}

View File

@ -0,0 +1,41 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.gitea;
in
{
sops.secrets = {
"gitea/passwd-ssh-key" = { };
"gitea/ssh-known-hosts" = { };
"gitea/import-user-env" = { };
};
systemd.services.gitea-import-users = lib.mkIf cfg.enable {
enable = true;
preStart=''${pkgs.rsync}/bin/rsync -e "${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$CREDENTIALS_DIRECTORY/ssh-known-hosts -i $CREDENTIALS_DIRECTORY/sshkey" -a pvv@smtp.pvv.ntnu.no:/etc/passwd /tmp/passwd-import'';
serviceConfig = {
ExecStart = pkgs.writers.writePython3 "gitea-import-users" {
flakeIgnore = [
"E501" # Line over 80 chars lol
];
libraries = with pkgs.python3Packages; [ requests ];
} (builtins.readFile ./gitea-import-users.py);
LoadCredential=[
"sshkey:${config.sops.secrets."gitea/passwd-ssh-key".path}"
"ssh-known-hosts:${config.sops.secrets."gitea/ssh-known-hosts".path}"
];
DynamicUser="yes";
EnvironmentFile=config.sops.secrets."gitea/import-user-env".path;
};
};
systemd.timers.gitea-import-users = lib.mkIf cfg.enable {
requires = [ "gitea.service" ];
after = [ "gitea.service" ];
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 02:00:00";
Persistent = true;
Unit = "gitea-import-users.service";
};
};
}

View File

@ -0,0 +1,198 @@
import requests
import secrets
import os
EMAIL_DOMAIN = os.getenv('EMAIL_DOMAIN')
if EMAIL_DOMAIN is None:
EMAIL_DOMAIN = 'pvv.ntnu.no'
API_TOKEN = os.getenv('API_TOKEN')
if API_TOKEN is None:
raise Exception('API_TOKEN not set')
GITEA_API_URL = os.getenv('GITEA_API_URL')
if GITEA_API_URL is None:
GITEA_API_URL = 'https://git.pvv.ntnu.no/api/v1'
def gitea_list_all_users() -> dict[str, dict[str, any]] | None:
r = requests.get(
GITEA_API_URL + '/admin/users',
headers={'Authorization': 'token ' + API_TOKEN}
)
if r.status_code != 200:
print('Failed to get users:', r.text)
return None
return {user['login']: user for user in r.json()}
def gitea_create_user(username: str, userdata: dict[str, any]) -> bool:
r = requests.post(
GITEA_API_URL + '/admin/users',
json=userdata,
headers={'Authorization': 'token ' + API_TOKEN},
)
if r.status_code != 201:
print(f'ERR: Failed to create user {username}:', r.text)
return False
return True
def gitea_edit_user(username: str, userdata: dict[str, any]) -> bool:
r = requests.patch(
GITEA_API_URL + f'/admin/users/{username}',
json=userdata,
headers={'Authorization': 'token ' + API_TOKEN},
)
if r.status_code != 200:
print(f'ERR: Failed to update user {username}:', r.text)
return False
return True
def gitea_list_teams_for_organization(org: str) -> dict[str, any] | None:
r = requests.get(
GITEA_API_URL + f'/orgs/{org}/teams',
headers={'Authorization': 'token ' + API_TOKEN},
)
if r.status_code != 200:
print(f"ERR: Failed to list teams for {org}:", r.text)
return None
return {team['name']: team for team in r.json()}
def gitea_add_user_to_organization_team(username: str, team_id: int) -> bool:
r = requests.put(
GITEA_API_URL + f'/teams/{team_id}/members/{username}',
headers={'Authorization': 'token ' + API_TOKEN},
)
if r.status_code != 204:
print(f'ERR: Failed to add user {username} to org team {team_id}:', r.text)
return False
return True
# If a passwd user has one of the following shells,
# it is most likely not a PVV user, but rather a system user.
# Users with these shells should thus be ignored.
BANNED_SHELLS = [
"/usr/bin/nologin",
"/usr/sbin/nologin",
"/sbin/nologin",
"/bin/false",
"/bin/msgsh",
]
# Reads out a passwd-file line for line, and filters out
# real PVV users (as opposed to system users meant for daemons and such)
def passwd_file_parser(passwd_path):
with open(passwd_path, 'r') as f:
for line in f.readlines():
uid = int(line.split(':')[2])
if uid < 1000:
continue
shell = line.split(':')[-1]
if shell in BANNED_SHELLS:
continue
username = line.split(':')[0]
name = line.split(':')[4].split(',')[0]
yield (username, name)
# This function either creates a new user in gitea
# and fills it out with some default information if
# it does not exist, or ensures that the default information
# is correct if the user already exists. All user information
# (including non-default fields) is pulled from gitea and added
# to the `existing_users` dict
def add_or_patch_gitea_user(
username: str,
name: str,
existing_users: dict[str, dict[str, any]],
) -> None:
user = {
"full_name": name,
"username": username,
"login_name": username,
"source_id": 1, # 1 = SMTP
}
if username not in existing_users:
user["password"] = secrets.token_urlsafe(32)
user["must_change_password"] = False
user["visibility"] = "private"
user["email"] = username + '@' + EMAIL_DOMAIN
if not gitea_create_user(username, user):
return
print('Created user', username)
existing_users[username] = user
else:
user["visibility"] = existing_users[username]["visibility"]
if not gitea_edit_user(username, user):
return
print('Updated user', username)
# This function adds a user to a gitea team (part of organization)
# if the user is not already part of said team.
def ensure_gitea_user_is_part_of_team(
username: str,
org: str,
team_name: str,
) -> None:
teams = gitea_list_teams_for_organization(org)
if teams is None:
return
if team_name not in teams:
print(f'ERR: could not find team "{team_name}" in organization "{org}"')
gitea_add_user_to_organization_team(username, teams[team_name]['id'])
print(f'User {username} is now part of {org}/{team_name}')
# List of teams that all users should be part of by default
COMMON_USER_TEAMS = [
("Projects", "Members"),
("Kurs", "Members"),
]
def main():
existing_users = gitea_list_all_users()
if existing_users is None:
exit(1)
for username, name in passwd_file_parser("/tmp/passwd-import"):
print(f"Processing {username}")
add_or_patch_gitea_user(username, name, existing_users)
for org, team_name in COMMON_USER_TEAMS:
ensure_gitea_user_is_part_of_team(username, org, team_name)
print()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,114 @@
{ config, pkgs, lib, ... }:
let
organizations = [
"Drift"
"Projects"
"Kurs"
];
giteaCfg = config.services.gitea;
giteaWebSecretProviderScript = pkgs.writers.writePython3 "gitea-web-secret-provider" {
libraries = with pkgs.python3Packages; [ requests ];
flakeIgnore = [
"E501" # Line over 80 chars lol
"E201" # "whitespace after {"
"E202" # "whitespace after }"
"E251" # unexpected spaces around keyword / parameter equals
"W391" # Newline at end of file
];
makeWrapperArgs = [
"--prefix PATH : ${(lib.makeBinPath [ pkgs.openssh ])}"
];
} (builtins.readFile ./gitea-web-secret-provider.py);
in
{
users.groups."gitea-web" = { };
users.users."gitea-web" = {
group = "gitea-web";
isSystemUser = true;
};
sops.secrets."gitea/web-secret-provider/token" = {
owner = "gitea-web";
group = "gitea-web";
restartUnits = [
"gitea-web-secret-provider@"
] ++ (map (org: "gitea-web-secret-provider@${org}") organizations);
};
systemd.slices.system-giteaweb = {
description = "Gitea web directories";
};
# https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Specifiers
# %i - instance name (after the @)
# %d - secrets directory
systemd.services."gitea-web-secret-provider@" = {
description = "Ensure all repos in %i has an SSH key to push web content";
requires = [ "gitea.service" "network.target" ];
serviceConfig = {
Slice = "system-giteaweb.slice";
Type = "oneshot";
ExecStart = let
args = lib.cli.toGNUCommandLineShell { } {
org = "%i";
token-path = "%d/token";
api-url = "${giteaCfg.settings.server.ROOT_URL}api/v1";
key-dir = "/var/lib/gitea-web/keys/%i";
authorized-keys-path = "/var/lib/gitea-web/authorized_keys.d/%i";
rrsync-script = pkgs.writeShellScript "rrsync-chown" ''
${lib.getExe pkgs.rrsync} -wo "$1"
${pkgs.coreutils}/bin/chown -R gitea-web:gitea-web "$1"
'';
web-dir = "/var/lib/gitea-web/web";
};
in "${giteaWebSecretProviderScript} ${args}";
User = "gitea-web";
Group = "gitea-web";
StateDirectory = "gitea-web";
StateDirectoryMode = "0750";
LoadCredential = [
"token:${config.sops.secrets."gitea/web-secret-provider/token".path}"
];
NoNewPrivileges = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectSystem = true;
ProtectHome = true;
ProtectControlGroups = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
RestrictRealtime = true;
RestrictSUIDSGID = true;
MemoryDenyWriteExecute = true;
LockPersonality = true;
};
};
systemd.timers."gitea-web-secret-provider@" = {
description = "Ensure all repos in %i has an SSH key to push web content";
timerConfig = {
RandomizedDelaySec = "1h";
Persistent = true;
Unit = "gitea-web-secret-provider@%i.service";
OnCalendar = "daily";
};
};
systemd.targets.timers.wants = map (org: "gitea-web-secret-provider@${org}.timer") organizations;
services.openssh.authorizedKeysFiles = map (org: "/var/lib/gitea-web/authorized_keys.d/${org}") organizations;
users.users.nginx.extraGroups = [ "gitea-web" ];
services.nginx.virtualHosts."pages.pvv.ntnu.no" = {
kTLS = true;
forceSSL = true;
enableACME = true;
root = "/var/lib/gitea-web/web";
};
}

View File

@ -0,0 +1,112 @@
import argparse
import hashlib
import os
import requests
import subprocess
from pathlib import Path
def parse_args():
parser = argparse.ArgumentParser(description="Generate SSH keys for Gitea repositories and add them as secrets")
parser.add_argument("--org", required=True, type=str, help="The organization to generate keys for")
parser.add_argument("--token-path", metavar='PATH', required=True, type=Path, help="Path to a file containing the Gitea API token")
parser.add_argument("--api-url", metavar='URL', type=str, help="The URL of the Gitea API", default="https://git.pvv.ntnu.no/api/v1")
parser.add_argument("--key-dir", metavar='PATH', type=Path, help="The directory to store the generated keys in", default="/run/gitea-web-secret-provider")
parser.add_argument("--authorized-keys-path", metavar='PATH', type=Path, help="The path to the resulting authorized_keys file", default="/etc/ssh/authorized_keys.d/gitea-web-secret-provider")
parser.add_argument("--rrsync-script", metavar='PATH', type=Path, help="The path to a rrsync script, taking the destination path as its single argument")
parser.add_argument("--web-dir", metavar='PATH', type=Path, help="The directory to sync the repositories to", default="/var/www")
parser.add_argument("--force", action="store_true", help="Overwrite existing keys")
return parser.parse_args()
def add_secret(args: argparse.Namespace, token: str, repo: str, name: str, secret: str):
result = requests.put(
f"{args.api_url}/repos/{args.org}/{repo}/actions/secrets/{name}",
json = { 'data': secret },
headers = { 'Authorization': 'token ' + token },
)
if result.status_code not in (201, 204):
raise Exception(f"Failed to add secret: {result.json()}")
def get_org_repo_list(args: argparse.Namespace, token: str):
result = requests.get(
f"{args.api_url}/orgs/{args.org}/repos",
headers = { 'Authorization': 'token ' + token },
)
return [repo["name"] for repo in result.json()]
def generate_ssh_key(args: argparse.Namespace, repository: str):
keyname = hashlib.sha256(args.org.encode() + repository.encode()).hexdigest()
key_path = args.key_dir / keyname
if not key_path.is_file() or args.force:
subprocess.run(
[
"ssh-keygen",
*("-t", "ed25519"),
*("-f", key_path),
*("-N", ""),
*("-C", f"{args.org}/{repository}"),
],
check=True,
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print(f"Generated SSH key for `{args.org}/{repository}`")
with open(key_path, "r") as f:
private_key = f.read()
pub_key_path = args.key_dir / (keyname + '.pub')
with open(pub_key_path, "r") as f:
public_key = f.read()
return private_key, public_key
SSH_OPTS = ",".join([
"restrict",
"no-agent-forwarding",
"no-port-forwarding",
"no-pty",
"no-X11-forwarding",
])
def generate_authorized_keys(args: argparse.Namespace, repo_public_keys: list[tuple[str, str]]):
lines = []
for repo, public_key in repo_public_keys:
command = f"{args.rrsync_script} {args.web_dir}/{args.org}/{repo}"
lines.append(f'command="{command}",{SSH_OPTS} {public_key}')
with open(args.authorized_keys_path, "w") as f:
f.writelines(lines)
def main():
args = parse_args()
with open(args.token_path, "r") as f:
token = f.read().strip()
os.makedirs(args.key_dir, 0o700, exist_ok=True)
os.makedirs(args.authorized_keys_path.parent, 0o700, exist_ok=True)
repos = get_org_repo_list(args, token)
print(f'Found {len(repos)} repositories in `{args.org}`')
repo_public_keys = []
for repo in repos:
print(f"Locating key for `{args.org}/{repo}`")
private_key, public_key = generate_ssh_key(args, repo)
add_secret(args, token, repo, "WEB_SYNC_SSH_KEY", private_key)
repo_public_keys.append((repo, public_key))
generate_authorized_keys(args, repo_public_keys)
print(f"Wrote authorized_keys file to `{args.authorized_keys_path}`")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,135 @@
<?php
/**
* Authenticate using HTTP login.
*
* @author Yorn de Jong
* @author Oystein Kristoffer Tveit
* @package simpleSAMLphp
*/
namespace SimpleSAML\Module\authpwauth\Auth\Source;
class PwAuth extends \SimpleSAML\Module\core\Auth\UserPassBase
{
protected $pwauth_bin_path;
protected $mail_domain;
public function __construct(array $info, array &$config) {
assert('is_array($info)');
assert('is_array($config)');
/* Call the parent constructor first, as required by the interface. */
parent::__construct($info, $config);
$this->pwauth_bin_path = $config['pwauth_bin_path'];
if (array_key_exists('mail_domain', $config)) {
$this->mail_domain = '@' . ltrim($config['mail_domain'], '@');
}
}
public function login(string $username, string $password): array {
$username = strtolower( $username );
if (!file_exists($this->pwauth_bin_path)) {
die("Could not find pwauth binary");
return false;
}
if (!is_executable($this->pwauth_bin_path)) {
die("pwauth binary is not executable");
return false;
}
$handle = popen($this->pwauth_bin_path, 'w');
if ($handle === FALSE) {
die("Error opening pipe to pwauth");
return false;
}
$data = "$username\n$password\n";
if (fwrite($handle, $data) !== strlen($data)) {
die("Error writing to pwauth pipe");
return false;
}
# Is the password valid?
$result = pclose( $handle );
if ($result !== 0) {
if (!in_array($result, [1, 2, 3, 4, 5, 6, 7], true)) {
die("pwauth returned $result for username $username");
}
throw new \SimpleSAML\Error\Error('WRONGUSERPASS');
}
/*
$ldap = ldap_connect('129.241.210.159', 389);
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_start_tls($ldap);
ldap_bind($ldap, 'passordendrer@pvv.ntnu.no', 'Oi7aekoh');
$search = ldap_search($ldap, 'DC=pvv,DC=ntnu,DC=no', '(sAMAccountName='.ldap_escape($username, '', LDAP_ESCAPE_FILTER).')');
$entry = ldap_first_entry($ldap, $search);
$dn = ldap_get_dn($ldap, $entry);
$newpassword = mb_convert_encoding("\"$password\"", 'UTF-16LE', 'UTF-8');
ldap_modify_batch($ldap, $dn, [
#[
# 'modtype' => LDAP_MODIFY_BATCH_REMOVE,
# 'attrib' => 'unicodePwd',
# 'values' => [$password],
#],
[
#'modtype' => LDAP_MODIFY_BATCH_ADD,
'modtype' => LDAP_MODIFY_BATCH_REPLACE,
'attrib' => 'unicodePwd',
'values' => [$newpassword],
],
]);
*/
#0 - Login OK.
#1 - Nonexistant login or (for some configurations) incorrect password.
#2 - Incorrect password (for some configurations).
#3 - Uid number is below MIN_UNIX_UID value configured in config.h.
#4 - Login ID has expired.
#5 - Login's password has expired.
#6 - Logins to system have been turned off (usually by /etc/nologin file).
#7 - Limit on number of bad logins exceeded.
#50 - pwauth was not run with real uid SERVER_UID. If you get this
# this error code, you probably have SERVER_UID set incorrectly
# in pwauth's config.h file.
#51 - pwauth was not given a login & password to check. The means
# the passing of data from mod_auth_external to pwauth is messed
# up. Most likely one is trying to pass data via environment
# variables, while the other is trying to pass data via a pipe.
#52 - one of several possible internal errors occured.
$uid = $username;
# TODO: Reinstate this code once passwd is working...
/*
$cn = trim(shell_exec('getent passwd '.escapeshellarg($uid).' | cut -d: -f5 | cut -d, -f1'));
$groups = preg_split('_\\s_', shell_exec('groups '.escapeshellarg($uid)));
array_shift($groups);
array_shift($groups);
array_pop($groups);
$info = posix_getpwnam($uid);
$group = $info['gid'];
if (!in_array($group, $groups)) {
$groups[] = $group;
}
*/
$cn = "Unknown McUnknown";
$groups = array();
$result = array(
'uid' => array($uid),
'cn' => array($cn),
'group' => $groups,
);
if (isset($this->mail_domain)) {
$result['mail'] = array($uid.$this->mail_domain);
}
return $result;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,214 @@
{ config, pkgs, lib, ... }:
let
pwAuthScript = pkgs.writeShellApplication {
name = "pwauth";
runtimeInputs = with pkgs; [ coreutils heimdal ];
text = ''
read -r user1
user2="$(echo -n "$user1" | tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz')"
if test "$user1" != "$user2"
then
read -r _
exit 2
fi
kinit --password-file=STDIN "''${user1}@PVV.NTNU.NO" >/dev/null 2>/dev/null
kdestroy >/dev/null 2>/dev/null
'';
};
package = pkgs.simplesamlphp.override {
extra_files = {
# NOTE: Using self signed certificate created 30. march 2024, with command:
# openssl req -newkey rsa:4096 -new -x509 -days 365 -nodes -out idp.crt -keyout idp.pem
"metadata/saml20-idp-hosted.php" = pkgs.writeText "saml20-idp-remote.php" ''
<?php
$metadata['https://idp.pvv.ntnu.no/'] = array(
'host' => '__DEFAULT__',
'privatekey' => '${config.sops.secrets."idp/privatekey".path}',
'certificate' => '${./idp.crt}',
'auth' => 'pwauth',
);
?>
'';
"metadata/saml20-sp-remote.php" = pkgs.writeText "saml20-sp-remote.php" ''
<?php
${ lib.pipe config.services.idp.sp-remote-metadata [
(map (url: ''
$metadata['${url}'] = [
'SingleLogoutService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => '${url}module.php/saml/sp/saml2-logout.php/default-sp',
],
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP',
'Location' => '${url}module.php/saml/sp/saml2-logout.php/default-sp',
],
],
'AssertionConsumerService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
'Location' => '${url}module.php/saml/sp/saml2-acs.php/default-sp',
'index' => 0,
],
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact',
'Location' => '${url}module.php/saml/sp/saml2-acs.php/default-sp',
'index' => 1,
],
],
];
''))
(lib.concatStringsSep "\n")
]}
?>
'';
"config/authsources.php" = pkgs.writeText "idp-authsources.php" ''
<?php
$config = array(
'admin' => array(
'core:AdminPassword'
),
'pwauth' => array(
'authpwauth:PwAuth',
'pwauth_bin_path' => '${lib.getExe pwAuthScript}',
'mail_domain' => '@pvv.ntnu.no',
),
);
?>
'';
"config/config.php" = pkgs.runCommandLocal "simplesamlphp-config.php" { } ''
cp ${./config.php} "$out"
substituteInPlace "$out" \
--replace-warn '$SAML_COOKIE_SECURE' 'true' \
--replace-warn '$SAML_COOKIE_SALT' 'file_get_contents("${config.sops.secrets."idp/cookie_salt".path}")' \
--replace-warn '$SAML_ADMIN_NAME' '"Drift"' \
--replace-warn '$SAML_ADMIN_EMAIL' '"drift@pvv.ntnu.no"' \
--replace-warn '$SAML_ADMIN_PASSWORD' 'file_get_contents("${config.sops.secrets."idp/admin_password".path}")' \
--replace-warn '$SAML_TRUSTED_DOMAINS' 'array( "idp.pvv.ntnu.no" )' \
--replace-warn '$SAML_DATABASE_DSN' '"pgsql:host=postgres.pvv.ntnu.no;port=5432;dbname=idp"' \
--replace-warn '$SAML_DATABASE_USERNAME' '"idp"' \
--replace-warn '$SAML_DATABASE_PASSWORD' 'file_get_contents("${config.sops.secrets."idp/postgres_password".path}")' \
--replace-warn '$CACHE_DIRECTORY' '/var/cache/idp'
'';
"modules/authpwauth/src/Auth/Source/PwAuth.php" = ./authpwauth.php;
};
};
in
{
options.services.idp.sp-remote-metadata = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
description = ''
List of urls point to (simplesamlphp) service profiders, which the idp should trust.
:::{.note}
Make sure the url ends with a `/`
:::
'';
};
config = {
sops.secrets = {
"idp/privatekey" = {
owner = "idp";
group = "idp";
mode = "0770";
};
"idp/admin_password" = {
owner = "idp";
group = "idp";
};
"idp/postgres_password" = {
owner = "idp";
group = "idp";
};
"idp/cookie_salt" = {
owner = "idp";
group = "idp";
};
};
users.groups."idp" = { };
users.users."idp" = {
description = "PVV Identity Provider Service User";
group = "idp";
createHome = false;
isSystemUser = true;
};
systemd.tmpfiles.settings."10-idp" = {
"/var/cache/idp".d = {
user = "idp";
group = "idp";
mode = "0770";
};
"/var/lib/idp".d = {
user = "idp";
group = "idp";
mode = "0770";
};
};
services.phpfpm.pools.idp = {
user = "idp";
group = "idp";
settings = let
listenUser = config.services.nginx.user;
listenGroup = config.services.nginx.group;
in {
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"listen.owner" = listenUser;
"listen.group" = listenGroup;
"catch_workers_output" = true;
"php_admin_flag[log_errors]" = true;
# "php_admin_value[error_log]" = "stderr";
};
};
services.nginx.virtualHosts."idp.pvv.ntnu.no" = {
forceSSL = true;
enableACME = true;
kTLS = true;
root = "${package}/share/php/simplesamlphp/public";
locations = {
# based on https://simplesamlphp.org/docs/stable/simplesamlphp-install.html#configuring-nginx
"/" = {
alias = "${package}/share/php/simplesamlphp/public/";
index = "index.php";
extraConfig = ''
location ~ ^/(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_pass unix:${config.services.phpfpm.pools.idp.socket};
fastcgi_param SCRIPT_FILENAME ${package}/share/php/simplesamlphp/public/$phpfile;
fastcgi_param SCRIPT_NAME /$phpfile;
fastcgi_param PATH_INFO $pathinfo if_not_empty;
}
'';
};
"^~ /simplesaml/".extraConfig = ''
rewrite ^/simplesaml/(.*)$ /$1 redirect;
return 404;
'';
"/robots.txt" = {
root = pkgs.writeTextDir "robots.txt" ''
User-agent: *
Disallow: /
'';
};
};
};
};
}

View File

@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFqTCCA5GgAwIBAgIUL2+PMM9rE9wI5W2yNnJ2CmfGxh0wDQYJKoZIhvcNAQEL
BQAwZDELMAkGA1UEBhMCTk8xEzARBgNVBAgMClNvbWUtU3RhdGUxHjAcBgNVBAoM
FVByb2dyYW12YXJldmVya3N0ZWRldDEgMB4GCSqGSIb3DQEJARYRZHJpZnRAcHZ2
Lm50bnUubm8wHhcNMjQwMzMwMDAyNjQ0WhcNMjUwMzMwMDAyNjQ0WjBkMQswCQYD
VQQGEwJOTzETMBEGA1UECAwKU29tZS1TdGF0ZTEeMBwGA1UECgwVUHJvZ3JhbXZh
cmV2ZXJrc3RlZGV0MSAwHgYJKoZIhvcNAQkBFhFkcmlmdEBwdnYubnRudS5ubzCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/0l0jdV+PoVxdd21F+2NLm
JN6sZmSJexOSk/sFjhhF4WMtjOfDAQYjt3hlLPyYl//jCe9WteavvtdCx1tHJitd
xjOUJ/leVjHzBttCVZR+iTlQtpsZ2TbRMJ5Fcfl82njlPecV4umJvnnFXawE4Qee
dE2OM8ODjjrK1cNaHR74tyZCwmdOxNHXZ7RN22p9kZjLD18LQyNr5igaDBeaZkyk
Gxbg4tbP51x9JFRLF7kUlyAc83geFnw6v/wBahr49m/X4y7xE0rdPb2L0moUjmOO
Zyl3hvxMI3+g/0FVMM5eKmfIIP2rIVEAa6MWMx0vPjC6h2fIyxkUqg5C8aFlpqav
+8f2rUc+JfdiFsIZNrylBXsleGzS+/wY1uB/pAy5Vg9WCp+eC75EtWMt0k2f442G
rhKa3lAZ6GIYrtEiQiNGM1aT1Cs1nqTtslfnHiuAKBefLjCXgq9uvL2yRodwe9/m
oZiqYnLHy/v1xfnF5rKTcRmOleU3tc+nlN6tZSGC1nZgMpqpoqdcbJXAkvaJ2Km4
sl0YS28VQnztgzuVPNdnv8lcS6HmkaGaNWbepKgWeaH5oT7O6u99wZIv88m+tf5m
Eu197YVpcclnojQCYKauWcQFsXS20egsVP87Qk0e2SHmGTUQp6YEYX6RLjkg7/vS
BelDBbCldraNVEiC0jmpAgMBAAGjUzBRMB0GA1UdDgQWBBSL0yofG5NEmzFIRuqC
xmyiuZW6DTAfBgNVHSMEGDAWgBSL0yofG5NEmzFIRuqCxmyiuZW6DTAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAZZVs7BLk/NLq3f4Ik8qH3IoDN
2m4XXRZS+xxw5RwctgSnik7AffgAfv8QQm2co8UYkHbB0whaG1PDz+L7wB1hVkWn
DVUaJcKQnn0x+sNU5LoTbjI0PlaST7PO5D0OMFab8FSNxpzzpbUcgZUhelc99Ri/
2Gh8mf4b3Y3Uzq6YKFsuFM65OuJhH8f1w6onai9x28t6tERHUSUfJ2keXzU4ytCV
EitWXwhe759VLqmdP4BATwlCOCuwa5aDeGcWRIqFpYIn0SOAmVV3o4V71JdZc1jE
fuOo/PbiHZ+R9ZGbh98aMidb0moL1ZDhmir9KbedezNyki6JJ72mVclhLqUajFxr
T39FXd5e2+QBMHPPhVFznQoHWnHEbZigTt61b0cg/TsxaxOkF4Ilmr/2DmSWysWK
TF5eq8hp6/53qVbXXSzrCjxd3wzGnRabsEVPX/L2hYDx81hluovJQCtskqTq1joI
W2R7AO5Sdyc6NfOR85kl0HXzHa+0Slsf8ZDs5nCz/mOOPoAGl7IxF7xQ6kPO7V+U
HdGE2tkblM/TrAObJH0HXySeJGI7Vfya+D1Y8IqGtyZtWyx1DmlA/OezGGf5D3rG
88LywHQQ2mQ+8aosBTE4+HQ+apLKZBprqQKuiDjT1RSUbfUHQkYuL+D1oIVmklAc
UxTpf01QJnZkMqf5NQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,22 @@
''
<?php
$metadata['https://idp.pvv.ntnu.no/'] = [
'metadata-set' => 'saml20-idp-hosted',
'entityid' => 'https://idp.pvv.ntnu.no/',
'SingleSignOnService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://idp.pvv.ntnu.no/module.php/saml/idp/singleSignOnService',
],
],
'SingleLogoutService' => [
[
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://idp.pvv.ntnu.no/module.php/saml/idp/singleLogout',
],
],
'NameIDFormat' => [ 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient' ],
'certificate' => '${./idp.crt}',
];
?>
''

View File

@ -0,0 +1,14 @@
{ config, pkgs, lib, ... }:
{
security.krb5 = {
enable = true;
settings = {
libdefaults = {
default_realm = "PVV.NTNU.NO";
dns_lookup_realm = "yes";
dns_lookup_kdc = "yes";
};
realms."PVV.NTNU.NO".admin_server = "kdc.pvv.ntnu.no";
};
};
}

View File

@ -0,0 +1,88 @@
{ pkgs, lib, ... }:
# Based on
# - https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html
# - https://manpages.debian.org/unstable/heimdal-docs/krb5.conf.5heimdal.en.html
let
inherit (lib) boolToString concatMapStringsSep concatStringsSep filter
isAttrs isBool isList mapAttrsToList mdDoc mkOption singleton splitString;
inherit (lib.types) attrsOf bool coercedTo either int listOf oneOf path
str submodule;
in
{ }: {
type = let
section = attrsOf relation;
relation = either (attrsOf value) value;
value = either (listOf atom) atom;
atom = oneOf [int str bool];
in submodule {
freeformType = attrsOf section;
options = {
include = mkOption {
default = [ ];
description = mdDoc ''
Files to include in the Kerberos configuration.
'';
type = coercedTo path singleton (listOf path);
};
includedir = mkOption {
default = [ ];
description = mdDoc ''
Directories containing files to include in the Kerberos configuration.
'';
type = coercedTo path singleton (listOf path);
};
module = mkOption {
default = [ ];
description = mdDoc ''
Modules to obtain Kerberos configuration from.
'';
type = coercedTo path singleton (listOf path);
};
};
};
generate = let
indent = str: concatMapStringsSep "\n" (line: " " + line) (splitString "\n" str);
formatToplevel = args @ {
include ? [ ],
includedir ? [ ],
module ? [ ],
...
}: let
sections = removeAttrs args [ "include" "includedir" "module" ];
in concatStringsSep "\n" (filter (x: x != "") [
(concatStringsSep "\n" (mapAttrsToList formatSection sections))
(concatMapStringsSep "\n" (m: "module ${m}") module)
(concatMapStringsSep "\n" (i: "include ${i}") include)
(concatMapStringsSep "\n" (i: "includedir ${i}") includedir)
]);
formatSection = name: section: ''
[${name}]
${indent (concatStringsSep "\n" (mapAttrsToList formatRelation section))}
'';
formatRelation = name: relation:
if isAttrs relation
then ''
${name} = {
${indent (concatStringsSep "\n" (mapAttrsToList formatValue relation))}
}''
else formatValue name relation;
formatValue = name: value:
if isList value
then concatMapStringsSep "\n" (formatAtom name) value
else formatAtom name value;
formatAtom = name: atom: let
v = if isBool atom then boolToString atom else toString atom;
in "${name} = ${v}";
in
name: value: pkgs.writeText name ''
${formatToplevel value}
'';
}

View File

@ -0,0 +1,90 @@
{ config, lib, pkgs, ... }:
let
inherit (lib) mdDoc mkIf mkOption mkPackageOption mkRemovedOptionModule;
inherit (lib.types) bool;
mkRemovedOptionModule' = name: reason: mkRemovedOptionModule ["krb5" name] reason;
mkRemovedOptionModuleCfg = name: mkRemovedOptionModule' name ''
The option `krb5.${name}' has been removed. Use
`security.krb5.settings.${name}' for structured configuration.
'';
cfg = config.security.krb5;
format = import ./krb5-conf-format.nix { inherit pkgs lib; } { };
in {
imports = [
(mkRemovedOptionModuleCfg "libdefaults")
(mkRemovedOptionModuleCfg "realms")
(mkRemovedOptionModuleCfg "domain_realm")
(mkRemovedOptionModuleCfg "capaths")
(mkRemovedOptionModuleCfg "appdefaults")
(mkRemovedOptionModuleCfg "plugins")
(mkRemovedOptionModuleCfg "config")
(mkRemovedOptionModuleCfg "extraConfig")
(mkRemovedOptionModule' "kerberos" ''
The option `krb5.kerberos' has been moved to `security.krb5.package'.
'')
];
options = {
security.krb5 = {
enable = mkOption {
default = false;
description = mdDoc "Enable and configure Kerberos utilities";
type = bool;
};
package = mkPackageOption pkgs "krb5" {
example = "heimdal";
};
settings = mkOption {
default = { };
type = format.type;
description = mdDoc ''
Structured contents of the {file}`krb5.conf` file. See
{manpage}`krb5.conf(5)` for details about configuration.
'';
example = {
include = [ "/run/secrets/secret-krb5.conf" ];
includedir = [ "/run/secrets/secret-krb5.conf.d" ];
libdefaults = {
default_realm = "ATHENA.MIT.EDU";
};
realms = {
"ATHENA.MIT.EDU" = {
admin_server = "athena.mit.edu";
kdc = [
"athena01.mit.edu"
"athena02.mit.edu"
];
};
};
domain_realm = {
"mit.edu" = "ATHENA.MIT.EDU";
};
logging = {
kdc = "SYSLOG:NOTICE";
admin_server = "SYSLOG:NOTICE";
default = "SYSLOG:NOTICE";
};
};
};
};
};
config = mkIf cfg.enable {
environment = {
systemPackages = [ cfg.package ];
etc."krb5.conf".source = format.generate "krb5.conf" cfg.settings;
};
};
meta.maintainers = builtins.attrValues {
inherit (lib.maintainers) dblsaiko h7x4;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
{ pkgs, config, values, ... }:
{
sops.secrets."keys/postgres/keycloak" = {
owner = "keycloak";
group = "keycloak";
restartUnits = [ "keycloak.service" ];
};
services.keycloak = {
enable = true;
settings = {
hostname = "auth.pvv.ntnu.no";
# hostname-strict-backchannel = true;
};
database = {
host = values.hosts.bicep.ipv4;
createLocally = false;
passwordFile = config.sops.secrets."keys/postgres/keycloak".path;
caCert = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
};
};
}

View File

@ -1,175 +0,0 @@
{ pkgs, lib, config, values, ... }: let
cfg = config.services.mediawiki;
# "mediawiki"
user = config.systemd.services.mediawiki-init.serviceConfig.User;
# "mediawiki"
group = config.users.users.${user}.group;
in {
sops.secrets = {
"mediawiki/password" = {
restartUnits = [ "mediawiki-init.service" "phpfpm-mediawiki.service" ];
owner = user;
group = group;
};
"keys/postgres/mediawiki" = {
restartUnits = [ "mediawiki-init.service" "phpfpm-mediawiki.service" ];
owner = user;
group = group;
};
};
services.mediawiki = {
enable = true;
name = "Programvareverkstedet";
passwordFile = config.sops.secrets."mediawiki/password".path;
passwordSender = "drift@pvv.ntnu.no";
database = {
type = "postgres";
host = "postgres.pvv.ntnu.no";
port = config.services.postgresql.port;
passwordFile = config.sops.secrets."keys/postgres/mediawiki".path;
createLocally = false;
# TODO: create a normal database and copy over old data when the service is production ready
name = "mediawiki_test";
};
# Host through nginx
webserver = "none";
poolConfig = let
listenUser = config.services.nginx.user;
listenGroup = config.services.nginx.group;
in {
inherit user group;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"listen.owner" = listenUser;
"listen.group" = listenGroup;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = "on";
"env[PATH]" = lib.makeBinPath [ pkgs.php ];
"catch_workers_output" = true;
# to accept *.html file
"security.limit_extensions" = "";
};
extensions = {
DeleteBatch = pkgs.fetchzip {
url = "https://extdist.wmflabs.org/dist/extensions/DeleteBatch-REL1_39-995ea6f.tar.gz";
sha256 = "sha256-0F4GLCy2f5WcWIY2YgF1tVxgYbglR0VOsj/pMrW93b8=";
};
UserMerge = pkgs.fetchzip {
url = "https://extdist.wmflabs.org/dist/extensions/UserMerge-REL1_39-b10d50e.tar.gz";
sha256 = "sha256-bXhj1+OlOUJDbvEuc8iwqb1LLEu6cN6+C/7cAvnWPOQ=";
};
PluggableAuth = pkgs.fetchzip {
url = "https://extdist.wmflabs.org/dist/extensions/PluggableAuth-REL1_39-1210fc3.tar.gz";
sha256 = "sha256-F6bTMCzkK3kZwZGIsNE87WlZWqXXmTMhEjApO99YKR0=";
};
SimpleSAMLphp = pkgs.fetchzip {
url = "https://extdist.wmflabs.org/dist/extensions/SimpleSAMLphp-REL1_39-dcf0acb.tar.gz";
sha256 = "sha256-tCvFmb2+q2rxms+lRo5pgoI3h6GjCwXAR8XisPg03TQ=";
};
};
extraConfig = let
SimpleSAMLphpRepo = pkgs.stdenvNoCC.mkDerivation rec {
pname = "configuredSimpleSAML";
version = "2.0.4";
src = pkgs.fetchzip {
url = "https://github.com/simplesamlphp/simplesamlphp/releases/download/v${version}/simplesamlphp-${version}.tar.gz";
sha256 = "sha256-pfMV/VmqqxgtG7Nx4s8MW4tWSaxOkVPtCRJwxV6RDSE=";
};
buildPhase = ''
cat > config/authsources.php << EOF
<?php
$config = array(
'default-sp' => array(
'saml:SP',
'idp' => 'https://idp.pvv.ntnu.no/',
),
);
EOF
'';
installPhase = ''
cp -r . $out
'';
};
in ''
$wgServer = "https://bekkalokk.pvv.ntnu.no";
$wgLocaltimezone = "Europe/Oslo";
# Only allow login through SSO
$wgEnableEmail = false;
$wgEnableUserEmail = false;
$wgEmailAuthentication = false;
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['autocreateaccount'] = true;
$wgPluggableAuth_EnableAutoLogin = true;
# Disable anonymous editing
$wgGroupPermissions['*']['edit'] = false;
# Styling
$wgLogo = "/PNG/PVV-logo.png";
$wgDefaultSkin = "monobook";
# Misc
$wgEmergencyContact = "${cfg.passwordSender}";
$wgShowIPinHeader = false;
$wgUseTeX = false;
$wgLocalInterwiki = $wgSitename;
# SimpleSAML
$wgSimpleSAMLphp_InstallDir = "${SimpleSAMLphpRepo}";
$wgSimpleSAMLphp_AuthSourceId = "default-sp";
$wgSimpleSAMLphp_RealNameAttribute = "cn";
$wgSimpleSAMLphp_EmailAttribute = "mail";
$wgSimpleSAMLphp_UsernameAttribute = "uid";
# Fix https://github.com/NixOS/nixpkgs/issues/183097
$wgDBserver = "${toString cfg.database.host}";
'';
};
# Override because of https://github.com/NixOS/nixpkgs/issues/183097
systemd.services.mediawiki-init.script = let
# According to module
stateDir = "/var/lib/mediawiki";
pkg = cfg.finalPackage;
mediawikiConfig = config.services.phpfpm.pools.mediawiki.phpEnv.MEDIAWIKI_CONFIG;
inherit (lib) optionalString mkForce;
in mkForce ''
if ! test -e "${stateDir}/secret.key"; then
tr -dc A-Za-z0-9 </dev/urandom 2>/dev/null | head -c 64 > ${stateDir}/secret.key
fi
echo "exit( wfGetDB( DB_MASTER )->tableExists( 'user' ) ? 1 : 0 );" | \
${pkgs.php}/bin/php ${pkg}/share/mediawiki/maintenance/eval.php --conf ${mediawikiConfig} && \
${pkgs.php}/bin/php ${pkg}/share/mediawiki/maintenance/install.php \
--confpath /tmp \
--scriptpath / \
--dbserver "${cfg.database.host}" \
--dbport ${toString cfg.database.port} \
--dbname ${cfg.database.name} \
${optionalString (cfg.database.tablePrefix != null) "--dbprefix ${cfg.database.tablePrefix}"} \
--dbuser ${cfg.database.user} \
${optionalString (cfg.database.passwordFile != null) "--dbpassfile ${cfg.database.passwordFile}"} \
--passfile ${cfg.passwordFile} \
--dbtype ${cfg.database.type} \
${cfg.name} \
admin
${pkgs.php}/bin/php ${pkg}/share/mediawiki/maintenance/update.php --conf ${mediawikiConfig} --quick
'';
}

View File

@ -0,0 +1,231 @@
{ pkgs, lib, fp, config, values, pkgs-unstable, ... }: let
cfg = config.services.mediawiki;
# "mediawiki"
user = config.systemd.services.mediawiki-init.serviceConfig.User;
# "mediawiki"
group = config.users.users.${user}.group;
simplesamlphp = pkgs.simplesamlphp.override {
extra_files = {
"metadata/saml20-idp-remote.php" = pkgs.writeText "mediawiki-saml20-idp-remote.php" (import ../idp-simplesamlphp/metadata.php.nix);
"config/authsources.php" = ./simplesaml-authsources.php;
"config/config.php" = pkgs.runCommandLocal "mediawiki-simplesamlphp-config.php" { } ''
cp ${./simplesaml-config.php} "$out"
substituteInPlace "$out" \
--replace-warn '$SAML_COOKIE_SECURE' 'true' \
--replace-warn '$SAML_COOKIE_SALT' 'file_get_contents("${config.sops.secrets."mediawiki/simplesamlphp/cookie_salt".path}")' \
--replace-warn '$SAML_ADMIN_NAME' '"Drift"' \
--replace-warn '$SAML_ADMIN_EMAIL' '"drift@pvv.ntnu.no"' \
--replace-warn '$SAML_ADMIN_PASSWORD' 'file_get_contents("${config.sops.secrets."mediawiki/simplesamlphp/admin_password".path}")' \
--replace-warn '$SAML_TRUSTED_DOMAINS' 'array( "wiki.pvv.ntnu.no" )' \
--replace-warn '$SAML_DATABASE_DSN' '"pgsql:host=postgres.pvv.ntnu.no;port=5432;dbname=mediawiki_simplesamlphp"' \
--replace-warn '$SAML_DATABASE_USERNAME' '"mediawiki_simplesamlphp"' \
--replace-warn '$SAML_DATABASE_PASSWORD' 'file_get_contents("${config.sops.secrets."mediawiki/simplesamlphp/postgres_password".path}")' \
--replace-warn '$CACHE_DIRECTORY' '/var/cache/mediawiki/idp'
'';
};
};
in {
services.idp.sp-remote-metadata = [ "https://wiki.pvv.ntnu.no/simplesaml/" ];
sops.secrets = lib.pipe [
"mediawiki/password"
"mediawiki/postgres_password"
"mediawiki/simplesamlphp/postgres_password"
"mediawiki/simplesamlphp/cookie_salt"
"mediawiki/simplesamlphp/admin_password"
] [
(map (key: lib.nameValuePair key {
owner = user;
group = group;
restartUnits = [ "phpfpm-mediawiki.service" ];
}))
lib.listToAttrs
];
services.mediawiki = {
enable = true;
name = "Programvareverkstedet";
passwordFile = config.sops.secrets."mediawiki/password".path;
passwordSender = "drift@pvv.ntnu.no";
database = {
type = "mysql";
host = "mysql.pvv.ntnu.no";
port = 3306;
user = "mediawiki";
passwordFile = config.sops.secrets."mediawiki/postgres_password".path;
createLocally = false;
# TODO: create a normal database and copy over old data when the service is production ready
name = "mediawiki";
};
webserver = "nginx";
nginx.hostName = "wiki.pvv.ntnu.no";
poolConfig = {
inherit user group;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 4;
"catch_workers_output" = true;
"php_admin_flag[log_errors]" = true;
# "php_admin_value[error_log]" = "stderr";
# to accept *.html file
"security.limit_extensions" = "";
};
extensions = {
inherit (pkgs.mediawiki-extensions)
CodeEditor
CodeMirror
DeleteBatch
PluggableAuth
Popups
Scribunto
SimpleSAMLphp
TemplateData
TemplateStyles
UserMerge
VisualEditor
WikiEditor
;
};
extraConfig = ''
$wgServer = "https://wiki.pvv.ntnu.no";
$wgLocaltimezone = "Europe/Oslo";
# Only allow login through SSO
$wgEnableEmail = false;
$wgEnableUserEmail = false;
$wgEmailAuthentication = false;
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['autocreateaccount'] = true;
$wgPluggableAuth_EnableAutoLogin = false;
# Misc. permissions
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['read'] = true;
# Allow subdirectories in article URLs
$wgNamespacesWithSubpages[NS_MAIN] = true;
# Styling
$wgLogos = array(
"2x" => "/PNG/PVV-logo.png",
"icon" => "/PNG/PVV-logo.svg",
);
$wgDefaultSkin = "vector-2022";
# from https://github.com/wikimedia/mediawiki-skins-Vector/blob/master/skin.json
$wgVectorDefaultSidebarVisibleForAnonymousUser = true;
$wgVectorResponsive = true;
# Misc
$wgEmergencyContact = "${cfg.passwordSender}";
$wgUseTeX = false;
$wgLocalInterwiki = $wgSitename;
# Fix https://github.com/NixOS/nixpkgs/issues/183097
$wgDBserver = "${toString cfg.database.host}";
$wgAllowCopyUploads = true;
# Misc program paths
$wgFFmpegLocation = '${pkgs.ffmpeg}/bin/ffmpeg';
$wgExiftool = '${pkgs.exiftool}/bin/exiftool';
$wgExiv2Command = '${pkgs.exiv2}/bin/exiv2';
# See https://gist.github.com/sergejmueller/088dce028b6dd120a16e
$wgJpegTran = '${pkgs.mozjpeg}/bin/jpegtran';
$wgGitBin = '${pkgs.git}/bin/git';
# Debugging
$wgShowExceptionDetails = false;
$wgShowIPinHeader = false;
# EXT:{SimpleSAML,PluggableAuth}
$wgSimpleSAMLphp_InstallDir = "${simplesamlphp}/share/php/simplesamlphp/";
$wgPluggableAuth_Config['Log in using SAML'] = [
'plugin' => 'SimpleSAMLphp',
'data' => [
'authSourceId' => 'default-sp',
'usernameAttribute' => 'uid',
'emailAttribute' => 'mail',
'realNameAttribute' => 'cn',
]
];
# EXT:Scribunto
$wgScribuntoDefaultEngine = 'luastandalone';
$wgScribuntoEngineConf['luastandalone']['luaPath'] = '${pkgs.lua}/bin';
# EXT:WikiEditor
$wgWikiEditorRealtimePreview = true;
'';
};
# Cache directory for simplesamlphp
# systemd.services.phpfpm-mediawiki.serviceConfig.CacheDirectory = "mediawiki/simplesamlphp";
systemd.tmpfiles.settings."10-mediawiki"."/var/cache/mediawiki/simplesamlphp".d = {
user = "mediawiki";
group = "mediawiki";
mode = "0770";
};
users.groups.mediawiki.members = [ "nginx" ];
services.nginx.virtualHosts."wiki.pvv.ntnu.no" = {
kTLS = true;
forceSSL = true;
enableACME = true;
locations = {
"= /wiki/Main_Page" = lib.mkForce {
return = "301 /wiki/Programvareverkstedet";
};
# based on https://simplesamlphp.org/docs/stable/simplesamlphp-install.html#configuring-nginx
"^~ /simplesaml/" = {
alias = "${simplesamlphp}/share/php/simplesamlphp/public/";
index = "index.php";
extraConfig = ''
location ~ ^/simplesaml/(?<phpfile>.+?\.php)(?<pathinfo>/.*)?$ {
include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_pass unix:${config.services.phpfpm.pools.mediawiki.socket};
fastcgi_param SCRIPT_FILENAME ${simplesamlphp}/share/php/simplesamlphp/public/$phpfile;
# Must be prepended with the baseurlpath
fastcgi_param SCRIPT_NAME /simplesaml/$phpfile;
fastcgi_param PATH_INFO $pathinfo if_not_empty;
}
'';
};
"= /PNG/PVV-logo.svg".alias = fp /assets/logo_blue_regular.svg;
"= /PNG/PVV-logo.png".alias = fp /assets/logo_blue_regular.png;
"= /favicon.ico".alias = pkgs.runCommandLocal "mediawiki-favicon.ico" {
buildInputs = with pkgs; [ imagemagick ];
} ''
convert \
-resize x64 \
-gravity center \
-crop 64x64+0+0 \
${fp /assets/logo_blue_regular.png} \
-flatten \
-colors 256 \
-background transparent \
$out
'';
};
};
}

View File

@ -0,0 +1,11 @@
<?php
$config = array(
'admin' => array(
'core:AdminPassword'
),
'default-sp' => array(
'saml:SP',
'entityID' => 'https://wiki.pvv.ntnu.no/simplesaml/',
'idp' => 'https://idp.pvv.ntnu.no/',
),
);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
{ pkgs, config, ... }:
{
services.nginx.enable = true;
}

View File

@ -1,22 +0,0 @@
{ pkgs, config, ... }:
{
imports = [
./ingress.nix
];
security.acme = {
acceptTerms = true;
defaults.email = "drift@pvv.ntnu.no";
};
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
}

View File

@ -1,55 +0,0 @@
{ config, lib, ... }:
{
services.nginx.virtualHosts = {
"www2.pvv.ntnu.no" = {
serverAliases = [ "www2.pvv.org" "pvv.ntnu.no" "pvv.org" ];
addSSL = true;
enableACME = true;
locations = {
# Proxy home directories
"/~" = {
extraConfig = ''
proxy_redirect off;
proxy_pass https://tom.pvv.ntnu.no;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
'';
};
# Redirect old wiki entries
"/disk".return = "301 https://www.pvv.ntnu.no/pvv/Diskkjøp";
"/dok/boker.php".return = "301 https://www.pvv.ntnu.no/pvv/Bokhyllen";
"/styret/lover/".return = "301 https://www.pvv.ntnu.no/pvv/Lover";
"/styret/".return = "301 https://www.pvv.ntnu.no/pvv/Styret";
"/info/".return = "301 https://www.pvv.ntnu.no/pvv/";
"/info/maskinpark/".return = "301 https://www.pvv.ntnu.no/pvv/Maskiner";
"/medlemssider/meldinn.php".return = "301 https://www.pvv.ntnu.no/pvv/Medlemskontingent";
"/diverse/medlems-sider.php".return = "301 https://www.pvv.ntnu.no/pvv/Medlemssider";
"/cert/".return = "301 https://www.pvv.ntnu.no/pvv/CERT";
"/drift".return = "301 https://www.pvv.ntnu.no/pvv/Drift";
"/diverse/abuse.php".return = "301 https://www.pvv.ntnu.no/pvv/CERT/Abuse";
"/nerds/".return = "301 https://www.pvv.ntnu.no/pvv/Nerdepizza";
# TODO: Redirect webmail
"/webmail".return = "301 https://webmail.pvv.ntnu.no/squirrelmail";
# Redirect everything else to the main website
"/".return = "301 https://www.pvv.ntnu.no$request_uri";
# Proxy the matrix well-known files
# Host has be set before proxy_pass
# The header must be set so nginx on the other side routes it to the right place
"/.well-known/matrix/" = {
extraConfig = ''
proxy_set_header Host matrix.pvv.ntnu.no;
proxy_pass https://matrix.pvv.ntnu.no/.well-known/matrix/;
'';
};
};
};
};
}

View File

@ -0,0 +1,51 @@
{ lib, ... }:
let
pools = map (pool: "phpfpm-${pool}") [
"idp"
"mediawiki"
"pvv-nettsiden"
"roundcube"
"snappymail"
];
in
{
# Source: https://www.pierreblazquez.com/2023/06/17/how-to-harden-apache-php-fpm-daemons-using-systemd/
systemd.services = lib.genAttrs pools (_: {
serviceConfig = let
caps = [
"CAP_NET_BIND_SERVICE"
"CAP_SETGID"
"CAP_SETUID"
"CAP_CHOWN"
"CAP_KILL"
"CAP_IPC_LOCK"
"CAP_DAC_OVERRIDE"
];
in {
AmbientCapabilities = caps;
CapabilityBoundingSet = caps;
DeviceAllow = [ "" ];
LockPersonality = true;
MemoryDenyWriteExecute = false;
NoNewPrivileges = true;
PrivateMounts = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RemoveIPC = true;
UMask = "0077";
RestrictNamespaces = "~mnt";
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
KeyringMode = "private";
SystemCallFilter = [
"@system-service"
];
};
});
}

View File

@ -0,0 +1,104 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.vaultwarden;
domain = "pw.pvv.ntnu.no";
address = "127.0.1.2";
port = 3011;
wsPort = 3012;
in {
sops.secrets."vaultwarden/environ" = {
owner = "vaultwarden";
group = "vaultwarden";
};
services.vaultwarden = {
enable = true;
dbBackend = "postgresql";
environmentFile = config.sops.secrets."vaultwarden/environ".path;
config = {
domain = "https://${domain}";
rocketAddress = address;
rocketPort = port;
websocketEnabled = true;
websocketAddress = address;
websocketPort = wsPort;
signupsAllowed = true;
signupsVerify = true;
signupsDomainsWhitelist = "pvv.ntnu.no";
smtpFrom = "vaultwarden@pvv.ntnu.no";
smtpFromName = "VaultWarden PVV";
smtpHost = "smtp.pvv.ntnu.no";
smtpUsername = "vaultwarden";
smtpSecurity = "force_tls";
smtpAuthMechanism = "Login";
# Configured in environ:
# databaseUrl = "postgresql://vaultwarden@/vaultwarden";
# smtpPassword = hemli
};
};
services.nginx.virtualHosts."${domain}" = {
forceSSL = true;
enableACME = true;
kTLS = true;
extraConfig = ''
client_max_body_size 128M;
'';
locations."/" = {
proxyPass = "http://${address}:${toString port}";
proxyWebsockets = true;
};
locations."/notifications/hub" = {
proxyPass = "http://${address}:${toString wsPort}";
proxyWebsockets = true;
};
locations."/notifications/hub/negotiate" = {
proxyPass = "http://${address}:${toString port}";
proxyWebsockets = true;
};
};
systemd.services.vaultwarden = lib.mkIf cfg.enable {
serviceConfig = {
AmbientCapabilities = [ "" ];
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
NoNewPrivileges = true;
# MemoryDenyWriteExecute = true;
PrivateMounts = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [
"AF_INET"
"AF_INET6"
"AF_UNIX"
];
RemoveIPC = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
];
UMask = "0007";
};
};
}

View File

@ -2,14 +2,20 @@
{ {
imports = [ imports = [
./roundcube.nix ./roundcube.nix
./snappymail.nix
]; ];
services.nginx.virtualHosts."webmail2.pvv.ntnu.no" = { services.nginx.virtualHosts."webmail.pvv.ntnu.no" = {
forceSSL = true; forceSSL = true;
enableACME = true; enableACME = true;
#locations."/" = lib.mkForce { }; kTLS = true;
locations."= /" = { locations = {
return = "301 https://www.pvv.ntnu.no/mail/"; "= /".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/afterlogic_lite".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/squirrelmail".return = "302 https://webmail.pvv.ntnu.no/roundcube";
"/rainloop".return = "302 https://snappymail.pvv.ntnu.no/";
"/snappymail".return = "302 https://snappymail.pvv.ntnu.no/";
}; };
}; };
} }

View File

@ -3,9 +3,14 @@
with lib; with lib;
let let
cfg = config.services.roundcube; cfg = config.services.roundcube;
domain = "webmail2.pvv.ntnu.no"; domain = "webmail.pvv.ntnu.no";
in in
{ {
sops.secrets."roundcube/postgres_password" = {
owner = "nginx";
group = "nginx";
};
services.roundcube = { services.roundcube = {
enable = true; enable = true;
@ -20,6 +25,11 @@ in
maxAttachmentSize = 20; maxAttachmentSize = 20;
hostName = "roundcubeplaceholder.example.com"; hostName = "roundcubeplaceholder.example.com";
database = {
host = "postgres.pvv.ntnu.no";
passwordFile = config.sops.secrets."roundcube/postgres_password".path;
};
extraConfig = '' extraConfig = ''
$config['enable_installer'] = false; $config['enable_installer'] = false;
$config['default_host'] = "ssl://imap.pvv.ntnu.no"; $config['default_host'] = "ssl://imap.pvv.ntnu.no";
@ -35,6 +45,7 @@ in
services.nginx.virtualHosts."roundcubeplaceholder.example.com" = lib.mkForce { }; services.nginx.virtualHosts."roundcubeplaceholder.example.com" = lib.mkForce { };
services.nginx.virtualHosts.${domain} = { services.nginx.virtualHosts.${domain} = {
kTLS = true;
locations."/roundcube" = { locations."/roundcube" = {
tryFiles = "$uri $uri/ =404"; tryFiles = "$uri $uri/ =404";
index = "index.php"; index = "index.php";

View File

@ -0,0 +1,18 @@
{ config, lib, fp, pkgs, ... }:
let
cfg = config.services.snappymail;
in {
imports = [ (fp /modules/snappymail.nix) ];
services.snappymail = {
enable = true;
hostname = "snappymail.pvv.ntnu.no";
};
services.nginx.virtualHosts.${cfg.hostname} = {
forceSSL = true;
enableACME = true;
kTLS = true;
};
}

View File

@ -1,4 +0,0 @@
{ ... }:
{
}

View File

@ -0,0 +1,121 @@
{ pkgs, lib, config, ... }:
let
format = pkgs.formats.php { };
cfg = config.services.pvv-nettsiden;
in {
imports = [
./fetch-gallery.nix
];
sops.secrets = lib.genAttrs [
"nettsiden/door_secret"
"nettsiden/mysql_password"
"nettsiden/simplesamlphp/admin_password"
"nettsiden/simplesamlphp/cookie_salt"
] (_: {
owner = config.services.phpfpm.pools.pvv-nettsiden.user;
group = config.services.phpfpm.pools.pvv-nettsiden.group;
restartUnits = [ "phpfpm-pvv-nettsiden.service" ];
});
services.idp.sp-remote-metadata = [
"https://www.pvv.ntnu.no/simplesaml/"
"https://pvv.ntnu.no/simplesaml/"
"https://www.pvv.org/simplesaml/"
"https://pvv.org/simplesaml/"
];
services.pvv-nettsiden = {
enable = true;
package = pkgs.pvv-nettsiden.override {
extra_files = {
"${pkgs.pvv-nettsiden.passthru.simplesamlphpPath}/metadata/saml20-idp-remote.php" = pkgs.writeText "pvv-nettsiden-saml20-idp-remote.php" (import ../idp-simplesamlphp/metadata.php.nix);
"${pkgs.pvv-nettsiden.passthru.simplesamlphpPath}/config/authsources.php" = pkgs.writeText "pvv-nettsiden-authsources.php" ''
<?php
$config = array(
'admin' => array(
'core:AdminPassword'
),
'default-sp' => array(
'saml:SP',
'entityID' => 'https://${cfg.domainName}/simplesaml/',
'idp' => 'https://idp.pvv.ntnu.no/',
),
);
'';
};
};
domainName = "www.pvv.ntnu.no";
settings = let
includeFromSops = path: format.lib.mkRaw "file_get_contents('${config.sops.secrets."nettsiden/${path}".path}')";
in {
DOOR_SECRET = includeFromSops "door_secret";
DB = {
DSN = "mysql:dbname=www-data_nettside;host=mysql.pvv.ntnu.no";
USER = "www-data_nettsi";
PASS = includeFromSops "mysql_password";
};
# TODO: set up postgres session for simplesamlphp
SAML = {
COOKIE_SALT = includeFromSops "simplesamlphp/cookie_salt";
COOKIE_SECURE = true;
ADMIN_NAME = "PVV Drift";
ADMIN_EMAIL = "drift@pvv.ntnu.no";
ADMIN_PASSWORD = includeFromSops "simplesamlphp/admin_password";
TRUSTED_DOMAINS = [ cfg.domainName ];
};
};
};
services.phpfpm.pools."pvv-nettsiden".settings = {
# "php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
services.nginx.virtualHosts.${cfg.domainName} = {
serverAliases = [
"pvv.ntnu.no"
"www.pvv.org"
"pvv.org"
];
locations = {
# Proxy home directories
"^~ /~" = {
extraConfig = ''
proxy_redirect off;
proxy_pass https://tom.pvv.ntnu.no;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
'';
};
# Redirect the old webmail/wiki paths from spikkjeposche
"^~ /webmail".return = "301 https://webmail.pvv.ntnu.no";
"~ /pvv/([^\\n\\r]*)".return = "301 https://wiki.pvv.ntnu.no/wiki/$1";
"= /pvv".return = "301 https://wiki.pvv.ntnu.no/";
# Redirect old wiki entries
"/disk".return = "301 https://wiki.pvv.ntnu.no/wiki/Diskkjøp";
"/dok/boker.php".return = "301 https://wiki.pvv.ntnu.no/wiki/Bokhyllen";
"/styret/lover/".return = "301 https://wiki.pvv.ntnu.no/wiki/Lover";
"/styret/".return = "301 https://wiki.pvv.ntnu.no/wiki/Styret";
"/info/".return = "301 https://wiki.pvv.ntnu.no/wiki/";
"/info/maskinpark/".return = "301 https://wiki.pvv.ntnu.no/wiki/Maskiner";
"/medlemssider/meldinn.php".return = "301 https://wiki.pvv.ntnu.no/wiki/Medlemskontingent";
"/diverse/medlems-sider.php".return = "301 https://wiki.pvv.ntnu.no/wiki/Medlemssider";
"/cert/".return = "301 https://wiki.pvv.ntnu.no/wiki/CERT";
"/drift".return = "301 https://wiki.pvv.ntnu.no/wiki/Drift";
"/diverse/abuse.php".return = "301 https://wiki.pvv.ntnu.no/wiki/CERT/Abuse";
"/nerds/".return = "301 https://wiki.pvv.ntnu.no/wiki/Nerdepizza";
};
};
}

View File

@ -0,0 +1,94 @@
{ pkgs, lib, config, ... }:
let
galleryDir = config.services.pvv-nettsiden.settings.GALLERY.DIR;
transferDir = "${config.services.pvv-nettsiden.settings.GALLERY.DIR}-transfer";
in {
users.users.${config.services.pvv-nettsiden.user} = {
useDefaultShell = true;
# This is pushed from microbel:/var/www/www-gallery/build-gallery.sh
openssh.authorizedKeys.keys = [
''command="${pkgs.rrsync}/bin/rrsync -wo ${transferDir}",restrict,no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIjHhC2dikhWs/gG+m7qP1eSohWzTehn4ToNzDSOImyR gallery-publish''
];
};
systemd.paths.pvv-nettsiden-gallery-update = {
wantedBy = [ "multi-user.target" ];
pathConfig = {
PathChanged = "${transferDir}/gallery.tar.gz";
Unit = "pvv-nettsiden-gallery-update.service";
MakeDirectory = true;
};
};
systemd.services.pvv-nettsiden-gallery-update = {
path = with pkgs; [ imagemagick gnutar gzip ];
script = ''
tar ${lib.cli.toGNUCommandLineShell {} {
extract = true;
file = "${transferDir}/gallery.tar.gz";
directory = ".";
}}
# Delete files and directories that exists in the gallery that don't exist in the tarball
filesToRemove=$(uniq -u <(sort <(find . -not -path "./.thumbnails*") <(tar -tf ${transferDir}/gallery.tar.gz | sed 's|/$||')))
while IFS= read fname; do
rm -f "$fname" ||:
rm -f ".thumbnails/$fname.png" ||:
done <<< "$filesToRemove"
find . -type d -empty -delete
mkdir -p .thumbnails
images=$(find . -type f -not -path "./.thumbnails*")
while IFS= read fname; do
# Skip this file if an up-to-date thumbnail already exists
if [ -f ".thumbnails/$fname.png" ] && \
[ "$(date -R -r "$fname")" == "$(date -R -r ".thumbnails/$fname.png")" ]
then
continue
fi
echo "Creating thumbnail for $fname"
mkdir -p $(dirname ".thumbnails/$fname")
convert -define jpeg:size=200x200 "$fname" -thumbnail 300 -auto-orient ".thumbnails/$fname.png" ||:
touch -m -d "$(date -R -r "$fname")" ".thumbnails/$fname.png"
done <<< "$images"
'';
serviceConfig = {
WorkingDirectory = galleryDir;
User = config.services.pvv-nettsiden.user;
Group = config.services.pvv-nettsiden.group;
AmbientCapabilities = [ "" ];
CapabilityBoundingSet = [ "" ];
DeviceAllow = [ "" ];
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true; # disable for third party rotate scripts
PrivateDevices = true;
PrivateNetwork = true; # disable for mail delivery
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true; # disable for userdir logs
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
ProtectSystem = "full";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true; # disable for creating setgid directories
SocketBindDeny = [ "any" ];
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
];
};
};
}

View File

@ -0,0 +1,18 @@
{ ... }:
{
services.nginx.virtualHosts."www.pvv.ntnu.no".locations = {
"^~ /.well-known/" = {
alias = (toString ./root) + "/";
};
# Proxy the matrix well-known files
# Host has be set before proxy_pass
# The header must be set so nginx on the other side routes it to the right place
"^~ /.well-known/matrix/" = {
extraConfig = ''
proxy_set_header Host matrix.pvv.ntnu.no;
proxy_pass https://matrix.pvv.ntnu.no/.well-known/matrix/;
'';
};
};
}

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<clientConfig version="1.1">
<emailProvider id="pvv.ntnu.no">
<domain>pvv.ntnu.no</domain>
<domain>pvv.org</domain>
<displayName>Programvareverkstedet</displayName>
<incomingServer type="imap">
<hostname>imap.pvv.ntnu.no</hostname>
<port>993</port>
<socketType>SSL</socketType>
<username>%EMAILLOCALPART%</username>
<authentication>password-cleartext</authentication>
</incomingServer>
<outgoingServer type="smtp">
<hostname>smtp.pvv.ntnu.no</hostname>
<port>587</port>
<socketType>STARTTLS</socketType>
<username>%EMAILLOCALPART%</username>
<authentication>password-cleartext</authentication>
<useGlobalPreferredServer>true</useGlobalPreferredServer>
</outgoingServer>
<documentation url="https://www.pvv.ntnu.no/pvv/Drift/Mail/IMAP_POP3">
<descr lang="en">Setup programvareverkstedet email user with IMAP or POP3</descr>
<descr lang="nb">Sett opp programvareverkstedet email bruker med IMAP eller POP3</descr>
</documentation>
</emailProvider>
</clientConfig>

View File

@ -0,0 +1,12 @@
Contact: mailto:drift@pvv.ntnu.no
Contact: mailto:cert@pvv.ntnu.no
# drift@pvv.ntnu.no is read by more people and have a quicker reaction time,
# but cert@pvv.ntnu.no can be used for more severe issues.
Preferred-Languages: no, en
Expires: 2032-12-31T23:59:59.000Z
# This file was last updated 2024-09-14.
# You can find a wikipage for our security policies at:
# https://wiki.pvv.ntnu.no/wiki/CERT

View File

@ -1,24 +0,0 @@
{ values, ... }:
{
users.groups.acme.members = [ "nginx" ];
security.acme.certs."postgres.pvv.ntnu.no" = {
group = "acme";
extraDomainNames = [
# "postgres.pvv.org"
"bicep.pvv.ntnu.no"
# "bicep.pvv.org"
# values.hosts.bicep.ipv4
# values.hosts.bicep.ipv6
];
};
services.nginx = {
enable = true;
virtualHosts."postgres.pvv.ntnu.no" = {
forceSSL = true;
enableACME = true;
# useACMEHost = "postgres.pvv.ntnu.no";
};
};
}

View File

@ -1,24 +1,21 @@
{ pkgs, values, ... }: { fp, pkgs, values, ... }:
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../../base.nix (fp /base)
../../misc/metrics-exporters.nix (fp /misc/metrics-exporters.nix)
./services/nginx ./services/nginx
./acmeCert.nix
./services/mysql.nix ./services/mysql.nix
./services/postgres.nix ./services/postgres.nix
./services/mysql.nix ./services/mysql.nix
# TODO: fix the calendar bot ./services/calendar-bot.nix
# ./services/calendar-bot.nix
./services/matrix ./services/matrix
]; ];
sops.defaultSopsFile = ../../secrets/bicep/bicep.yaml; sops.defaultSopsFile = fp /secrets/bicep/bicep.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.age.keyFile = "/var/lib/sops-nix/key.txt"; sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true; sops.age.generateKey = true;
@ -37,6 +34,9 @@
anyInterface = true; anyInterface = true;
}; };
# There are no smart devices
services.smartd.enable = false;
# Do not change, even during upgrades. # Do not change, even during upgrades.
# See https://search.nixos.org/options?show=system.stateVersion # See https://search.nixos.org/options?show=system.stateVersion
system.stateVersion = "22.11"; system.stateVersion = "22.11";

View File

@ -1,12 +1,20 @@
{ config, lib, pkgs, ... }: { config, fp, lib, pkgs, ... }:
let let
cfg = config.services.pvv-calendar-bot; cfg = config.services.pvv-calendar-bot;
in { in {
sops.secrets."calendar-bot/matrix_token" = { sops.secrets = {
sopsFile = ../../../secrets/bicep/bicep.yaml; "calendar-bot/matrix_token" = {
key = "calendar-bot/matrix_token"; sopsFile = fp /secrets/bicep/bicep.yaml;
owner = cfg.user; key = "calendar-bot/matrix_token";
group = cfg.group; owner = cfg.user;
group = cfg.group;
};
"calendar-bot/mysql_password" = {
sopsFile = fp /secrets/bicep/bicep.yaml;
key = "calendar-bot/mysql_password";
owner = cfg.user;
group = cfg.group;
};
}; };
services.pvv-calendar-bot = { services.pvv-calendar-bot = {
@ -18,6 +26,11 @@ in {
user = "@bot_calendar:pvv.ntnu.no"; user = "@bot_calendar:pvv.ntnu.no";
channel = "!gkNLUIhYVpEyLatcRz:pvv.ntnu.no"; channel = "!gkNLUIhYVpEyLatcRz:pvv.ntnu.no";
}; };
database = {
host = "mysql.pvv.ntnu.no";
user = "calendar-bot";
passwordFile = config.sops.secrets."calendar-bot/mysql_password".path;
};
secretsFile = config.sops.secrets."calendar-bot/matrix_token".path; secretsFile = config.sops.secrets."calendar-bot/matrix_token".path;
onCalendar = "*-*-* 09:00:00"; onCalendar = "*-*-* 09:00:00";
}; };

View File

@ -1,14 +1,14 @@
{ config, lib, pkgs, secrets, ... }: { config, lib, fp, pkgs, secrets, values, ... }:
{ {
sops.secrets."matrix/synapse/turnconfig" = { sops.secrets."matrix/synapse/turnconfig" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml; sopsFile = fp /secrets/bicep/matrix.yaml;
key = "synapse/turnconfig"; key = "synapse/turnconfig";
owner = config.users.users.matrix-synapse.name; owner = config.users.users.matrix-synapse.name;
group = config.users.users.matrix-synapse.group; group = config.users.users.matrix-synapse.group;
}; };
sops.secrets."matrix/coturn/static-auth-secret" = { sops.secrets."matrix/coturn/static-auth-secret" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml; sopsFile = fp /secrets/bicep/matrix.yaml;
key = "coturn/static-auth-secret"; key = "coturn/static-auth-secret";
owner = config.users.users.turnserver.name; owner = config.users.users.turnserver.name;
group = config.users.users.turnserver.group; group = config.users.users.turnserver.group;
@ -60,12 +60,14 @@
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
use-auth-secret = true; use-auth-secret = true;
# World readable but I dont think it's that bad
static-auth-secret-file = config.sops.secrets."matrix/coturn/static-auth-secret".path; static-auth-secret-file = config.sops.secrets."matrix/coturn/static-auth-secret".path;
secure-stun = true; secure-stun = true;
listening-ips = [ "129.241.210.213" "2001:700:300:1900::213" ]; listening-ips = [
values.services.turn.ipv4
# values.services.turn.ipv6
];
tls-listening-port = 443; tls-listening-port = 443;
alt-tls-listening-port = 5349; alt-tls-listening-port = 5349;

View File

@ -10,6 +10,7 @@
./mjolnir.nix ./mjolnir.nix
./discord.nix ./discord.nix
./hookshot
]; ];

View File

@ -1,4 +1,4 @@
{ config, lib, ... }: { config, lib, fp, ... }:
let let
cfg = config.services.mx-puppet-discord; cfg = config.services.mx-puppet-discord;
@ -6,15 +6,42 @@ in
{ {
users.groups.keys-matrix-registrations = { }; users.groups.keys-matrix-registrations = { };
sops.secrets."matrix/registrations/mx-puppet-discord" = { sops.secrets."matrix/discord/as_token" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml; sopsFile = fp /secrets/bicep/matrix.yaml;
key = "registrations/mx-puppet-discord"; key = "discord/as_token";
};
sops.secrets."matrix/discord/hs_token" = {
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "discord/hs_token";
};
sops.templates."discord-registration.yaml" = {
owner = config.users.users.matrix-synapse.name; owner = config.users.users.matrix-synapse.name;
group = config.users.groups.keys-matrix-registrations.name; group = config.users.groups.keys-matrix-registrations.name;
content = ''
as_token: "${config.sops.placeholder."matrix/discord/as_token"}"
hs_token: "${config.sops.placeholder."matrix/discord/hs_token"}"
id: discord-puppet
namespaces:
users:
- exclusive: true
regex: '@_discordpuppet_.*'
rooms: []
aliases:
- exclusive: true
regex: '#_discordpuppet_.*'
protocols: []
rate_limited: false
sender_localpart: _discordpuppet_bot
url: 'http://localhost:8434'
de.sorunome.msc2409.push_ephemeral: true
'';
}; };
systemd.services.mx-puppet-discord = { systemd.services.mx-puppet-discord = {
serviceConfig.SupplementaryGroups = [ config.users.groups.keys-matrix-registrations.name ]; serviceConfig.SupplementaryGroups = [
config.users.groups.keys-matrix-registrations.name
];
}; };
@ -29,11 +56,16 @@ in
relay.whitelist = [ ".*" ]; relay.whitelist = [ ".*" ];
selfService.whitelist = [ "@danio:pvv\\.ntnu\\.no" "@dandellion:dodsorf\\.as" ]; selfService.whitelist = [ "@danio:pvv\\.ntnu\\.no" "@dandellion:dodsorf\\.as" ];
}; };
services.mx-puppet-discord.serviceDependencies = [ "matrix-synapse.target" "nginx.service" ]; services.mx-puppet-discord.serviceDependencies = [
"matrix-synapse.target"
"nginx.service"
];
services.matrix-synapse-next.settings = { services.matrix-synapse-next.settings = {
app_service_config_files = [ config.sops.secrets."matrix/registrations/mx-puppet-discord".path ]; app_service_config_files = [
config.sops.templates."discord-registration.yaml".path
];
use_appservice_legacy_authorization = true; use_appservice_legacy_authorization = true;
}; };

View File

@ -5,6 +5,7 @@ in {
services.nginx.virtualHosts."chat.pvv.ntnu.no" = { services.nginx.virtualHosts."chat.pvv.ntnu.no" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
kTLS = true;
root = pkgs.element-web.override { root = pkgs.element-web.override {
conf = { conf = {
@ -24,21 +25,26 @@ in {
features = { features = {
feature_latex_maths = true; feature_latex_maths = true;
feature_pinning = true; feature_pinning = true;
feature_render_reaction_images = true;
feature_state_counters = true; feature_state_counters = true;
feature_custom_status = false; # element call group calls
feature_group_calls = true;
}; };
default_theme = "dark"; default_theme = "dark";
# Servers in this list should provide some sort of valuable scoping
# matrix.org is not useful compared to matrixrooms.info,
# because it has so many general members, rooms of all topics are on it.
# Something matrixrooms.info is already providing.
room_directory.servers = [ room_directory.servers = [
"pvv.ntnu.no" "pvv.ntnu.no"
"matrix.omegav.no" "matrixrooms.info" # Searches all public room directories
"matrix.org" "matrix.omegav.no" # Friends
"libera.chat" "gitter.im" # gitter rooms
"gitter.im" "mozilla.org" # mozilla and friends
"mozilla.org" "kde.org" # KDE rooms
"kde.org" "fosdem.org" # FOSDEM
"t2bot.io" "dodsorf.as" # PVV Member
"fosdem.org" "nani.wtf" # PVV Member
"dodsorf.as"
]; ];
enable_presence_by_hs_url = { enable_presence_by_hs_url = {
"https://matrix.org" = false; "https://matrix.org" = false;

View File

@ -0,0 +1,139 @@
{ config, lib, fp, unstablePkgs, inputs, ... }:
let
cfg = config.services.matrix-hookshot;
webhookListenAddress = "127.0.0.1";
webhookListenPort = 8435;
in
{
imports = [
./module.nix
];
sops.secrets."matrix/hookshot/as_token" = {
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "hookshot/as_token";
};
sops.secrets."matrix/hookshot/hs_token" = {
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "hookshot/hs_token";
};
sops.templates."hookshot-registration.yaml" = {
owner = config.users.users.matrix-synapse.name;
group = config.users.groups.keys-matrix-registrations.name;
content = ''
id: matrix-hookshot
as_token: "${config.sops.placeholder."matrix/hookshot/as_token"}"
hs_token: "${config.sops.placeholder."matrix/hookshot/hs_token"}"
namespaces:
rooms: []
users:
- regex: "@_webhooks_.*:pvv.ntnu.no"
exclusive: true
- regex: "@bot_feeds:pvv.ntnu.no"
exclusive: true
aliases: []
sender_localpart: hookshot
url: "http://${cfg.settings.bridge.bindAddress}:${toString cfg.settings.bridge.port}"
rate_limited: false
# If enabling encryption
de.sorunome.msc2409.push_ephemeral: true
push_ephemeral: true
org.matrix.msc3202: true
'';
};
systemd.services.matrix-hookshot = {
serviceConfig.SupplementaryGroups = [
config.users.groups.keys-matrix-registrations.name
];
};
services.matrix-hookshot = {
enable = true;
package = unstablePkgs.matrix-hookshot;
registrationFile = config.sops.templates."hookshot-registration.yaml".path;
settings = {
bridge = {
bindAddress = "127.0.0.1";
domain = "pvv.ntnu.no";
url = "https://matrix.pvv.ntnu.no";
mediaUrl = "https://matrix.pvv.ntnu.no";
port = 9993;
};
listeners = [
{
bindAddress = webhookListenAddress;
port = webhookListenPort;
resources = [
"webhooks"
# "metrics"
# "provisioning"
"widgets"
];
}
];
generic = {
enabled = true;
outbound = true;
urlPrefix = "https://hookshot.pvv.ntnu.no/webhook/";
userIdPrefix = "_webhooks_";
allowJsTransformationFunctions = false;
waitForComplete = false;
};
feeds = {
enabled = true;
pollIntervalSeconds = 600;
};
serviceBots = [
{ localpart = "bot_feeds";
displayname = "Aya";
avatar = ./feeds.png;
prefix = "!aya";
service = "feeds";
}
];
permissions = [
# Users of the PVV Server
{ actor = "pvv.ntnu.no";
services = [ { service = "*"; level = "commands"; } ];
}
# Members of Medlem space (for people with their own hs)
{ actor = "!pZOTJQinWyyTWaeOgK:pvv.ntnu.no";
services = [ { service = "*"; level = "commands"; } ];
}
# Members of Drift
{ actor = "!eYgeufLrninXxQpYml:pvv.ntnu.no";
services = [ { service = "*"; level = "admin"; } ];
}
# Dan bootstrap
{ actor = "@dandellion:dodsorf.as";
services = [ { service = "*"; level = "admin"; } ];
}
];
};
};
services.matrix-hookshot.serviceDependencies = [
"matrix-synapse.target"
"nginx.service"
];
services.matrix-synapse-next.settings = {
app_service_config_files = [
config.sops.templates."hookshot-registration.yaml".path
];
};
services.nginx.virtualHosts."hookshot.pvv.ntnu.no" = {
enableACME = true;
locations."/" = {
proxyPass = "http://${webhookListenAddress}:${toString webhookListenPort}";
};
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,127 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.services.matrix-hookshot;
settingsFormat = pkgs.formats.yaml { };
configFile = settingsFormat.generate "matrix-hookshot-config.yml" cfg.settings;
in
{
options = {
services.matrix-hookshot = {
enable = lib.mkEnableOption "matrix-hookshot, a bridge between Matrix and project management services";
package = lib.mkPackageOption pkgs "matrix-hookshot" { };
registrationFile = lib.mkOption {
type = lib.types.path;
description = ''
Appservice registration file.
As it contains secret tokens, you may not want to add this to the publicly readable Nix store.
'';
example = lib.literalExpression ''
pkgs.writeText "matrix-hookshot-registration" \'\'
id: matrix-hookshot
as_token: aaaaaaaaaa
hs_token: aaaaaaaaaa
namespaces:
rooms: []
users:
- regex: "@_webhooks_.*:foobar"
exclusive: true
sender_localpart: hookshot
url: "http://localhost:9993"
rate_limited: false
\'\'
'';
};
settings = lib.mkOption {
description = ''
{file}`config.yml` configuration as a Nix attribute set.
For details please see the [documentation](https://matrix-org.github.io/matrix-hookshot/latest/setup/sample-configuration.html).
'';
example = {
bridge = {
domain = "example.com";
url = "http://localhost:8008";
mediaUrl = "https://example.com";
port = 9993;
bindAddress = "127.0.0.1";
};
listeners = [
{
port = 9000;
bindAddress = "0.0.0.0";
resources = [ "webhooks" ];
}
{
port = 9001;
bindAddress = "localhost";
resources = [
"metrics"
"provisioning"
];
}
];
};
default = { };
type = lib.types.submodule {
freeformType = settingsFormat.type;
options = {
passFile = lib.mkOption {
type = lib.types.path;
default = "/var/lib/matrix-hookshot/passkey.pem";
description = ''
A passkey used to encrypt tokens stored inside the bridge.
File will be generated if not found.
'';
};
};
};
};
serviceDependencies = lib.mkOption {
type = with lib.types; listOf str;
default = lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit;
defaultText = lib.literalExpression ''
lib.optional config.services.matrix-synapse.enable config.services.matrix-synapse.serviceUnit
'';
description = ''
List of Systemd services to require and wait for when starting the application service,
such as the Matrix homeserver if it's running on the same host.
'';
};
};
};
config = lib.mkIf cfg.enable {
systemd.services.matrix-hookshot = {
description = "a bridge between Matrix and multiple project management services";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ] ++ cfg.serviceDependencies;
after = [ "network-online.target" ] ++ cfg.serviceDependencies;
preStart = ''
if [ ! -f '${cfg.settings.passFile}' ]; then
mkdir -p $(dirname '${cfg.settings.passFile}')
${pkgs.openssl}/bin/openssl genpkey -out '${cfg.settings.passFile}' -outform PEM -algorithm RSA -pkeyopt rsa_keygen_bits:4096
fi
'';
serviceConfig = {
Type = "simple";
Restart = "always";
ExecStart = "${cfg.package}/bin/matrix-hookshot ${configFile} ${cfg.registrationFile}";
};
};
};
meta.maintainers = with lib.maintainers; [ flandweber ];
}

View File

@ -1,8 +1,8 @@
{ config, lib, ... }: { config, lib, fp, ... }:
{ {
sops.secrets."matrix/mjolnir/access_token" = { sops.secrets."matrix/mjolnir/access_token" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml; sopsFile = fp /secrets/bicep/matrix.yaml;
key = "mjolnir/access_token"; key = "mjolnir/access_token";
owner = config.users.users.mjolnir.name; owner = config.users.users.mjolnir.name;
group = config.users.users.mjolnir.group; group = config.users.users.mjolnir.group;
@ -11,7 +11,7 @@
services.mjolnir = { services.mjolnir = {
enable = true; enable = true;
pantalaimon.enable = false; pantalaimon.enable = false;
homeserverUrl = http://127.0.0.1:8008; homeserverUrl = "https://matrix.pvv.ntnu.no";
accessTokenFile = config.sops.secrets."matrix/mjolnir/access_token".path; accessTokenFile = config.sops.secrets."matrix/mjolnir/access_token".path;
managementRoom = "!gsdeCoWjvYRBrzuiRq:pvv.ntnu.no"; managementRoom = "!gsdeCoWjvYRBrzuiRq:pvv.ntnu.no";
protectedRooms = map (a: "https://matrix.to/#/${a}") [ protectedRooms = map (a: "https://matrix.to/#/${a}") [

View File

@ -7,6 +7,9 @@ from synapse import module_api
import re import re
import logging
logger = logging.getLogger(__name__)
class SMTPAuthProvider: class SMTPAuthProvider:
def __init__(self, config: dict, api: module_api): def __init__(self, config: dict, api: module_api):
self.api = api self.api = api
@ -43,8 +46,13 @@ class SMTPAuthProvider:
if result == True: if result == True:
userid = self.api.get_qualified_user_id(username) userid = self.api.get_qualified_user_id(username)
if not self.api.check_user_exists(userid):
self.api.register_user(username) userid = await self.api.check_user_exists(userid)
if not userid:
logger.info(f"user did not exist, registering {username}")
userid = await self.api.register_user(username)
logger.info(f"registered userid: {userid}")
return (userid, None) return (userid, None)
else: else:
logger.info("returning None")
return None return None

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, values, inputs, ... }: { config, lib, fp, pkgs, values, inputs, ... }:
let let
cfg = config.services.matrix-synapse-next; cfg = config.services.matrix-synapse-next;
@ -10,23 +10,18 @@ let
in { in {
sops.secrets."matrix/synapse/signing_key" = { sops.secrets."matrix/synapse/signing_key" = {
key = "synapse/signing_key"; key = "synapse/signing_key";
sopsFile = ../../../../secrets/bicep/matrix.yaml; sopsFile = fp /secrets/bicep/matrix.yaml;
owner = config.users.users.matrix-synapse.name; owner = config.users.users.matrix-synapse.name;
group = config.users.users.matrix-synapse.group; group = config.users.users.matrix-synapse.group;
}; };
sops.secrets."matrix/synapse/user_registration" = { sops.secrets."matrix/synapse/user_registration" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml; sopsFile = fp /secrets/bicep/matrix.yaml;
key = "synapse/signing_key"; key = "synapse/signing_key";
owner = config.users.users.matrix-synapse.name; owner = config.users.users.matrix-synapse.name;
group = config.users.users.matrix-synapse.group; group = config.users.users.matrix-synapse.group;
}; };
sops.secrets."matrix/sliding-sync/env" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml;
key = "sliding-sync/env";
};
services.matrix-synapse-next = { services.matrix-synapse-next = {
enable = true; enable = true;
@ -43,8 +38,6 @@ in {
workers.eventPersisters = 2; workers.eventPersisters = 2;
workers.useUserDirectoryWorker = true; workers.useUserDirectoryWorker = true;
enableSlidingSync = true;
enableNginx = true; enableNginx = true;
settings = { settings = {
@ -134,90 +127,16 @@ in {
"129.241.0.0/16" "129.241.0.0/16"
"2001:700:300::/44" "2001:700:300::/44"
]; ];
saml2_config = {
sp_config.metadata.remote = [
{ url = "https://idp.pvv.ntnu.no/simplesaml/saml2/idp/metadata.php"; }
];
description = [ "Matrix Synapse SP" "en" ];
name = [ "Matrix Synapse SP" "en" ];
ui_info = {
display_name = [
{
lang = "en";
text = "PVV Matrix login";
}
];
description = [
{
lang = "en";
text = "Matrix is a modern free and open federated chat protocol";
}
];
#information_url = [
# {
# lang = "en";
# text = "";
# };
#];
#privacy_statement_url = [
# {
# lang = "en";
# text = "";
# };
#];
keywords = [
{
lang = "en";
text = [ "Matrix" "Element" ];
}
];
#logo = [
# {
# lang = "en";
# text = "";
# width = "";
# height = "";
# }
#];
};
organization = {
name = "Programvareverkstedet";
display_name = [ "Programvareverkstedet" "en" ];
url = "https://www.pvv.ntnu.no";
};
contact_person = [
{ given_name = "Drift";
sur_name = "King";
email_adress = [ "drift@pvv.ntnu.no" ];
contact_type = "technical";
}
];
user_mapping_provider = {
config = {
mxid_source_attribute = "uid"; # What is this supposed to be?
mxid_mapping = "hexencode";
};
};
#attribute_requirements = [
# {attribute = "userGroup"; value = "medlem";} # Do we have this?
#];
};
}; };
}; };
services.matrix-synapse.sliding-sync.environmentFile = config.sops.secrets."matrix/sliding-sync/env".path;
services.redis.servers."".enable = true; services.redis.servers."".enable = true;
services.nginx.virtualHosts."matrix.pvv.ntnu.no" = lib.mkMerge [ services.nginx.virtualHosts."matrix.pvv.ntnu.no" = lib.mkMerge [
({ {
kTLS = true;
}
{
locations."/.well-known/matrix/server" = { locations."/.well-known/matrix/server" = {
return = '' return = ''
200 '{"m.server": "matrix.pvv.ntnu.no:443"}' 200 '{"m.server": "matrix.pvv.ntnu.no:443"}'
@ -227,26 +146,38 @@ in {
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Origin *;
''; '';
}; };
}) }
({ {
locations."/_synapse/admin" = {
proxyPass = "http://$synapse_backend";
extraConfig = ''
allow 127.0.0.1;
allow ::1;
allow ${values.hosts.bicep.ipv4};
allow ${values.hosts.bicep.ipv6};
deny all;
'';
};
}
{
locations = let locations = let
connectionInfo = w: matrix-lib.workerConnectionResource "metrics" w; connectionInfo = w: matrix-lib.workerConnectionResource "metrics" w;
socketAddress = w: let c = connectionInfo w; in "${c.host}:${toString (c.port)}"; socketAddress = w: let c = connectionInfo w; in "${c.host}:${toString c.port}";
metricsPath = w: "/metrics/${w.type}/${toString w.index}"; metricsPath = w: "/metrics/${w.type}/${toString w.index}";
proxyPath = w: "http://${socketAddress w}/_synapse/metrics"; proxyPath = w: "http://${socketAddress w}/_synapse/metrics";
in lib.mapAttrs' (n: v: lib.nameValuePair in lib.mapAttrs' (n: v: lib.nameValuePair
(metricsPath v) ({ (metricsPath v) {
proxyPass = proxyPath v; proxyPass = proxyPath v;
extraConfig = '' extraConfig = ''
allow ${values.hosts.ildkule.ipv4}; allow ${values.hosts.ildkule.ipv4};
allow ${values.hosts.ildkule.ipv6}; allow ${values.hosts.ildkule.ipv6};
deny all; deny all;
''; '';
})) })
cfg.workers.instances; cfg.workers.instances;
}) }
({ {
locations."/metrics/master/1" = { locations."/metrics/master/1" = {
proxyPass = "http://127.0.0.1:9000/_synapse/metrics"; proxyPass = "http://127.0.0.1:9000/_synapse/metrics";
extraConfig = '' extraConfig = ''
@ -269,5 +200,5 @@ in {
labels = { }; labels = { };
}]) + "/"; }]) + "/";
}; };
})]; }];
} }

View File

@ -15,12 +15,12 @@
mysqld = { mysqld = {
# PVV allows a lot of connections at the same time # PVV allows a lot of connections at the same time
max_connect_errors = 10000; max_connect_errors = 10000;
bind-address = values.services.mysql.ipv4; bind-address = values.services.mysql.ipv4;
skip-networking = 0; skip-networking = 0;
# This was needed in order to be able to use all of the old users # This was needed in order to be able to use all of the old users
# during migration from knakelibrak to bicep in Sep. 2023 # during migration from knakelibrak to bicep in Sep. 2023
secure_auth = 0; secure_auth = 0;
}; };
}; };

View File

@ -1,15 +1,8 @@
{ config, values, ... }: { config, values, ... }:
{ {
security.acme = {
acceptTerms = true;
defaults.email = "danio@pvv.ntnu.no";
};
services.nginx = { services.nginx = {
enable = true; enable = true;
enableReload = true; enableReload = true;
defaultListenAddresses = [ defaultListenAddresses = [
values.hosts.bicep.ipv4 values.hosts.bicep.ipv4
"[${values.hosts.bicep.ipv6}]" "[${values.hosts.bicep.ipv6}]"
@ -18,28 +11,5 @@
"127.0.0.2" "127.0.0.2"
"[::1]" "[::1]"
]; ];
appendConfig = ''
pcre_jit on;
worker_processes 8;
worker_rlimit_nofile 8192;
'';
eventsConfig = ''
multi_accept on;
worker_connections 4096;
'';
recommendedProxySettings = true;
recommendedTlsSettings = true;
recommendedGzipSettings = true;
recommendedBrotliSettings = true;
recommendedOptimisation = true;
};
networking.firewall.allowedTCPPorts = [ 80 443 ];
systemd.services.nginx.serviceConfig = {
LimitNOFILE = 65536;
}; };
} }

View File

@ -1,7 +1,4 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
let
sslCert = config.security.acme.certs."postgres.pvv.ntnu.no";
in
{ {
services.postgresql = { services.postgresql = {
enable = true; enable = true;
@ -79,12 +76,16 @@ in
systemd.services.postgresql.serviceConfig = { systemd.services.postgresql.serviceConfig = {
LoadCredential = [ LoadCredential = [
"cert:${sslCert.directory}/cert.pem" "cert:/etc/certs/postgres.crt"
"key:${sslCert.directory}/key.pem" "key:/etc/certs/postgres.key"
]; ];
}; };
users.groups.acme.members = [ "postgres" ]; environment.snakeoil-certs."/etc/certs/postgres" = {
owner = "postgres";
group = "postgres";
subject = "/C=NO/O=Programvareverkstedet/CN=postgres.pvv.ntnu.no/emailAddress=drift@pvv.ntnu.no";
};
networking.firewall.allowedTCPPorts = [ 5432 ]; networking.firewall.allowedTCPPorts = [ 5432 ];
networking.firewall.allowedUDPPorts = [ 5432 ]; networking.firewall.allowedUDPPorts = [ 5432 ];

View File

@ -1,16 +1,16 @@
{ config, pkgs, values, ... }: { config, fp, pkgs, values, ... }:
{ {
imports = [ imports = [
# Include the results of the hardware scan. # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
../../base.nix (fp /base)
../../misc/metrics-exporters.nix (fp /misc/metrics-exporters.nix)
./disks.nix ./disks.nix
../../misc/builder.nix (fp /misc/builder.nix)
]; ];
sops.defaultSopsFile = ../../secrets/bob/bob.yaml; sops.defaultSopsFile = fp /secrets/bob/bob.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.age.keyFile = "/var/lib/sops-nix/key.txt"; sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true; sops.age.generateKey = true;

View File

@ -1,10 +1,10 @@
{ config, pkgs, values, ... }: { config, fp, pkgs, values, ... }:
{ {
imports = [ imports = [
# Include the results of the hardware scan. # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
../../base.nix (fp /base)
../../misc/metrics-exporters.nix (fp /misc/metrics-exporters.nix)
./services/grzegorz.nix ./services/grzegorz.nix
]; ];

View File

@ -1,6 +1,6 @@
{ config, ... }: { config, fp, ... }:
{ {
imports = [ ../../../modules/grzegorz.nix ]; imports = [ (fp /modules/grzegorz.nix) ];
services.nginx.virtualHosts."${config.networking.fqdn}" = { services.nginx.virtualHosts."${config.networking.fqdn}" = {
serverAliases = [ serverAliases = [

View File

@ -1,36 +0,0 @@
{ config, pkgs, values, ... }:
{
imports = [
./hardware-configuration.nix
../../base.nix
../../misc/metrics-exporters.nix
];
# buskerud does not support efi?
# boot.loader.systemd-boot.enable = true;
# boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.enable = true;
boot.loader.grub.device = "/dev/sdb";
networking.hostName = "buskerud";
networking.search = [ "pvv.ntnu.no" "pvv.org" ];
networking.nameservers = [ "129.241.0.200" "129.241.0.201" ];
networking.tempAddresses = "disabled";
systemd.network.networks."enp3s0f0" = values.defaultNetworkConfig // {
matchConfig.Name = "enp3s0f0";
address = with values.hosts.buskerud; [ (ipv4 + "/25") (ipv6 + "/64") ];
};
# List packages installed in system profile
environment.systemPackages = with pkgs; [
];
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "23.05"; # Did you read the comment?
}

View File

@ -1,37 +0,0 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ "uhci_hcd" "ehci_pci" "ata_piix" "hpsa" "usb_storage" "usbhid" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ "kvm-intel" ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/ed9654fe-575a-4fb3-b6ff-1b059479acff";
fsType = "ext4";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.enp14s0f0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp14s0f1.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0f0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp3s0f1.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0f0.useDHCP = lib.mkDefault true;
# networking.interfaces.enp4s0f1.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View File

@ -1,12 +1,12 @@
{ config, pkgs, values, ... }: { config, fp, pkgs, values, ... }:
{ {
imports = [ imports = [
# Include the results of the hardware scan. # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
../../base.nix (fp /base)
../../misc/metrics-exporters.nix (fp /misc/metrics-exporters.nix)
../../modules/grzegorz.nix (fp /modules/grzegorz.nix)
]; ];
boot.loader.systemd-boot.enable = true; boot.loader.systemd-boot.enable = true;

View File

@ -1,42 +1,55 @@
{ config, pkgs, values, ... }: { config, fp, pkgs, lib, values, ... }:
{ {
imports = [ imports = [
# Include the results of the hardware scan. # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
../../base.nix (fp /base)
../../misc/metrics-exporters.nix (fp /misc/metrics-exporters.nix)
./services/monitoring
./services/nginx ./services/nginx
./services/metrics
]; ];
sops.defaultSopsFile = ../../secrets/ildkule/ildkule.yaml; sops.defaultSopsFile = fp /secrets/ildkule/ildkule.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.age.keyFile = "/var/lib/sops-nix/key.txt"; sops.age.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true; sops.age.generateKey = true;
boot.loader.systemd-boot.enable = true; boot.loader.grub.device = "/dev/vda";
boot.loader.efi.canTouchEfiVariables = true; boot.tmp.cleanOnBoot = true;
zramSwap.enable = true;
networking.hostName = "ildkule"; # Define your hostname. # Openstack Neutron and systemd-networkd are not best friends, use something else:
systemd.network.enable = lib.mkForce false;
networking = let
hostConf = values.hosts.ildkule;
in {
hostName = "ildkule";
tempAddresses = "disabled";
useDHCP = lib.mkForce true;
systemd.network.networks."30-ens18" = values.defaultNetworkConfig // { search = values.defaultNetworkConfig.domains;
matchConfig.Name = "ens18"; nameservers = values.defaultNetworkConfig.dns;
address = with values.hosts.ildkule; [ (ipv4 + "/25") (ipv6 + "/64") ]; defaultGateway.address = hostConf.ipv4_internal_gw;
interfaces."ens4" = {
ipv4.addresses = [
{ address = hostConf.ipv4; prefixLength = 32; }
{ address = hostConf.ipv4_internal; prefixLength = 24; }
];
ipv6.addresses = [
{ address = hostConf.ipv6; prefixLength = 64; }
];
};
}; };
# List packages installed in system profile # List packages installed in system profile
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
]; ];
# List services that you want to enable: # No devices with SMART
services.smartd.enable = false;
# This value determines the NixOS release from which the default system.stateVersion = "23.11"; # Did you read the comment?
# settings for stateful data, like file locations and database versions
# on your system were taken. Its perfectly fine and recommended to leave
# this value at the release version of the first install of this system.
# Before changing this value read the documentation for this option
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
system.stateVersion = "21.11"; # Did you read the comment?
} }

View File

@ -1,37 +1,16 @@
# Do not modify this file! It was generated by nixos-generate-config { modulesPath, lib, ... }:
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{ {
imports = imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
[ (modulesPath + "/profiles/qemu-guest.nix") boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
]; boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = {
device = "/dev/disk/by-uuid/e35eb4ce-aac3-4f91-8383-6e7cd8bbf942";
fsType = "ext4";
};
fileSystems."/data" = {
device = "/dev/disk/by-uuid/0a4c1234-02d3-4b53-aeca-d95c4c8d534b";
fsType = "ext4";
};
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/afe70fe4-681a-4675-8cbd-e5d08cdcf5b5";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/B71A-E5CD";
fsType = "vfat";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
} }

View File

@ -1,16 +0,0 @@
{ config, ... }: let
cfg = config.services.prometheus;
in {
services.prometheus.scrapeConfigs = [{
job_name = "git-gogs";
scheme = "https";
metrics_path = "/-/metrics";
static_configs = [
{
targets = [
"essendrop.pvv.ntnu.no:443"
];
}
];
}];
}

View File

@ -1,22 +0,0 @@
{ config, ... }: let
cfg = config.services.prometheus;
in {
services.prometheus.scrapeConfigs = [{
job_name = "node";
static_configs = [
{
targets = [
"ildkule.pvv.ntnu.no:${toString cfg.exporters.node.port}"
"microbel.pvv.ntnu.no:9100"
"isvegg.pvv.ntnu.no:9100"
"knakelibrak.pvv.ntnu.no:9100"
"hildring.pvv.ntnu.no:9100"
"bicep.pvv.ntnu.no:9100"
"essendrop.pvv.ntnu.no:9100"
"andresbu.pvv.ntnu.no:9100"
"bekkalokk.pvv.ntnu.no:9100"
];
}
];
}];
}

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,9 @@
{ {
imports = [ imports = [
./prometheus
./grafana.nix ./grafana.nix
./loki.nix ./loki.nix
./prometheus
./uptime-kuma.nix
]; ];
} }

View File

@ -7,7 +7,6 @@ in {
in { in {
"keys/grafana/secret_key" = { inherit owner group; }; "keys/grafana/secret_key" = { inherit owner group; };
"keys/grafana/admin_password" = { inherit owner group; }; "keys/grafana/admin_password" = { inherit owner group; };
"keys/postgres/grafana" = { inherit owner group; };
}; };
services.grafana = { services.grafana = {
@ -18,7 +17,7 @@ in {
secretFile = path: "$__file{${path}}"; secretFile = path: "$__file{${path}}";
in { in {
server = { server = {
domain = "ildkule.pvv.ntnu.no"; domain = "grafana.pvv.ntnu.no";
http_port = 2342; http_port = 2342;
http_addr = "127.0.0.1"; http_addr = "127.0.0.1";
}; };
@ -27,13 +26,6 @@ in {
secret_key = secretFile config.sops.secrets."keys/grafana/secret_key".path; secret_key = secretFile config.sops.secrets."keys/grafana/secret_key".path;
admin_password = secretFile config.sops.secrets."keys/grafana/admin_password".path; admin_password = secretFile config.sops.secrets."keys/grafana/admin_password".path;
}; };
database = {
type = "postgres";
user = "grafana";
host = "${values.hosts.bicep.ipv4}:5432";
password = secretFile config.sops.secrets."keys/postgres/grafana".path;
};
}; };
provision = { provision = {
@ -42,13 +34,13 @@ in {
{ {
name = "Ildkule Prometheus"; name = "Ildkule Prometheus";
type = "prometheus"; type = "prometheus";
url = ("http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}"); url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}";
isDefault = true; isDefault = true;
} }
{ {
name = "Ildkule loki"; name = "Ildkule loki";
type = "loki"; type = "loki";
url = ("http://${config.services.loki.configuration.server.http_listen_address}:${toString config.services.loki.configuration.server.http_listen_port}"); url = "http://${config.services.loki.configuration.server.http_listen_address}:${toString config.services.loki.configuration.server.http_listen_port}";
} }
]; ];
dashboards.settings.providers = [ dashboards.settings.providers = [
@ -64,13 +56,13 @@ in {
url = "https://raw.githubusercontent.com/matrix-org/synapse/develop/contrib/grafana/synapse.json"; url = "https://raw.githubusercontent.com/matrix-org/synapse/develop/contrib/grafana/synapse.json";
options.path = dashboards/synapse.json; options.path = dashboards/synapse.json;
} }
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged # TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
# { # {
# name = "MySQL"; # name = "MySQL";
# type = "file"; # type = "file";
# url = "https://raw.githubusercontent.com/prometheus/mysqld_exporter/main/mysqld-mixin/dashboards/mysql-overview.json"; # url = "https://raw.githubusercontent.com/prometheus/mysqld_exporter/main/mysqld-mixin/dashboards/mysql-overview.json";
# options.path = dashboards/mysql.json; # options.path = dashboards/mysql.json;
# } # }
{ {
name = "Postgresql"; name = "Postgresql";
type = "file"; type = "file";
@ -83,6 +75,12 @@ in {
url = "https://grafana.com/api/dashboards/240/revisions/3/download"; url = "https://grafana.com/api/dashboards/240/revisions/3/download";
options.path = dashboards/go-processes.json; options.path = dashboards/go-processes.json;
} }
{
name = "Gitea Dashbaord";
type = "file";
url = "https://grafana.com/api/dashboards/17802/revisions/3/download";
options.path = dashboards/gitea-dashbaord.json;
}
]; ];
}; };
@ -91,6 +89,7 @@ in {
services.nginx.virtualHosts.${cfg.settings.server.domain} = { services.nginx.virtualHosts.${cfg.settings.server.domain} = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
kTLS = true;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://127.0.0.1:${toString cfg.settings.server.http_port}"; proxyPass = "http://127.0.0.1:${toString cfg.settings.server.http_port}";

View File

@ -2,6 +2,7 @@
let let
cfg = config.services.loki; cfg = config.services.loki;
stateDir = "/data/monitoring/loki";
in { in {
services.loki = { services.loki = {
enable = true; enable = true;
@ -16,7 +17,7 @@ in {
ingester = { ingester = {
wal = { wal = {
enabled = true; enabled = true;
dir = "/var/lib/loki/wal"; dir = "${stateDir}/wal";
}; };
lifecycler = { lifecycler = {
address = "127.0.0.1"; address = "127.0.0.1";
@ -48,32 +49,30 @@ in {
storage_config = { storage_config = {
boltdb_shipper = { boltdb_shipper = {
active_index_directory = "/var/lib/loki/boltdb-shipper-index"; active_index_directory = "${stateDir}/boltdb-shipper-index";
cache_location = "/var/lib/loki/boltdb-shipper-cache"; cache_location = "${stateDir}/boltdb-shipper-cache";
shared_store = "filesystem";
cache_ttl = "24h"; cache_ttl = "24h";
}; };
filesystem = { filesystem = {
directory = "/var/lib/loki/chunks"; directory = "${stateDir}/chunks";
}; };
}; };
limits_config = { limits_config = {
enforce_metric_name = false; allow_structured_metadata = false;
reject_old_samples = true; reject_old_samples = true;
reject_old_samples_max_age = "72h"; reject_old_samples_max_age = "72h";
}; };
compactor = { compactor = {
working_directory = "/var/lib/loki/compactor"; working_directory = "${stateDir}/compactor";
shared_store = "filesystem";
}; };
# ruler = { # ruler = {
# storage = { # storage = {
# type = "local"; # type = "local";
# local = { # local = {
# directory = "/var/lib/loki/rules"; # directory = "${stateDir}/rules";
# }; # };
# }; # };
# rule_path = "/etc/loki/rules"; # rule_path = "/etc/loki/rules";

View File

@ -1,18 +1,26 @@
{ config, ... }: { { config, ... }: let
stateDir = "/data/monitoring/prometheus";
in {
imports = [ imports = [
./gogs.nix ./gitea.nix
./matrix-synapse.nix ./matrix-synapse.nix
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged # TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
# ./mysqld.nix # ./mysqld.nix
./node.nix
./postgres.nix ./postgres.nix
./machines.nix
]; ];
services.prometheus = { services.prometheus = {
enable = true; enable = true;
listenAddress = "127.0.0.1"; listenAddress = "127.0.0.1";
port = 9001; port = 9001;
ruleFiles = [ rules/synapse-v2.rules ]; ruleFiles = [ rules/synapse-v2.rules ];
}; };
fileSystems."/var/lib/prometheus2" = {
device = stateDir;
options = [ "bind" ];
};
} }

View File

@ -0,0 +1,16 @@
{ ... }:
{
services.prometheus.scrapeConfigs = [{
job_name = "gitea";
scrape_interval = "60s";
scheme = "https";
static_configs = [
{
targets = [
"git.pvv.ntnu.no:443"
];
}
];
}];
}

View File

@ -0,0 +1,54 @@
{ config, ... }: let
cfg = config.services.prometheus;
in {
services.prometheus.scrapeConfigs = [{
job_name = "base_info";
static_configs = [
{ labels.hostname = "ildkule";
targets = [
"ildkule.pvv.ntnu.no:${toString cfg.exporters.node.port}"
"ildkule.pvv.ntnu.no:${toString cfg.exporters.systemd.port}"
];
}
{ labels.hostname = "bekkalokk";
targets = [
"bekkalokk.pvv.ntnu.no:9100"
"bekkalokk.pvv.ntnu.no:9101"
];
}
{ labels.hostname = "bicep";
targets = [
"bicep.pvv.ntnu.no:9100"
"bicep.pvv.ntnu.no:9101"
];
}
{ labels.hostname = "brzeczyszczykiewicz";
targets = [
"brzeczyszczykiewicz.pvv.ntnu.no:9100"
"brzeczyszczykiewicz.pvv.ntnu.no:9101"
];
}
{ labels.hostname = "georg";
targets = [
"georg.pvv.ntnu.no:9100"
"georg.pvv.ntnu.no:9101"
];
}
{ labels.hostname = "hildring";
targets = [
"hildring.pvv.ntnu.no:9100"
];
}
{ labels.hostname = "isvegg";
targets = [
"isvegg.pvv.ntnu.no:9100"
];
}
{ labels.hostname = "microbel";
targets = [
"microbel.pvv.ntnu.no:9100"
];
}
];
}];
}

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