Compare commits

...

254 Commits

Author SHA1 Message Date
850d0b0ec5
bekkalokk/gitea-web: fix SSH access
All checks were successful
Eval nix flake / evals (push) Successful in 13m28s
2024-12-10 21:05:06 +01:00
02792fc20e
bekkalokk/gitea: fix api pagination for web secret provider
All checks were successful
Eval nix flake / evals (push) Successful in 4m14s
2024-12-10 19:35:10 +01:00
40dd069a52 ustetind/gitea-runners: fix podman dns
All checks were successful
Eval nix flake / evals (push) Successful in 4m25s
2024-12-09 23:25:54 +01:00
04a838fc62
flake.nix: nixlib -> lib
Some checks failed
Eval nix flake / evals (push) Has been cancelled
2024-12-09 22:33:39 +01:00
1f85208587
hosts/ustetind: set up gitea-runners 2024-12-09 22:24:54 +01:00
c10c6d5a09 hosts/ustetind: init 2024-12-09 21:31:30 +01:00
6301688c95
common/smartd: only run on non-virtualized hardware
It's still part of the simulation tho
2024-12-09 21:03:50 +01:00
0ed0a3a504
flake.nix: make outputs.inputs buildable 2024-12-08 00:29:59 +01:00
5242d99260
bekkalokk/gitea: add gpg signing key 2024-11-24 03:23:54 +01:00
c60597dc5a Merge pull request 'Let smartd send mail notification' (!92) from add-mail-to-smartd into main
Reviewed-on: Drift/pvv-nixos-config#92
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>

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

Reviewed-on: Drift/pvv-nixos-config#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
2d52ebce52 Ildkule: hardware-config: use UUIDs 2024-11-09 21:42:44 +01:00
464576e856
flake.lock: bump greg-ng 2024-11-09 19:43:07 +01:00
df35715978 Merge pull request 'Add alfhj.nix' (!89) from newusersconfig into main
Reviewed-on: Drift/pvv-nixos-config#89
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-11-09 19:40:03 +01:00
165ff56948 Add alfhj.nix 2024-11-09 19:35:19 +01:00
11f6ef0572 Ildkule: Move monitoring state directories to data volume 2024-11-09 15:21:12 +01:00
815f48c30d
flake.lock: bump greg-ng 2024-10-22 19:50:29 +02:00
4985bac3ba
flake.lock: bump greg-ng 2024-10-20 23:18:35 +02:00
9e41c3374d Merge pull request 'bekkalokk/nginx: host .well-known' (!79) from move-well-known-to-bekkalokk into main
Reviewed-on: Drift/pvv-nixos-config#79
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-10-20 01:35:22 +02:00
f39fee4213
bekkalokk/nginx: host .well-known 2024-10-20 01:34:41 +02:00
4c77c9fc67 Merge pull request 'greg-ng 🎉' (!86) from greg-ng-working-branch into main
Reviewed-on: Drift/pvv-nixos-config#86
Reviewed-by: Felix Albrigtsen <felixalb@pvv.ntnu.no>
2024-10-20 01:30:26 +02:00
7938e8135f
flake.lock: bump 2024-10-19 23:31:29 +02:00
cbc3490882
modules/grzegorz: use greg-ng 2024-10-19 23:31:28 +02:00
47ed79986c bicep/matrix: use sops templates for appservice registrations 2024-10-14 15:46:58 +02:00
5aed665cc8 flake update 2024-10-14 00:24:29 +02:00
2c86a2d812 bicep/matrix/hookshot: More configuration 2024-10-14 00:13:15 +02:00
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
f5c16f46f1 Merge pull request 'disable-postgres-on-bekkalokk' (!85) from disable-postgres-on-bekkalokk into main
Reviewed-on: Drift/pvv-nixos-config#85
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-10-13 02:34:45 +02:00
aa71d497f1
bekkalokk/roundcube: add postgres password 2024-10-12 23:57:27 +02:00
c56d157c3f add registration secret 2024-10-12 23:49:10 +02:00
4fbd823be6 bekkalokk/roundcube: add database.host 2024-10-12 22:53:42 +02:00
6c9e651e59 bekkalokk/gitea: Add important emoji reactions 2024-10-12 22:42:59 +02:00
f56e73548c base: openssh fix 2024-10-12 22:32:18 +02:00
c62ea129ed Merge pull request 'base openssh added sleipner ssh keys' (!83) from sleipner-authorised-keys into main
Reviewed-on: Drift/pvv-nixos-config#83
2024-10-12 21:48:08 +02:00
4b41ddcf5d base: openssh added sleipner ssh keys 2024-10-12 21:47:31 +02:00
abec66b287 users/danio: add to wheel 2024-10-08 14:08:17 +02:00
aa884353c7 Merge pull request 'Add ipv6 gateway' (!82) from ipv6-fix into main
Reviewed-on: Drift/pvv-nixos-config#82
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-09-28 21:44:55 +02:00
2147b56864 Add ipv6 gateway 2024-09-28 21:35:57 +02:00
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
cd23e35aac bicep/matrix: update module and remove deprecated options 2024-09-27 06:38:12 +02:00
06668cda79 Merge pull request 'flake.lock: Update' (!81) from sounding into main
Reviewed-on: Drift/pvv-nixos-config#81
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-09-21 22:19:36 +02:00
2861f939b7 Merge pull request 'auto-upgrade: store flake input refs' (!80) from retain-flake-inputs into main
Reviewed-on: Drift/pvv-nixos-config#80
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-09-21 22:19:18 +02:00
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
4913b22ab9 auto-upgrade: store flake input refs 2024-09-16 02:51:20 +02:00
4e81647fb6 auto-upgrade: --update-input -> --override-input 2024-09-15 19:14:03 +02:00
5a76b62700 Merge pull request 'add gitea metrics' (!78) from gitea-metric into main
Reviewed-on: Drift/pvv-nixos-config#78
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-09-14 20:33:28 +02:00
0f77a42e34 Grafana: Add Gitea Dashbaord [sic] 2024-09-14 20:28:35 +02:00
c64d28fc26 Prometheus: Monitor gitea metrics 2024-09-14 20:21:12 +02:00
179d0743ce gitea: export metric issue #101 2024-09-14 19:26:25 +02:00
47fa3759c3 buskerud: remove
This is now a proxmox machine :grr:
2024-09-05 18:00:42 +02:00
3a37fefd4d fixup! Merge pull request 'Fix Ildkule/Openstack networking' (!75) from fix-openstack-networking into main 2024-09-05 14:24:40 +02:00
47d7b88a05 ildkule/prometheus: consolidate scrape jobs and label with hostname for base info 2024-09-05 14:14:28 +02:00
78456063ba Merge pull request 'Fix Ildkule/Openstack networking' (!75) from fix-openstack-networking into main
Reviewed-on: Drift/pvv-nixos-config#75
2024-09-05 01:58:50 +02:00
ca287b95c9 Ildkule/openstack: fix networking
Removes systemd-networkd, and configures proper ipv4 and ipv6 in
openstack.
2024-09-05 00:24:22 +02:00
7e95b77e15 grzegorz: follow stable nix channel
It broke because sanic
2024-09-03 13:28:13 +02:00
669733309b ildkule: get systemd stats from more machines 2024-09-03 13:10:36 +02:00
4ed12573ff ildkule: fix system activation by disabling smartd 2024-09-03 13:07:58 +02:00
8418cc016c fix biceps systemd units failing on activation 2024-09-03 13:00:12 +02:00
b4c602e31c metrics: install systemd exporter 2024-09-02 23:12:24 +02:00
3a0b8e270d bekkalokk/idp: Disallow bots 2024-09-02 23:11:44 +02:00
9505223dc9 justfile: fix flake input updating 2024-09-02 19:33:15 +02:00
201784fa21 bluemap on bekkalokk 💀 2024-09-02 15:11:32 +02:00
ccefcb01fa flake.lock update 2024-09-02 14:12:39 +02:00
f7e2c74f89 base: enable rebuilding nixos-config without updating the channels used 2024-09-01 22:10:58 +02:00
161265d346 Bekkalokk/Nettsiden: deploy #78 2024-09-01 20:13:56 +02:00
f85d18769f
common: clean /tmp on boot by default 2024-09-01 03:29:46 +02:00
b47a626427
common/openssh: socket activate 2024-09-01 03:21:13 +02:00
4d65b9fd1d
common/sudo: misc config 2024-09-01 03:17:15 +02:00
f3e094520e
common/postfix: init 2024-09-01 03:13:18 +02:00
69f98933a4
common/smartd: add smartctl to environment packages 2024-09-01 01:55:38 +02:00
bf2959c68d
common/nix: flesh out 2024-09-01 01:44:59 +02:00
17f0268d12
common/irqbalance: init 2024-09-01 01:39:35 +02:00
ebce0eb67a
common/smartd: init 2024-09-01 01:23:15 +02:00
b48230e811
bekkalokk/btrfs: scrubbalubba dubdub 2024-09-01 01:04:28 +02:00
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
8610a59f35
base.nix: split into multiple files 2024-08-31 22:28:17 +02:00
bd42412b94 bekkalokk/gitea/import-users: refactor + add members to groups 2024-08-27 22:07:29 +02:00
ef3b146b58 bekkalokk/gitea: don't autowatch all members to all projects 2024-08-27 09:26:00 +02:00
bb4662b345 modules/snakeoil-certs: fix lmao 2024-08-26 20:43:34 +02:00
5b1c04e4b8 bicep/postgres: use snakeoil certs 2024-08-26 20:43:34 +02:00
3fa7f67027 bekkalokk/gitea-web: host pages 2024-08-26 20:36:03 +02:00
b0f555667c bekkalokk/gitea: set up gitea-web sync units 2024-08-26 20:36:03 +02:00
ef418bf125
base/logrotate: systemd hardening + more 2024-08-22 23:00:45 +02:00
945d53cdb4
bekkalokk/vaultwarden: systemd hardening 2024-08-22 22:59:32 +02:00
cf3b62e01e
bekkalokk/phpfpm-*: systemd hardening 2024-08-22 22:58:48 +02:00
c12a47cee0
flake.nix: bump calendar bot 2024-08-17 01:19:46 +02:00
b9ef27565f
Bump calendar-bot 2024-08-16 09:16:26 +02:00
f5c99b58c8
bicep/calendar-bot: reactivate 2024-08-15 23:22:50 +02:00
c780f7954c Merge pull request 'justfile: add recipe run-vm' (!64) from run-vm into main
Reviewed-on: Drift/pvv-nixos-config#64
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-15 21:14:29 +02:00
d64d8edd68 bekkalokk/gitea: add some extra tabs 2024-08-14 17:36:19 +02:00
4de7bd09bd Merge pull request 'enable thermald on physical machines' (!61) from thermald into main
Reviewed-on: Drift/pvv-nixos-config#61
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-14 17:31:44 +02:00
0f5c48902b Merge pull request 'users: disable password login for users in @wheel' (!62) from fix-deploy into main
Reviewed-on: Drift/pvv-nixos-config#62
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-14 17:31:08 +02:00
2ff69dfec6 justfile: add recipe run-vm 2024-08-14 17:25:55 +02:00
36a8868f94 users: disable password login for users in @wheel 2024-08-11 03:42:26 +02:00
fe3e5d6a3d enable thermald on physical machines 2024-08-10 23:55:29 +02:00
2f3bcaf124 shell.nix: fix typo 2024-08-10 18:15:31 +02:00
c6684d5146 Merge pull request 'justfile: init' (!56) from justfile into main
Reviewed-on: Drift/pvv-nixos-config#56
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-07 12:22:04 +02:00
f6cb934ffb Merge pull request 'flake.nix: simplify allMachines' (!59) from attrnames into main
Reviewed-on: Drift/pvv-nixos-config#59
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-08-04 23:44:54 +02:00
9625258942 Merge pull request 'flake.nix: export snakeoil-certs and snappymail nixos modules' (!58) from export-modules into main
Reviewed-on: Drift/pvv-nixos-config#58
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-08-04 23:44:19 +02:00
34637e383a justfile: add update-inputs recipe 2024-08-04 17:19:40 +02:00
0bfa6ac329 flake.nix: export inputs 2024-08-04 17:19:33 +02:00
2c3261de74 flake.nix: simplify allMachines 2024-08-04 17:11:21 +02:00
c2e6f294ea flake.nix: export snakeoil-certs and snappymail nixos modules 2024-08-04 16:48:21 +02:00
41e94695f0 Merge pull request 'editorconfig' (!55) from editorconfig into main
Reviewed-on: Drift/pvv-nixos-config#55
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 16:20:23 +02:00
c6b4ea9929 add .git-blame-ignore-revs 2024-08-04 04:39:17 +02:00
9dbf5d56f5 fix whitespacing issues 2024-08-04 04:37:23 +02:00
64b5bb548b editorconfig: init 2024-08-04 04:35:25 +02:00
261c8e0811 Merge pull request 'Run statix' (!54) from statix into main
Reviewed-on: Drift/pvv-nixos-config#54
Reviewed-by: Daniel Lovbrotte Olsen <danio@pvv.ntnu.no>
2024-08-04 04:26:23 +02:00
4476cdcbbc justfile: init 2024-08-04 03:28:17 +02:00
f475243b94 Merge pull request 'sops: add pederbs' (!51) from pederbs-sops into main
Reviewed-on: Drift/pvv-nixos-config#51
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:56:31 +02:00
f382109b4a Merge pull request 'users: add pederbs' (!49) from user-pederbs into main
Reviewed-on: Drift/pvv-nixos-config#49
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:46:59 +02:00
e5e3100639 Merge pull request 'direnv: yes' (!50) from direnv into main
Reviewed-on: Drift/pvv-nixos-config#50
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:46:18 +02:00
5853e42c1b Merge pull request 'SimpleSamlPHP: use concatLines' (!53) from concatlines into main
Reviewed-on: Drift/pvv-nixos-config#53
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:46:01 +02:00
d59aa08986 Merge pull request 'shell.nix: remove cc' (!52) from shell-cc into main
Reviewed-on: Drift/pvv-nixos-config#52
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-08-04 02:44:52 +02:00
95a5603f27
secrets: run sops updatekeys on everything 2024-08-04 02:04:29 +02:00
1714681532 statix fix 2024-08-04 01:46:00 +02:00
314c7960d1 statix: init 2024-08-04 01:45:20 +02:00
43d353190c SimpleSamlPHP: use concatLines 2024-08-04 01:42:32 +02:00
eb74d011db shell.nix: remove cc 2024-08-04 01:30:02 +02:00
b52de48455 sops: add pederbs 2024-08-04 01:24:54 +02:00
510f385f4a direnv: yes 2024-08-04 01:19:22 +02:00
e25ba96096 users: add pederbs 2024-08-04 00:58:11 +02:00
53040bada1
flake.lock: update pvv-nettsiden 2024-08-04 00:09:32 +02:00
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: Drift/pvv-nixos-config#47
2024-07-31 11:23:00 +02:00
c7797bdd04 Merge pull request 'SimpleSAMLPHP/MediaWiki: Update deprecated --replace' (!48) from fix-replace-warn into main
Reviewed-on: Drift/pvv-nixos-config#48
Reviewed-by: Oystein Kristoffer Tveit <oysteikt@pvv.ntnu.no>
2024-07-28 23:30:44 +02:00
615b5fc1f1 SimpleSAMLPHP/MediaWiki: Update deprecated --replace 2024-07-28 23:28:33 +02:00
a0a837e26d Merge pull request 'bekkalokk/gitea: direct non-logged-in users to the explore tab' (!46) from gitea-explore into main
Reviewed-on: Drift/pvv-nixos-config#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
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
78caceddce flake: remove nettsiden from output function scope
This is referred to by inputs anyways
2024-07-18 16:24:42 +02:00
868764e0cd bekkalokk/mediawiki: misc configuration 2024-07-10 19:04:55 +02:00
7c3ff2068d bekkalokk/mediawiki: add some more extensions 2024-07-10 19:04:36 +02:00
9d3f1381bf packages/mediawiki-extensions: refactor 2024-07-10 18:59:16 +02:00
f3a29429aa bekkalokk/gitea: set default email notification preference to 'onmention' 2024-07-10 00:18:01 +02:00
1591fdb7cc bekkalokk/mediawiki: re-enable DeleteBatch extension 2024-07-08 19:56:43 +02:00
ed28ba28f3 bekkalokk/mediawiki: leave togglable debug flags for future use 2024-07-08 19:55:52 +02:00
52b46667b1 packages/mediawiki-extensions: use fetchgit 2024-07-08 19:54:42 +02:00
d0f63b2fc8 packages/mediawiki-extensions: bump all 2024-07-08 16:55:01 +02:00
0301691b1c
gitea: enable notification mails 2024-07-04 20:41:46 +02:00
946555e408
gitea: add subject prefix to mail 2024-07-04 20:36:44 +02:00
e02062417a
gitea: move state back to /var/lib 2024-07-04 20:31:51 +02:00
b2806d78af
gitea: enable lfs 2024-07-04 20:30:55 +02:00
de2c7ea6f1
gitea: install custom images to correct dir 2024-07-04 20:29:50 +02:00
106081c967 Merge pull request 'all: Update to nixos-24.05' (!43) from 24.05-for-real into main
Reviewed-on: Drift/pvv-nixos-config#43
2024-06-30 01:55:41 +02:00
ca2deed668 WIP: all: Update to nixos-24.05 2024-06-30 01:55:25 +02:00
bb2f7899db Merge pull request 'bekkalokk/gitea: set default licenses and repo units' (!44) from gitea-set-misc-repo-settings into main
Reviewed-on: Drift/pvv-nixos-config#44
2024-06-29 23:16:17 +02:00
c2b35a7ae4
bekkalokk/gitea: set default licenses and repo units 2024-06-29 23:14:41 +02:00
c88c3f87e0 buskerud: add libvirtd 2024-06-22 17:36:30 +02:00
c5bad75edc bekkalokk/nettsiden: Update nettsiden to disable recurring events 2024-06-19 22:15:36 +02:00
71479d5ca0 quickfix: bekkalokk/mediawiki: remove DeleteBatch 2024-05-27 11:02:35 +02:00
cf01792269 bekkalokk/vaultarden: Add kTLS 2024-05-26 10:50:29 +02:00
afae0da0b6 Merge pull request 'bekkalokk: add vaultwarden' (!40) from bekkalokk-vaultwarden into main
Reviewed-on: Drift/pvv-nixos-config#40
2024-05-26 04:21:28 +02:00
35d745b156 bekkalokk: add vaultwarden 2024-05-26 04:19:17 +02:00
218ee776c7 Merge pull request 'packages/mediawiki-extensions: use stable url' (!35) from fix-mediawiki-extensions-url into main
Reviewed-on: Drift/pvv-nixos-config#35
2024-05-26 02:45:04 +02:00
3a972f03f7
flake: move mediawiki-extensions back to packages 2024-05-26 02:42:31 +02:00
96024efa28
flake: move mediawiki-extensions to legacyPackages 2024-05-26 02:42:31 +02:00
af54cc2df4
packages/mediawiki/pluggable-auth: fix typo 2024-05-26 02:42:31 +02:00
6f6721ce07
packages/mediawiki-extensions: use stable url 2024-05-26 02:42:28 +02:00
1c35da0295 Merge pull request 'bekkalokk: add snappymail' (!39) from bekkalokk-snappymail into main
Reviewed-on: Drift/pvv-nixos-config#39
2024-05-26 01:52:17 +02:00
5fb1b805a8 bekkalokk: add snappymail 2024-05-26 01:07:27 +02:00
a38a12c429
flake.lock: update pvv-nettsiden 2024-05-19 22:27:59 +02:00
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: Drift/pvv-nixos-config#34
2024-05-14 05:27:44 +02:00
c267820426 overlays/nginx-test: drop 2024-05-13 07:04:00 +02:00
a57b5f07f9 Merge pull request 'gitea: setup mail' (!38) from gitea-setup-mail into main
Reviewed-on: Drift/pvv-nixos-config#38
2024-05-12 02:27:37 +02:00
bcf2ceed32
gitea: setup mail 2024-05-12 02:26:13 +02:00
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
45eea1a791 update flake.lock 2024-05-12 02:22:12 +02:00
200224d2c1 Merge pull request 'bekkalokk: misc gitea cleanup' (!33) from misc-gitea-cleanup into main
Reviewed-on: Drift/pvv-nixos-config#33
2024-05-12 02:12:55 +02:00
dcf29b76b8 bicep/matrix: allow global address of new ildkule to access metrics
All checks were successful
Eval nix flake / evals (push) Successful in 1h30m46s
2024-04-24 03:03:53 +02:00
55e8f01d1d Upgrade ildkule (!36)
Some checks failed
Eval nix flake / evals (push) Failing after 3h12m29s
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: Drift/pvv-nixos-config#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
b7b1c73bfa
bekkalokk/gitea: use systemd unit for gitea customization
Some checks failed
Eval nix flake / evals (pull_request) Failing after 47s
Eval nix flake / evals (push) Failing after 14m41s
2024-04-16 01:02:21 +02:00
19d5ddc688 Merge pull request 'bekkalokk: remove keycloak' (!30) from bekkalokk-remove-keycloak into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m49s
Reviewed-on: Drift/pvv-nixos-config#30
2024-04-15 00:00:17 +02:00
6851879a03
bekkalokk: remove keycloak
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m39s
Eval nix flake / evals (push) Failing after 1m41s
2024-04-14 23:59:46 +02:00
70603145cf
bekkalokk/website: add sp metadata for all domains
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m49s
Eval nix flake / evals (push) Failing after 41s
2024-04-14 17:06:01 +02:00
1e4195ea9d bekkalokk: pvv-nettsiden-gallery: Improve thumbnail generation
Some checks failed
Eval nix flake / evals (push) Failing after 1m46s
2024-04-14 02:04:45 +02:00
ee335e3712 bicep/synapse: fix registering users via smtp
Some checks failed
Eval nix flake / evals (push) Failing after 2m0s
2024-04-14 01:52:17 +02:00
ffbf855f24 update flake for grzegorz
Some checks failed
Eval nix flake / evals (push) Failing after 1m52s
2024-04-12 02:35:49 +02:00
28e7a63d33 update flake lock and remove non-derivations from flake ouput
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
2024-04-12 00:42:29 +02:00
01f0e63a49 use getExe' to silence errors 2024-04-12 00:41:57 +02:00
ae4ace9fa2 Merge pull request 'treewide: run nginx -t on all nginx config files' (!32) from test-nginx-overlay into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m46s
Reviewed-on: Drift/pvv-nixos-config#32
2024-04-11 23:39:42 +02:00
8c72088d9c dynamically get configured acme certs for nginx test
Some checks failed
Eval nix flake / evals (push) Failing after 1m44s
Eval nix flake / evals (pull_request) Failing after 1m51s
2024-04-11 23:29:05 +02:00
0056029da7 treewide: bubblewrap nginx test 2024-04-11 23:28:54 +02:00
9b4fbd847f treewide: run nginx -t on all nginx config files 2024-04-11 23:28:54 +02:00
5bed292a01
bekkalokk/gitea: move user import stuff to separate nix file 2024-04-11 21:47:44 +02:00
36b7087a3f
base.nix: hotfix for hotfix for nginx on bicep (3352e48f)
Some checks failed
Eval nix flake / evals (push) Failing after 1m49s
Turns out the settings were in biceps local nginx config
2024-04-11 20:41:02 +02:00
1919da7a1c bicep/matrix: remove SAML authentication
Some checks failed
Eval nix flake / evals (push) Failing after 1m50s
2024-04-11 19:55:10 +02:00
0950fedf98 bekkalokk/website: fix some nginx location directives
Some checks failed
Eval nix flake / evals (push) Failing after 1m50s
2024-04-11 13:21:11 +02:00
614c2d624c
bekkalokk/webmail: add redirects for old webmail locations
Some checks failed
Eval nix flake / evals (push) Failing after 1m45s
2024-04-11 10:47:13 +02:00
3352e48f47
base.nix: hotfix for nginx on bicep
Some checks failed
Eval nix flake / evals (push) Failing after 1m51s
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
db211c2304 bekkalokk/website: don't try to listen for ntnu.org
Some checks failed
Eval nix flake / evals (push) Failing after 1m48s
2024-04-11 05:31:33 +02:00
4f322ec0b1 Merge pull request 'finalize-www-migration' (!31) from finalize-www-migration into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m40s
Reviewed-on: Drift/pvv-nixos-config#31
2024-04-11 00:57:20 +02:00
79bf307ef2 bekkalokk: Reconfigure www ingress
Some checks failed
Eval nix flake / evals (push) Failing after 1m46s
Eval nix flake / evals (pull_request) Failing after 1m52s
2024-04-11 00:48:07 +02:00
4d50efc6db Finalize www/idp/webmail migration from spikkjeposche to bekkalokk
Some checks failed
Eval nix flake / evals (push) Failing after 1m48s
2024-04-10 23:31:04 +02:00
145a840a2c Merge pull request 'Setup pvv-nettsiden on www2.pvv.ntnu.no' (!27) from www2 into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
Reviewed-on: Drift/pvv-nixos-config#27
2024-04-10 23:05:37 +02:00
2bbc851e0e Point inputs/nettsiden to master after Projects/nettsiden#53
Some checks failed
Eval nix flake / evals (push) Failing after 1m48s
Eval nix flake / evals (pull_request) Failing after 1m48s
2024-04-10 23:04:20 +02:00
9577477460 bekkalokk/nettsiden: add secrets 2024-04-10 23:04:20 +02:00
fc19a8f1e1 bekkalokk: Automatically unpack pvv-nettsiden/gallery and generate thumbnails 2024-04-10 23:04:20 +02:00
8657e77514 bekkalokk: set up pvv-nettsiden 2024-04-10 23:04:18 +02:00
03c9638098 Merge pull request 'treewide: nginx optimizations' (!29) from treewide-nginx-optimizations into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
Reviewed-on: Drift/pvv-nixos-config#29
2024-04-10 22:54:39 +02:00
065992620e treewide: nginx optimizations
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
Eval nix flake / evals (pull_request) Failing after 1m54s
2024-04-10 22:06:44 +02:00
e22c7d5b4d added terminfo for foot to adriangl
Some checks failed
Eval nix flake / evals (push) Failing after 1m46s
2024-04-09 20:46:14 +02:00
4fcc1fd5e9 flake.lock: update nix-gitea-themes
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
2024-04-09 20:33:38 +02:00
05a1f049dc Merge pull request 'gitea: add theming module' (!28) from init-gitea-themes into main
Some checks failed
Eval nix flake / evals (push) Failing after 2m13s
Reviewed-on: Drift/pvv-nixos-config#28
2024-04-09 20:32:29 +02:00
fbbc54328b gitea: add theming module
Some checks failed
Eval nix flake / evals (push) Failing after 1m51s
Eval nix flake / evals (pull_request) Failing after 1m54s
2024-04-09 01:52:57 +02:00
d8e13ff67c Update users/adriangl.nix
Some checks failed
Eval nix flake / evals (push) Failing after 1m50s
2024-04-08 21:21:24 +02:00
42fd371c3b
mediawiki: restart phpfpm on updated secrets
Some checks failed
Eval nix flake / evals (push) Failing after 2m11s
2024-04-06 23:57:37 +02:00
f25a4e5c02 Merge pull request 'mediawiki: add VisualEditor' (#26) from mediawiki-add-visual-editor into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
Reviewed-on: Drift/pvv-nixos-config#26
2024-04-06 21:19:41 +02:00
6e1b06731f bekkalokk: add VisualEditor to mediawiki extensions
Some checks failed
Eval nix flake / evals (push) Failing after 1m53s
Eval nix flake / evals (pull_request) Failing after 1m42s
2024-04-06 21:09:01 +02:00
161ef284be packages: add mediawiki-extensions.VisualEditor 2024-04-06 21:08:32 +02:00
2cb7e06369
bekkalokk/mediawiki: fix path, upgrade security
Some checks failed
Eval nix flake / evals (push) Failing after 1m54s
2024-04-03 08:29:19 +02:00
a55c908fe7
bekkalokk/mediawiki: change domain from wiki2 to wiki
Some checks failed
Eval nix flake / evals (push) Failing after 1m48s
2024-04-02 19:54:28 +02:00
06bd93e5d1 Merge pull request 'bekkalokk: set up idp + mediawiki' (#25) from mediawiki-on-bekkalokk into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m56s
Reviewed-on: Drift/pvv-nixos-config#25
2024-04-02 00:00:24 +02:00
d531419f35 bekkalokk: init mediawiki
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m46s
Eval nix flake / evals (push) Failing after 1m53s
Co-authored-by: Jørn Åne <yorinad@pvv.ntnu.no>
2024-04-01 23:57:39 +02:00
806b18ede8 bekkalokk: init idp-simplesamlphp 2024-04-01 23:57:39 +02:00
c612975b60 base/nginx: 444 requests to nonexistent virtualhosts 2024-04-01 23:57:39 +02:00
9495682f57 bekkalokk: package mediawiki extensions outside of module 2024-04-01 00:39:12 +02:00
d39047b8cb packages: init simplesamlphp 2024-04-01 00:38:51 +02:00
266ce9ed08 bekkalokk: set up kerberos client 2024-04-01 00:38:49 +02:00
07c480d004 base: add ripgrep
Some checks failed
Eval nix flake / evals (push) Failing after 1m53s
2024-03-30 21:07:00 +01:00
64c7e3e365 flake.nix: fix usage of common nixos module/overlay list 2024-03-29 01:51:37 +01:00
fe4dd21acb add eirikwit to sops
Some checks failed
Eval nix flake / evals (push) Failing after 1m44s
2024-03-16 22:38:16 +01:00
0336744124 flake update: matrix module bug fix
Some checks failed
Eval nix flake / evals (push) Failing after 1m55s
2024-03-13 07:41:12 +01:00
b4d6e00622 Update flake.lock to get new matrix module
Some checks failed
Eval nix flake / evals (push) Failing after 1m51s
2024-03-13 06:33:43 +01:00
7c6d4d31c7 bicep/matrix/element: update room directories
Some checks failed
Eval nix flake / evals (push) Failing after 1m44s
2024-03-05 05:52:31 +01:00
9f46be1ca1 bicep/matrix: update element lab flags and room directoriy listings
Some checks failed
Eval nix flake / evals (push) Failing after 1m44s
2024-03-05 05:28:23 +01:00
545583cf04 bekkalokk/gitea: Do not change the user visibility
Some checks failed
Eval nix flake / evals (push) Failing after 1m55s
2024-03-03 00:29:24 +01:00
62b269637a bekkalokk/gitea: unset visibility when updating users
Some checks failed
Eval nix flake / evals (push) Failing after 1m50s
2024-02-12 11:24:14 +01:00
7fd9a1e646
started on bikkje container for new loginbox - work in progress
Some checks failed
Eval nix flake / evals (push) Failing after 1m47s
2024-01-07 01:21:11 +01:00
4ea90380ad bicep/matrix: use synapse package from stable
Some checks failed
Eval nix flake / evals (push) Failing after 1m52s
It's fixed now
2023-12-16 00:22:02 +01:00
bcd5292f78 update flake.lock
Some checks failed
Eval nix flake / evals (push) Failing after 1m46s
2023-12-13 20:02:09 +01:00
1ab1b3a84e Merge pull request 'Buskerud: Comment out openvpn-client' (#23) from buskerud-no-vpn into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m48s
Reviewed-on: Drift/pvv-nixos-config#23
2023-12-12 18:09:31 +01:00
80ef1ce4fa Buskerud: Remove OV-link, general cleanup
Some checks failed
Eval nix flake / evals (push) Failing after 1m43s
Eval nix flake / evals (pull_request) Failing after 1m42s
2023-12-12 15:27:20 +01:00
2b834eee14 Buskerud: Comment out openvpn-client
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m42s
Eval nix flake / evals (push) Failing after 1m40s
2023-12-12 11:39:33 +01:00
9ed2ca8883 Merge pull request 'Update users/jonmro.nix' (#21) from jonmro/pvv-nixos-config:main into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m50s
Reviewed-on: Drift/pvv-nixos-config#21
2023-12-10 05:46:20 +01:00
fe12e5441a Merge pull request '🎉 nixpkgs 23.11' (#20) from upgrade-to-nixpkgs-23-11 into main
Some checks failed
Eval nix flake / evals (push) Failing after 1m43s
Reviewed-on: Drift/pvv-nixos-config#20
2023-12-10 05:43:01 +01:00
2b305678df update flake.lock
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m43s
Eval nix flake / evals (push) Failing after 1m48s
2023-12-10 05:41:45 +01:00
dd8b677a79 buskerud: bootloader - 3.3TB, OS - 256GB 👍
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m49s
Eval nix flake / evals (push) Failing after 1m57s
2023-12-10 05:27:58 +01:00
eabd8df3d8 bicep/matrix: use package with fixed pythonEnv
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m46s
Eval nix flake / evals (push) Failing after 1m52s
2023-12-10 04:32:26 +01:00
8a0ebe761e Add user eirikwit
Some checks failed
Eval nix flake / evals (pull_request) Failing after 1m43s
Eval nix flake / evals (push) Failing after 1m48s
2023-12-10 02:00:18 +01:00
0c816068fe Update users/jonmro.nix
Some checks failed
Eval nix flake / evals (pull_request) Failing after 2m1s
Added "drift" "nix-builder-users"  groups
2023-12-10 00:25:04 +01:00
0b5e03471f
upgrade to nixpkgs 23.11
Some checks failed
Eval nix flake / evals (push) Failing after 3h8m33s
Eval nix flake / evals (pull_request) Failing after 3h5m17s
2023-12-05 00:36:09 +01:00
d8031ecca1 Merge pull request 'replace-knakelibrak-nginx-reverse-proxy' (#18) from replace-knakelibrak-nginx-reverse-proxy into main
All checks were successful
Eval nix flake / evals (push) Successful in 4m2s
Reviewed-on: Drift/pvv-nixos-config#18
2023-12-03 07:01:13 +01:00
28e3f5672c pin matrix-synapse-next module to last one compatible with 23.05
All checks were successful
Eval nix flake / evals (push) Successful in 3m53s
When we upgrade we can go back to tracking master
2023-12-02 10:05:27 +01:00
8ced91a285
hosts/buskerud: init
All checks were successful
Eval nix flake / evals (push) Successful in 4m43s
Co-authored-by: Felix Albrigtsen <felix@albrigtsen.it>
2023-11-30 19:42:05 +01:00
2c42b120a6 Merge branch 'extend_smtp'
All checks were successful
Eval nix flake / evals (push) Successful in 3m41s
2023-11-28 08:39:15 +01:00
27ba3f7a7f bicep/matrix: serve server well-known
All checks were successful
Eval nix flake / evals (push) Successful in 3m24s
2023-11-28 08:36:56 +01:00
c1c58122ea bicep/matrix: Improve flexibility of username login
All checks were successful
Eval nix flake / evals (push) Successful in 4m34s
It should be possible to log in  with @username:pvv.ntnu.no now
That way client well-known in third party clients will work

it might also fix the weird logout of session issues in element
2023-11-28 05:14:04 +01:00
7ac960c5ff
users/oysteikt: add to nix-builder-users
All checks were successful
Eval nix flake / evals (push) Successful in 3m15s
2023-11-26 07:22:12 +01:00
134 changed files with 10533 additions and 1238 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*
/configuration.nix
/.direnv/
*.qcow2

View File

@ -3,12 +3,17 @@ keys:
- &user_danio age17tagmpwqjk3mdy45rfesrfey6h863x8wfq38wh33tkrlrywxducs0k6tpq
- &user_felixalb age1mrnldl334l2nszuta6ywvewng0fswv2dz9l5g4qcwe3nj4yxf92qjskdx6
- &user_oysteikt F7D37890228A907440E1FD4846B9228E814A2AAC
- &user_eirikwit age1ju7rd26llahz3g8tz7cy5ld52swj8gsmg0flrmrxngc0nj0avq3ssh0sn5
- &user_pederbs_sopp age1hmpdk4h69wxpwqk9tkud39f66hprhehxtzhgw97r6dvr7v0mx5jscsuhkn
- &user_pederbs_nord age1wrssr4z4g6vl3fd3qme5cewchmmhm0j2xe6wf2meu4r6ycn37anse98mfs
- &user_pederbs_bjarte age1zhxul786an743u0fascv4wtc5xduu7qfy803lfs539yzhgmlq5ds2lznt5
# Hosts
- &host_jokum age1gp8ye4g2mmw3may5xg0zsy7mm04glfz3788mmdx9cvcsdxs9hg0s0cc9kt
- &host_ildkule age1hn45n46ypyrvypv0mwfnpt9ddrlmw34dwlpf33n8v67jexr3lucq6ahc9x
- &host_ildkule age1x28hmzvuv6f2n66c0jtqcca3h9rput8d7j5uek6jcpx8n9egd52sqpejq0
- &host_bekkalokk age12nj59tguy9wg882updc2vjdusx5srnxmjyfaqve4zx6jnnsaw3qsyjq6zd
- &host_bicep age1sl43gc9cw939z5tgha2lpwf0xxxgcnlw7w4xem4sqgmt2pt264vq0dmwx2
- &host_ustetind age1hffjafs4slznksefmtqrlj7rdaqgzqncn4un938rhr053237ry8s3rs0v8
creation_rules:
# Global secrets
@ -18,17 +23,24 @@ creation_rules:
- *host_jokum
- *user_danio
- *user_felixalb
- *user_eirikwit
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp:
- *user_oysteikt
# Host specific secrets
- path_regex: secrets/bekkalokk/[^/]+\.yaml$
key_groups:
- age:
- *host_bekkalokk
- *user_danio
- *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp:
- *user_oysteikt
@ -38,6 +50,9 @@ creation_rules:
- *host_jokum
- *user_danio
- *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp:
- *user_oysteikt
@ -47,14 +62,32 @@ creation_rules:
- *host_ildkule
- *user_danio
- *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp:
- *user_oysteikt
- path_regex: secrets/bicep/[^/]+\.yaml$
key_groups:
- age:
- *host_bicep
- *user_danio
- *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp:
- *user_oysteikt
- path_regex: secrets/ustetind/[^/]+\.yaml$
key_groups:
- age:
- *host_ustetind
- *user_danio
- *user_felixalb
- *user_pederbs_sopp
- *user_pederbs_nord
- *user_pederbs_bjarte
pgp:
- *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.
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.
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
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 = [ ];
};
}

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

@ -0,0 +1,20 @@
{ 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
]);
systemd.services.smartd.unitConfig.ConditionVirtualization = "no";
}

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;
}

200
flake.lock generated
View File

@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1699099781,
"narHash": "sha256-2WAs839yL6xmIPBLNVwbft46BDh0/RAjq1bAKNRqeR4=",
"lastModified": 1731746438,
"narHash": "sha256-f3SSp1axoOk0NAI7oFdRzbxG2XPBSIXC+/DaAXnvS1A=",
"owner": "nix-community",
"repo": "disko",
"rev": "548962c50b8afad7b8c820c1d6e21dc8394d6e65",
"rev": "cb64993826fa7a477490be6ccb38ba1fa1e18fa8",
"type": "github"
},
"original": {
@ -20,24 +20,25 @@
"type": "github"
}
},
"grzegorz": {
"greg-ng": {
"inputs": {
"nixpkgs": [
"nixpkgs-unstable"
]
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1696346665,
"narHash": "sha256-J6Tf6a/zhFZ8SereluHLrvgPsIVm2CGHHA8wrbhZB3Y=",
"owner": "Programvareverkstedet",
"repo": "grzegorz",
"rev": "9b9c3ac7d408ac7c6d67544b201e6b169afacb03",
"type": "github"
"lastModified": 1730249639,
"narHash": "sha256-G3URSlqCcb+GIvGyki+HHrDM5ZanX/dP9BtppD/SdfI=",
"ref": "refs/heads/main",
"rev": "80e0447bcb79adad4f459ada5610f3eae987b4e3",
"revCount": 34,
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/greg-ng.git"
},
"original": {
"owner": "Programvareverkstedet",
"repo": "grzegorz",
"type": "github"
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/greg-ng.git"
}
},
"grzegorz-clients": {
@ -47,96 +48,121 @@
]
},
"locked": {
"lastModified": 1693864994,
"narHash": "sha256-oLDiWdCKDtEfeGzfAuDTq+n9VWp6JCo67PEESEZ3y8E=",
"owner": "Programvareverkstedet",
"repo": "grzegorz-clients",
"rev": "a38a0b0fb31ad0ad78a91458cb2c7f77f686468f",
"type": "github"
"lastModified": 1726861934,
"narHash": "sha256-lOzPDwktd+pwszUTbpUdQg6iCzInS11fHLfkjmnvJrM=",
"ref": "refs/heads/master",
"rev": "546d921ec46735dbf876e36f4af8df1064d09432",
"revCount": 78,
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/grzegorz-clients.git"
},
"original": {
"owner": "Programvareverkstedet",
"repo": "grzegorz-clients",
"type": "github"
"type": "git",
"url": "https://git.pvv.ntnu.no/Projects/grzegorz-clients.git"
}
},
"matrix-next": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1697936579,
"narHash": "sha256-nMyepKnwoHMzu2OpXvG2ZhU081TV9ENmWCo0vWxs6AI=",
"lastModified": 1727410897,
"narHash": "sha256-tWsyxvf421ieWUJYgjV7m1eTdr2ZkO3vId7vmtvfFpQ=",
"owner": "dali99",
"repo": "nixos-matrix-modules",
"rev": "e09814657187c8ed1a5fe1646df6d8da1eb2dee9",
"rev": "ff787d410cba17882cd7b6e2e22cc88d4064193c",
"type": "github"
},
"original": {
"owner": "dali99",
"ref": "v0.6.1",
"repo": "nixos-matrix-modules",
"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": {
"locked": {
"lastModified": 1699110214,
"narHash": "sha256-L2TU4RgtiqF69W8Gacg2jEkEYJrW+Kp0Mp4plwQh5b8=",
"lastModified": 1731663789,
"narHash": "sha256-x07g4NcqGP6mQn6AISXJaks9sQYDjZmTMBlKIvajvyc=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "78f3a4ae19f0e99d5323dd2e3853916b8ee4afee",
"rev": "035d434d48f4375ac5d3a620954cf5fda7dd7c36",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-23.05-small",
"type": "indirect"
}
},
"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",
"owner": "NixOS",
"ref": "nixos-24.05-small",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1699110214,
"narHash": "sha256-L2TU4RgtiqF69W8Gacg2jEkEYJrW+Kp0Mp4plwQh5b8=",
"lastModified": 1730602179,
"narHash": "sha256-efgLzQAWSzJuCLiCaQUCDu4NudNlHdg2NzGLX5GYaEY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "78f3a4ae19f0e99d5323dd2e3853916b8ee4afee",
"rev": "3c2f1c4ca372622cb2f9de8016c9a0b1cbd0f37c",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "release-23.05",
"ref": "release-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1699128932,
"narHash": "sha256-4Hn/fpR/FRucpXQqMI0OSgxiu2ImowmR0dThAycPt/4=",
"lastModified": 1731745710,
"narHash": "sha256-SVeiClbgqL071JpAspOu0gCkPSAL51kSIRwo4C/pghA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0d2d729bf7091df906a78b69f90620f933ea963f",
"rev": "dfaa4cb76c2d450d8f396bb6b9f43cede3ade129",
"type": "github"
},
"original": {
"id": "nixpkgs",
"owner": "NixOS",
"ref": "nixos-unstable-small",
"type": "indirect"
"repo": "nixpkgs",
"type": "github"
}
},
"pvv-calendar-bot": {
@ -146,11 +172,11 @@
]
},
"locked": {
"lastModified": 1693136143,
"narHash": "sha256-amHprjftc3y/bg8yf4hITCLa+ez5HIi0yGfR7TU6UIc=",
"lastModified": 1723850344,
"narHash": "sha256-aT37O9l9eclWEnqxASVNBL1dKwDHZUOqdbA4VO9DJvw=",
"ref": "refs/heads/main",
"rev": "a32894b305f042d561500f5799226afd1faf5abb",
"revCount": 9,
"rev": "38b66677ab8c01aee10cd59e745af9ce3ea88092",
"revCount": 19,
"type": "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"
}
},
"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": {
"inputs": {
"disko": "disko",
"grzegorz": "grzegorz",
"greg-ng": "greg-ng",
"grzegorz-clients": "grzegorz-clients",
"matrix-next": "matrix-next",
"minecraft-data": "minecraft-data",
"nix-gitea-themes": "nix-gitea-themes",
"nixpkgs": "nixpkgs",
"nixpkgs-unstable": "nixpkgs-unstable",
"pvv-calendar-bot": "pvv-calendar-bot",
"pvv-nettsiden": "pvv-nettsiden",
"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": {
"inputs": {
"nixpkgs": [
@ -179,11 +249,11 @@
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1699153251,
"narHash": "sha256-CGx98mbAy9svKTa1dzlrVmkJwgGSXpAQUdMh7U0szts=",
"lastModified": 1731748189,
"narHash": "sha256-Zd/Uukvpcu26M6YGhpbsgqm6LUSLz+Q8mDZ5LOEGdiE=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "5bc2cde6e53241e7df0e8f5df5872223983efa72",
"rev": "d2bd7f433b28db6bc7ae03d5eca43564da0af054",
"type": "github"
},
"original": {

114
flake.nix
View File

@ -2,8 +2,8 @@
description = "PVV System flake";
inputs = {
nixpkgs.url = "nixpkgs/nixos-23.05-small";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable-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 = "github:NixOS/nixpkgs/nixos-unstable-small";
sops-nix.url = "github:Mic92/sops-nix";
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
@ -11,27 +11,36 @@
disko.url = "github:nix-community/disko";
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.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";
grzegorz.inputs.nixpkgs.follows = "nixpkgs-unstable";
grzegorz-clients.url = "github:Programvareverkstedet/grzegorz-clients";
nix-gitea-themes.url = "git+https://git.pvv.ntnu.no/oysteikt/nix-gitea-themes.git";
nix-gitea-themes.inputs.nixpkgs.follows = "nixpkgs";
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";
minecraft-data.url = "git+https://git.pvv.ntnu.no/Drift/minecraft-data.git";
};
outputs = { self, nixpkgs, nixpkgs-unstable, sops-nix, disko, ... }@inputs:
let
nixlib = nixpkgs.lib;
inherit (nixpkgs) lib;
systems = [
"x86_64-linux"
"aarch64-linux"
"aarch64-darwin"
];
forAllSystems = f: nixlib.genAttrs systems (system: f system);
allMachines = nixlib.mapAttrsToList (name: _: name) self.nixosConfigurations;
forAllSystems = f: lib.genAttrs systems f;
allMachines = builtins.attrNames self.nixosConfigurations;
importantMachines = [
"bekkalokk"
"bicep"
@ -40,31 +49,32 @@
"ildkule"
];
in {
inputs = lib.mapAttrs (_: src: src.outPath) inputs;
nixosConfigurations = let
nixosConfig = nixpkgs: name: config: nixpkgs.lib.nixosSystem (nixpkgs.lib.recursiveUpdate
unstablePkgs = nixpkgs-unstable.legacyPackages.x86_64-linux;
nixosConfig = nixpkgs: name: config: lib.nixosSystem (lib.recursiveUpdate
rec {
system = "x86_64-linux";
specialArgs = {
inherit nixpkgs-unstable inputs;
inherit unstablePkgs inputs;
values = import ./values.nix;
fp = path: ./${path};
};
modules = [
./hosts/${name}/configuration.nix
sops-nix.nixosModules.sops
];
] ++ config.modules or [];
pkgs = import nixpkgs {
inherit system;
overlays = [
(final: prev: {
mx-puppet-discord = prev.mx-puppet-discord.override { nodejs_14 = final.nodejs_18; };
})
inputs.pvv-calendar-bot.overlays.${system}.default
];
# Global overlays go here
] ++ config.overlays or [ ];
};
}
config
(removeAttrs config [ "modules" "overlays" ])
);
stableNixosConfig = nixosConfig nixpkgs;
@ -72,19 +82,31 @@
in {
bicep = stableNixosConfig "bicep" {
modules = [
./hosts/bicep/configuration.nix
sops-nix.nixosModules.sops
inputs.matrix-next.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" {
modules = [
./hosts/bob/configuration.nix
sops-nix.nixosModules.sops
disko.nixosModules.disko
{ disko.devices.disk.disk1.device = "/dev/vda"; }
];
@ -93,26 +115,37 @@
#ildkule-unstable = unstableNixosConfig "ildkule" { };
shark = stableNixosConfig "shark" { };
ustetind = stableNixosConfig "ustetind" {
modules = [
"${nixpkgs}/nixos/modules/virtualisation/lxc-container.nix"
];
};
brzeczyszczykiewicz = stableNixosConfig "brzeczyszczykiewicz" {
modules = [
./hosts/brzeczyszczykiewicz/configuration.nix
sops-nix.nixosModules.sops
inputs.grzegorz.nixosModules.grzegorz-kiosk
inputs.grzegorz-clients.nixosModules.grzegorz-webui
inputs.greg-ng.nixosModules.default
];
overlays = [
inputs.greg-ng.overlays.default
];
};
georg = stableNixosConfig "georg" {
modules = [
./hosts/georg/configuration.nix
sops-nix.nixosModules.sops
inputs.grzegorz.nixosModules.grzegorz-kiosk
inputs.grzegorz-clients.nixosModules.grzegorz-webui
inputs.greg-ng.nixosModules.default
];
overlays = [
inputs.greg-ng.overlays.default
];
};
};
nixosModules = {
snakeoil-certs = ./modules/snakeoil-certs.nix;
snappymail = ./modules/snappymail.nix;
};
devShells = forAllSystems (system: {
default = nixpkgs.legacyPackages.${system}.callPackage ./shell.nix { };
});
@ -123,10 +156,19 @@
in rec {
default = important-machines;
important-machines = pkgs.linkFarm "important-machines"
(nixlib.getAttrs importantMachines self.packages.x86_64-linux);
(lib.getAttrs importantMachines self.packages.x86_64-linux);
all-machines = pkgs.linkFarm "all-machines"
(nixlib.getAttrs allMachines self.packages.x86_64-linux);
} // nixlib.genAttrs allMachines
(lib.getAttrs allMachines self.packages.x86_64-linux);
simplesamlphp = pkgs.callPackage ./packages/simplesamlphp { };
} //
(lib.pipe null [
(_: pkgs.callPackage ./packages/mediawiki-extensions { })
(lib.flip builtins.removeAttrs ["override" "overrideDerivation"])
(lib.mapAttrs' (name: lib.nameValuePair "mediawiki-${name}"))
])
// lib.genAttrs allMachines
(machine: self.nixosConfigurations.${machine}.config.system.build.toplevel);
};
};

View File

@ -1,22 +1,25 @@
{ pkgs, values, ... }:
{ fp, pkgs, values, ... }:
{
imports = [
./hardware-configuration.nix
../../base.nix
../../misc/metrics-exporters.nix
(fp /base)
(fp /misc/metrics-exporters.nix)
#./services/keycloak.nix
# TODO: set up authentication for the following:
# ./services/website.nix
./services/nginx
./services/bluemap/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/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.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true;
@ -24,8 +27,6 @@
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
virtualisation.podman.enable = true;
networking.hostName = "bekkalokk";
systemd.network.networks."30-enp2s0" = values.defaultNetworkConfig // {
@ -33,6 +34,8 @@
address = with values.hosts.bekkalokk; [ (ipv4 + "/25") (ipv6 + "/64") ];
};
services.btrfs.autoScrub.enable = true;
# Do not change, even during upgrades.
# See https://search.nixos.org/options?show=system.stateVersion
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

@ -1,11 +1,13 @@
{ config, values, pkgs, ... }:
{ config, values, fp, pkgs, lib, ... }:
let
cfg = config.services.gitea;
domain = "git.pvv.ntnu.no";
sshPort = 2222;
in {
imports = [
./ci.nix
./gpg.nix
./import-users
./web-secret-provider
];
sops.secrets = {
@ -13,41 +15,119 @@ in {
owner = "gitea";
group = "gitea";
};
"gitea/passwd-ssh-key" = { };
"gitea/ssh-known-hosts" = { };
"gitea/import-user-env" = { };
"gitea/email-password" = {
owner = "gitea";
group = "gitea";
};
};
services.gitea = {
enable = true;
stateDir = "/data/gitea";
appName = "PVV Git";
database = {
type = "postgres";
host = "postgres.pvv.ntnu.no";
port = config.services.postgresql.port;
port = config.services.postgresql.settings.port;
passwordFile = config.sops.secrets."gitea/database".path;
createDatabase = false;
};
mailerPasswordFile = config.sops.secrets."gitea/email-password".path;
# https://docs.gitea.com/administration/config-cheat-sheet
settings = {
server = {
DOMAIN = domain;
ROOT_URL = "https://${domain}/";
PROTOCOL = "http+unix";
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;
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;
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 = {
DISABLE_GRAVATAR = true;
ENABLE_FEDERATED_AVATAR = false;
};
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";
};
};
@ -57,49 +137,54 @@ in {
services.nginx.virtualHosts."${domain}" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
recommendedProxySettings = true;
extraConfig = ''
client_max_body_size 512M;
'';
kTLS = true;
locations = {
"/" = {
proxyPass = "http://unix:${cfg.settings.server.HTTP_ADDR}";
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 ];
# Automatically import users
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;
};
};
# Extra customization
systemd.timers.gitea-import-users = {
requires = [ "gitea.service" ];
after = [ "gitea.service" ];
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "*-*-* 02:00:00";
Persistent = true;
Unit = "gitea-import-users.service";
};
};
services.gitea-themes.monokai = pkgs.gitea-theme-monokai;
system.activationScripts.linkGiteaLogo.text = let
logo-svg = ../../../../assets/logo_blue_regular.svg;
logo-png = ../../../../assets/logo_blue_regular.png;
in ''
install -Dm444 ${logo-svg} ${cfg.stateDir}/custom/public/img/logo.svg
install -Dm444 ${logo-png} ${cfg.stateDir}/custom/public/img/logo.png
install -Dm444 ${./loading.apng} ${cfg.stateDir}/custom/public/img/loading.png
'';
systemd.services.install-gitea-customization = {
description = "Install extra customization in gitea's CUSTOM_DIR";
wantedBy = [ "gitea.service" ];
requiredBy = [ "gitea.service" ];
serviceConfig = {
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,116 @@
{ 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;
shell = pkgs.bash;
};
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" ''
mkdir -p "$1"
${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,126 @@
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 },
)
results = [repo["name"] for repo in result.json()]
target = int(result.headers['X-Total-Count'])
i = 2
while len(results) < target:
result = requests.get(
f"{args.api_url}/orgs/{args.org}/repos",
params = { 'page': i },
headers = { 'Authorization': 'token ' + token },
)
results += [repo["name"] for repo in result.json()]
i += 1
return results
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 = [
./roundcube.nix
./snappymail.nix
];
services.nginx.virtualHosts."webmail2.pvv.ntnu.no" = {
services.nginx.virtualHosts."webmail.pvv.ntnu.no" = {
forceSSL = true;
enableACME = true;
#locations."/" = lib.mkForce { };
locations."= /" = {
return = "301 https://www.pvv.ntnu.no/mail/";
kTLS = true;
locations = {
"= /".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;
let
cfg = config.services.roundcube;
domain = "webmail2.pvv.ntnu.no";
in
domain = "webmail.pvv.ntnu.no";
in
{
sops.secrets."roundcube/postgres_password" = {
owner = "nginx";
group = "nginx";
};
services.roundcube = {
enable = true;
@ -20,6 +25,11 @@ in
maxAttachmentSize = 20;
hostName = "roundcubeplaceholder.example.com";
database = {
host = "postgres.pvv.ntnu.no";
passwordFile = config.sops.secrets."roundcube/postgres_password".path;
};
extraConfig = ''
$config['enable_installer'] = false;
$config['default_host'] = "ssl://imap.pvv.ntnu.no";
@ -35,6 +45,7 @@ in
services.nginx.virtualHosts."roundcubeplaceholder.example.com" = lib.mkForce { };
services.nginx.virtualHosts.${domain} = {
kTLS = true;
locations."/roundcube" = {
tryFiles = "$uri $uri/ =404";
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,14 +1,12 @@
{ pkgs, values, ... }:
{ fp, pkgs, values, ... }:
{
imports = [
./hardware-configuration.nix
../../base.nix
../../misc/metrics-exporters.nix
(fp /base)
(fp /misc/metrics-exporters.nix)
./services/nginx
./acmeCert.nix
./services/mysql.nix
./services/postgres.nix
./services/mysql.nix
@ -17,7 +15,7 @@
./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.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true;
@ -36,6 +34,9 @@
anyInterface = true;
};
# There are no smart devices
services.smartd.enable = false;
# Do not change, even during upgrades.
# See https://search.nixos.org/options?show=system.stateVersion
system.stateVersion = "22.11";

View File

@ -1,12 +1,20 @@
{ config, lib, pkgs, ... }:
{ config, fp, lib, pkgs, ... }:
let
cfg = config.services.pvv-calendar-bot;
in {
sops.secrets."calendar-bot/matrix_token" = {
sopsFile = ../../../secrets/bicep/bicep.yaml;
key = "calendar-bot/matrix_token";
owner = cfg.user;
group = cfg.group;
sops.secrets = {
"calendar-bot/matrix_token" = {
sopsFile = fp /secrets/bicep/bicep.yaml;
key = "calendar-bot/matrix_token";
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 = {
@ -18,6 +26,11 @@ in {
user = "@bot_calendar: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;
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" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml;
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "synapse/turnconfig";
owner = config.users.users.matrix-synapse.name;
group = config.users.users.matrix-synapse.group;
};
sops.secrets."matrix/coturn/static-auth-secret" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml;
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "coturn/static-auth-secret";
owner = config.users.users.turnserver.name;
group = config.users.users.turnserver.group;
@ -26,7 +26,7 @@
"turns:turn.pvv.ntnu.no:5349?transport=tcp"
"turns:turn.pvv.ntnu.no:5349?transport=udp"
"turns:turn.pvv.ntnu.no:3478?transport=udp"
"turns:turn.pvv.ntnu.no:3478?transport=tcp"
"turn:turn.pvv.ntnu.no:3478?transport=udp"
@ -60,16 +60,18 @@
pkey = "${config.security.acme.certs.${realm}.directory}/key.pem";
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;
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;
alt-tls-listening-port = 5349;
listening-port = 3478;
min-port = 49000;
@ -116,7 +118,7 @@
#total-quota=1200
'';
};
networking.firewall = {
interfaces.enp6s0f0 = let
range = with config.services.coturn; [ {

View File

@ -10,8 +10,9 @@
./mjolnir.nix
./discord.nix
./hookshot
];
}

View File

@ -1,4 +1,4 @@
{ config, lib, ... }:
{ config, lib, fp, ... }:
let
cfg = config.services.mx-puppet-discord;
@ -6,15 +6,42 @@ in
{
users.groups.keys-matrix-registrations = { };
sops.secrets."matrix/registrations/mx-puppet-discord" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml;
key = "registrations/mx-puppet-discord";
sops.secrets."matrix/discord/as_token" = {
sopsFile = fp /secrets/bicep/matrix.yaml;
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;
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 = {
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 = [ ".*" ];
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 = {
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;
};

View File

@ -5,6 +5,7 @@ in {
services.nginx.virtualHosts."chat.pvv.ntnu.no" = {
enableACME = true;
forceSSL = true;
kTLS = true;
root = pkgs.element-web.override {
conf = {
@ -24,21 +25,26 @@ in {
features = {
feature_latex_maths = true;
feature_pinning = true;
feature_render_reaction_images = true;
feature_state_counters = true;
feature_custom_status = false;
# element call group calls
feature_group_calls = true;
};
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 = [
"pvv.ntnu.no"
"matrix.omegav.no"
"matrix.org"
"libera.chat"
"gitter.im"
"mozilla.org"
"kde.org"
"t2bot.io"
"fosdem.org"
"dodsorf.as"
"matrixrooms.info" # Searches all public room directories
"matrix.omegav.no" # Friends
"gitter.im" # gitter rooms
"mozilla.org" # mozilla and friends
"kde.org" # KDE rooms
"fosdem.org" # FOSDEM
"dodsorf.as" # PVV Member
"nani.wtf" # PVV Member
];
enable_presence_by_hs_url = {
"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" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml;
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "mjolnir/access_token";
owner = config.users.users.mjolnir.name;
group = config.users.users.mjolnir.group;
@ -11,7 +11,7 @@
services.mjolnir = {
enable = true;
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;
managementRoom = "!gsdeCoWjvYRBrzuiRq:pvv.ntnu.no";
protectedRooms = map (a: "https://matrix.to/#/${a}") [

View File

@ -5,6 +5,10 @@ from smtplib import SMTP_SSL as SMTP
import synapse
from synapse import module_api
import re
import logging
logger = logging.getLogger(__name__)
class SMTPAuthProvider:
def __init__(self, config: dict, api: module_api):
@ -27,6 +31,10 @@ class SMTPAuthProvider:
if login_type != "m.login.password":
return None
# Convert `@username:server` to `username`
match = re.match(r'^@([\da-z\-\.=_\/\+]+):[\w\d\.:\[\]]+$', username)
username = match.group(1) if match else username
result = False
with SMTP(self.config["smtp_host"]) as smtp:
password = login_dict.get("password")
@ -38,8 +46,13 @@ class SMTPAuthProvider:
if result == True:
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)
else:
logger.info("returning None")
return None

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, values, inputs, ... }:
{ config, lib, fp, pkgs, values, inputs, ... }:
let
cfg = config.services.matrix-synapse-next;
@ -10,23 +10,18 @@ let
in {
sops.secrets."matrix/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;
group = config.users.users.matrix-synapse.group;
};
sops.secrets."matrix/synapse/user_registration" = {
sopsFile = ../../../../secrets/bicep/matrix.yaml;
sopsFile = fp /secrets/bicep/matrix.yaml;
key = "synapse/signing_key";
owner = config.users.users.matrix-synapse.name;
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 = {
enable = true;
@ -43,8 +38,6 @@ in {
workers.eventPersisters = 2;
workers.useUserDirectoryWorker = true;
enableSlidingSync = true;
enableNginx = true;
settings = {
@ -134,90 +127,16 @@ in {
"129.241.0.0/16"
"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.nginx.virtualHosts."matrix.pvv.ntnu.no" = lib.mkMerge [
({
{
kTLS = true;
}
{
locations."/.well-known/matrix/server" = {
return = ''
200 '{"m.server": "matrix.pvv.ntnu.no:443"}'
@ -227,26 +146,38 @@ in {
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
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}";
proxyPath = w: "http://${socketAddress w}/_synapse/metrics";
in lib.mapAttrs' (n: v: lib.nameValuePair
(metricsPath v) ({
(metricsPath v) {
proxyPass = proxyPath v;
extraConfig = ''
allow ${values.hosts.ildkule.ipv4};
allow ${values.hosts.ildkule.ipv6};
deny all;
'';
}))
})
cfg.workers.instances;
})
({
}
{
locations."/metrics/master/1" = {
proxyPass = "http://127.0.0.1:9000/_synapse/metrics";
extraConfig = ''
@ -269,5 +200,5 @@ in {
labels = { };
}]) + "/";
};
})];
}];
}

View File

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

View File

@ -1,15 +1,8 @@
{ config, values, ... }:
{
security.acme = {
acceptTerms = true;
defaults.email = "danio@pvv.ntnu.no";
};
services.nginx = {
enable = true;
enableReload = true;
defaultListenAddresses = [
values.hosts.bicep.ipv4
"[${values.hosts.bicep.ipv6}]"
@ -18,28 +11,5 @@
"127.0.0.2"
"[::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, ... }:
let
sslCert = config.security.acme.certs."postgres.pvv.ntnu.no";
in
{
services.postgresql = {
enable = true;
@ -79,12 +76,16 @@ in
systemd.services.postgresql.serviceConfig = {
LoadCredential = [
"cert:${sslCert.directory}/cert.pem"
"key:${sslCert.directory}/key.pem"
"cert:/etc/certs/postgres.crt"
"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.allowedUDPPorts = [ 5432 ];

View File

@ -0,0 +1,44 @@
{ config, pkgs, values, ... }:
{
networking.nat = {
enable = true;
internalInterfaces = ["ve-+"];
externalInterface = "ens3";
# Lazy IPv6 connectivity for the container
enableIPv6 = true;
};
containers.bikkje = {
autoStart = true;
config = { config, pkgs, ... }: {
#import packages
packages = with pkgs; [
alpine
mutt
mutt-ics
mutt-wizard
weechat
weechatScripts.edit
hexchat
irssi
pidgin
];
networking = {
firewall = {
enable = true;
# Allow SSH and HTTP and ports for email and irc
allowedTCPPorts = [ 80 22 194 994 6665 6666 6667 6668 6669 6697 995 993 25 465 587 110 143 993 995 ];
allowedUDPPorts = [ 80 22 194 994 6665 6666 6667 6668 6669 6697 995 993 25 465 587 110 143 993 995 ];
};
# Use systemd-resolved inside the container
# Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686
useHostResolvConf = mkForce false;
};
system.stateVersion = "23.11";
services.resolved.enable = true;
};
};
};

View File

@ -1,16 +1,16 @@
{ config, pkgs, values, ... }:
{ config, fp, pkgs, values, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
../../base.nix
../../misc/metrics-exporters.nix
(fp /base)
(fp /misc/metrics-exporters.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.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true;

View File

@ -1,10 +1,10 @@
{ config, pkgs, values, ... }:
{ config, fp, pkgs, values, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
../../base.nix
../../misc/metrics-exporters.nix
(fp /base)
(fp /misc/metrics-exporters.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}" = {
serverAliases = [

View File

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

View File

@ -1,42 +1,55 @@
{ config, pkgs, values, ... }:
{ config, fp, pkgs, lib, values, ... }:
{
imports = [
# Include the results of the hardware scan.
./hardware-configuration.nix
../../base.nix
../../misc/metrics-exporters.nix
(fp /base)
(fp /misc/metrics-exporters.nix)
./services/monitoring
./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.keyFile = "/var/lib/sops-nix/key.txt";
sops.age.generateKey = true;
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.grub.device = "/dev/vda";
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 // {
matchConfig.Name = "ens18";
address = with values.hosts.ildkule; [ (ipv4 + "/25") (ipv6 + "/64") ];
search = values.defaultNetworkConfig.domains;
nameservers = values.defaultNetworkConfig.dns;
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
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
# 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?
system.stateVersion = "23.11"; # Did you read the comment?
}

View File

@ -1,37 +1,16 @@
# 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, ... }:
{ modulesPath, lib, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
imports = [ (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.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

@ -23187,4 +23187,4 @@
"uid": "rYdddlPWk",
"version": 9,
"weekStart": ""
}
}

View File

@ -3164,4 +3164,4 @@
"title": "PostgreSQL Database",
"uid": "000000039",
"version": 1
}
}

View File

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

View File

@ -7,7 +7,6 @@ in {
in {
"keys/grafana/secret_key" = { inherit owner group; };
"keys/grafana/admin_password" = { inherit owner group; };
"keys/postgres/grafana" = { inherit owner group; };
};
services.grafana = {
@ -18,7 +17,7 @@ in {
secretFile = path: "$__file{${path}}";
in {
server = {
domain = "ildkule.pvv.ntnu.no";
domain = "grafana.pvv.ntnu.no";
http_port = 2342;
http_addr = "127.0.0.1";
};
@ -27,13 +26,6 @@ in {
secret_key = secretFile config.sops.secrets."keys/grafana/secret_key".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 = {
@ -42,13 +34,13 @@ in {
{
name = "Ildkule Prometheus";
type = "prometheus";
url = ("http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}");
isDefault = true;
url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}";
isDefault = true;
}
{
name = "Ildkule 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 = [
@ -64,13 +56,13 @@ in {
url = "https://raw.githubusercontent.com/matrix-org/synapse/develop/contrib/grafana/synapse.json";
options.path = dashboards/synapse.json;
}
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
# {
# name = "MySQL";
# type = "file";
# url = "https://raw.githubusercontent.com/prometheus/mysqld_exporter/main/mysqld-mixin/dashboards/mysql-overview.json";
# options.path = dashboards/mysql.json;
# }
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
# {
# name = "MySQL";
# type = "file";
# url = "https://raw.githubusercontent.com/prometheus/mysqld_exporter/main/mysqld-mixin/dashboards/mysql-overview.json";
# options.path = dashboards/mysql.json;
# }
{
name = "Postgresql";
type = "file";
@ -83,6 +75,12 @@ in {
url = "https://grafana.com/api/dashboards/240/revisions/3/download";
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} = {
enableACME = true;
forceSSL = true;
kTLS = true;
locations = {
"/" = {
proxyPass = "http://127.0.0.1:${toString cfg.settings.server.http_port}";

View File

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

View File

@ -1,18 +1,26 @@
{ config, ... }: {
{ config, ... }: let
stateDir = "/data/monitoring/prometheus";
in {
imports = [
./gogs.nix
./gitea.nix
./matrix-synapse.nix
# TODO: enable once https://github.com/NixOS/nixpkgs/pull/242365 gets merged
# ./mysqld.nix
./node.nix
./postgres.nix
./machines.nix
];
services.prometheus = {
enable = true;
listenAddress = "127.0.0.1";
port = 9001;
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"
];
}
];
}];
}

View File

@ -38,7 +38,7 @@ in {
};
systemd.services.prometheus-postgres-exporter-knakelibrak.serviceConfig = let
localCfg = config.services.prometheus.exporters.postgres;
localCfg = config.services.prometheus.exporters.postgres;
in lib.recursiveUpdate config.systemd.services.prometheus-postgres-exporter.serviceConfig {
EnvironmentFile = config.sops.secrets."keys/postgres/postgres_exporter_knakelibrak_env".path;
ExecStart = ''

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