From f5185e5c155e88f17a84d7af8572ca6971ab404b Mon Sep 17 00:00:00 2001 From: b12f Date: Mon, 30 Oct 2023 01:22:34 +0100 Subject: [PATCH] feat: add mediawiki Co-authored-by: @teutat3s --- .forgejo/workflows/check.yml | 5 + hosts/nachtigall/apps/mediawiki.nix | 232 +++++++++++++++++++++++ hosts/nachtigall/apps/postgresql.nix | 6 +- hosts/nachtigall/apps/searx.nix | 2 +- hosts/nachtigall/default.nix | 1 + modules/docker.nix | 2 + modules/users.nix | 2 +- overlays/default.nix | 2 + secrets/mediawiki-admin-password.age | 27 +++ secrets/mediawiki-database-password.age | 28 +++ secrets/mediawiki-oidc-client-secret.age | 27 +++ secrets/mediawiki-secret-key.age | 28 +++ secrets/secrets.nix | 5 + terraform/dns.tf | 5 + 14 files changed, 369 insertions(+), 3 deletions(-) create mode 100644 hosts/nachtigall/apps/mediawiki.nix create mode 100644 secrets/mediawiki-admin-password.age create mode 100644 secrets/mediawiki-database-password.age create mode 100644 secrets/mediawiki-oidc-client-secret.age create mode 100644 secrets/mediawiki-secret-key.age diff --git a/.forgejo/workflows/check.yml b/.forgejo/workflows/check.yml index 1fd318b..7d73e20 100644 --- a/.forgejo/workflows/check.yml +++ b/.forgejo/workflows/check.yml @@ -5,6 +5,11 @@ jobs: Check: runs-on: nix-flakes steps: + - name: Get Node.js dependency + run: | + nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs + nix-channel --update + nix-env -iA nixpkgs.nodejs_20 - name: Check out repository code uses: https://code.forgejo.org/actions/checkout@v4 - name: Prepare cachix diff --git a/hosts/nachtigall/apps/mediawiki.nix b/hosts/nachtigall/apps/mediawiki.nix new file mode 100644 index 0000000..3c65bcc --- /dev/null +++ b/hosts/nachtigall/apps/mediawiki.nix @@ -0,0 +1,232 @@ +{ + flake, + config, + lib, + pkgs, + ... +}: let + localSettingsPHP = pkgs.writeScript "LocalSettings.php" '' + "https://pub.solar/assets/pubsolar.svg", + 'icon' => "https://pub.solar/assets/pubsolar.svg", + 'wordmark' => [ + 'src'=> "https://pub.solar/assets/pubsolar.svg", + 'width'=> 0, + 'height'=> 0, + ], + ]; + $wgFavicon = 'https://pub.solar/assets/pubsolar.svg'; + + $wgDefaultSkin = 'vector-2022'; + + // https://www.mediawiki.org/wiki/Extension:PluggableAuth#Installation + $wgGroupPermissions['*']['autocreateaccount'] = true; + + // https://www.mediawiki.org/wiki/Extension:PluggableAuth#Configuration + $wgPluggableAuth_EnableAutoLogin = false; + $wgPluggableAuth_ButtonLabel = 'Login with pub.solar ID'; + + // https://www.mediawiki.org/wiki/Extension:OpenID_Connect#Keycloak + $wgPluggableAuth_Config[] = [ + 'plugin' => 'OpenIDConnect', + 'data' => [ + 'providerURL' => 'https://auth.pub.solar/realms/pub.solar', + 'clientID' => 'mediawiki', + 'clientsecret' => trim(file_get_contents('/run/mediawiki/oidc-client-secret')) + ] + ]; + $wgOpenIDConnect_SingleLogout = true; + $wgOpenIDConnect_MigrateUsersByEmail = true; + ''; + + uid = 986; + gid = 984; +in { + age.secrets.mediawiki-database-password = { + file = "${flake.self}/secrets/mediawiki-database-password.age"; + path = "/run/mediawiki/database-password"; + symlink = false; + mode = "440"; + owner = "mediawiki"; + group = "mediawiki"; + }; + + age.secrets.mediawiki-oidc-client-secret = { + file = "${flake.self}/secrets/mediawiki-oidc-client-secret.age"; + path = "/run/mediawiki/oidc-client-secret"; + symlink = false; + mode = "440"; + owner = "mediawiki"; + group = "mediawiki"; + }; + + age.secrets.mediawiki-secret-key = { + file = "${flake.self}/secrets/mediawiki-secret-key.age"; + path = "/run/mediawiki/secret-key"; + symlink = false; + mode = "440"; + owner = "mediawiki"; + group = "mediawiki"; + }; + + services.postgresql = { + authentication = '' + host mediawiki all 172.17.0.0/16 password + ''; + }; + + services.nginx.virtualHosts."wiki.pub.solar" = { + enableACME = true; + forceSSL = true; + + locations."/".proxyPass = "http://127.0.0.1:8293"; + }; + + users.users.mediawiki = { + isSystemUser = true; + group = "mediawiki"; + inherit uid; + }; + users.groups.mediawiki = { inherit gid; }; + + virtualisation = { + oci-containers = { + backend = "docker"; + + containers."mediawiki" = { + image = "git.pub.solar/pub-solar/mediawiki-oidc-docker:latest"; + user = "1000:${builtins.toString gid}"; + autoStart = true; + + ports = [ + "127.0.0.1:8293:80" + ]; + + extraOptions = [ + "--add-host=host.docker.internal:host-gateway" + "--pull=always" + ]; + + volumes = [ + "/run/mediawiki:/run/mediawiki" + "/var/lib/mediawiki/images:/var/www/html/images" + "/var/lib/mediawiki/uploads:/var/www/html/uploads" + "/var/lib/mediawiki/logs:/var/log/mediawiki" + "${localSettingsPHP}:/var/www/html/LocalSettings.php" + ]; + }; + }; + }; +} diff --git a/hosts/nachtigall/apps/postgresql.nix b/hosts/nachtigall/apps/postgresql.nix index 82d66e7..5ab56c6 100644 --- a/hosts/nachtigall/apps/postgresql.nix +++ b/hosts/nachtigall/apps/postgresql.nix @@ -1,7 +1,11 @@ { ... }: { - services.postgresql.enable = true; + services.postgresql = { + enable = true; + enableTCPIP = true; + }; + systemd.services.postgresql = { after = [ "var-lib-postgresql.mount" diff --git a/hosts/nachtigall/apps/searx.nix b/hosts/nachtigall/apps/searx.nix index 5785b9f..d97a012 100644 --- a/hosts/nachtigall/apps/searx.nix +++ b/hosts/nachtigall/apps/searx.nix @@ -8,7 +8,7 @@ { age.secrets.searx-environment = { file = "${flake.self}/secrets/searx-environment.age"; - mode = "700"; + mode = "600"; }; services.nginx.virtualHosts."search.pub.solar" = { diff --git a/hosts/nachtigall/default.nix b/hosts/nachtigall/default.nix index de92789..8800356 100644 --- a/hosts/nachtigall/default.nix +++ b/hosts/nachtigall/default.nix @@ -15,6 +15,7 @@ ./apps/keycloak.nix ./apps/mailman.nix ./apps/mastodon.nix + ./apps/mediawiki.nix ./apps/nextcloud.nix ./apps/owncast.nix ./apps/nginx-mastodon.nix diff --git a/modules/docker.nix b/modules/docker.nix index 8021dad..5cb9023 100644 --- a/modules/docker.nix +++ b/modules/docker.nix @@ -6,4 +6,6 @@ ''; storageDriver = "zfs"; }; + + networking.firewall.trustedInterfaces = [ "docker0" ]; } diff --git a/modules/users.nix b/modules/users.nix index 5f8b43c..a2e4ca7 100644 --- a/modules/users.nix +++ b/modules/users.nix @@ -2,7 +2,7 @@ users.users.${flake.self.username} = { name = flake.self.username; group = flake.self.username; - extraGroups = ["wheel"]; + extraGroups = ["wheel" "docker"]; isNormalUser = true; openssh.authorizedKeys.keys = flake.self.publicKeys.admins; }; diff --git a/overlays/default.nix b/overlays/default.nix index 97c9bc7..537e17b 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -10,6 +10,8 @@ (final: prev: { mastodon = inputs.mastodon-fork.legacyPackages.${prev.system}.mastodon; forgejo-actions-runner = inputs.unstable.legacyPackages.${prev.system}.forgejo-actions-runner; + + mediawiki = inputs.unstable.legacyPackages.${prev.system}.mediawiki; }) ]; }); diff --git a/secrets/mediawiki-admin-password.age b/secrets/mediawiki-admin-password.age new file mode 100644 index 0000000..5efb88c --- /dev/null +++ b/secrets/mediawiki-admin-password.age @@ -0,0 +1,27 @@ +age-encryption.org/v1 +-> ssh-ed25519 iDKjwg LcyG6l8PyH97exah393jsbCvMiPglSUdE9+xgiuxj24 ++iL2WJUShBHg3Phy20pj6Ey7+CbW0kePMpRr0IFGMow +-> ssh-ed25519 uYcDNw 2aoZ0g9M/dy+JN+XGijHbSER9C2WnGcbfiH8qamDTHk +uJvrHKDoKGFMTDYIoI1R+9GsRHbwOi+lncga7n+MZIY +-> ssh-rsa kFDS0A +XaTAfhahB+pcCodZp7lh3tGH7JRyvErDWPCgL2Uz7Z/MTeLqsqc/bWHHodGMvvba +gizm978vCp5jC7gz7Gior9y9//QlIC3nLklOXPtGRALMWxI72aYeWXuz6NclTfmB +8ADxCFJ/t+DHlphNvmYTm4OYbSd0rLUR2uhPB9bfcrs+Xn28IglP/3CnWtb0bKgU +xFu5ghqmzaZwYEsk1rBkslSpjClfsrAuptahAeAoP6ZB3UAcyGxYTl1JWZ8NsGx5 +wciyUdaMKernsAM9GOFFmA7ax6QtR70u57KCcsV9CyhBaB8W6vTlVomTGuxvA0tR +jM518FxK/R4DQ+DXyYy2t6k7AolN6owu04cxJQZIlplwBYA1jaqNUkbSs7OdnKqz +IQfmJ6EIJRqr+FAV4g4JrhfU9RMJiZsxN1sCIpUEH38RLY2VU0JTFhR5rFqLEaYH +q1phO0NBtEKbjZBH3WNdeaOl2420WTebMZXu8i+wwA9ApLAdmh9BdiJCRgxwXuxo +7vj5/QdRAtGZwscCol58s9fOtLz4euTSvEMp58uiQUg0Tlx8UTG+PIGYlIXQ2VuU +jbZiHU5u4yFIkQqlqwo9ffQtn6gH8GT7P5tdFKMucsrwZF7ui6FfuDCLk+TBWhGS +Y5k9Y7u3tXnIATksKUV+SfOEwqDyNU58Y0MA6M/HaU0 +-> ssh-ed25519 YFSOsg +3UYmfhtMlKT3bodpFR9S52lmpN3Cu7wT/lwm4kZrC8 +VtlMr493XZe7O6QsYf9rwq58JPox/wQvnGLXJN5CB5I +-> ssh-ed25519 iHV63A 9uadUaJT6jEsyMFMEfohMCUgxSXB7bsa++70P1a0LFM +BW99xSdQTBBjFkEmlNTB1N3jxmGY+0oYnps8RoidUvw +-> ssh-ed25519 BVsyTA Iuixq7laf7fN20bXYoc1O89cJWExzSxD/XkOg6BjKSc +Bq3+y48SSkaDnuYmp38yGXNkp93qUNJemfTxtVnpUD0 +-> 4-grease ($vN N +b6PMSRSIUZMlLXQx9xaM9KMlk1kzMotNwC1L +--- AKDHmogRbZ+hiS/5jYlvBFRG0vfY31lMbH/vqAlTfLY +-m8ɚAqAfhÆ]Dv.hWS~ȫp'.&-ȇ_ \ No newline at end of file diff --git a/secrets/mediawiki-database-password.age b/secrets/mediawiki-database-password.age new file mode 100644 index 0000000..cb436a7 --- /dev/null +++ b/secrets/mediawiki-database-password.age @@ -0,0 +1,28 @@ +age-encryption.org/v1 +-> ssh-ed25519 iDKjwg z0obMnCseK5QoAge88uhbvcI5fk07UOBZk/rEXQCagU +RtYb7D5diitYmAh+K0TbPlF2ps2LaBeVeQ8iabUA/3U +-> ssh-ed25519 uYcDNw xy8dFpnQszNlQernP7dkw/VIF1++KiTsIGDJsDHusSQ +l82JxR2oJ71rRSZYPeXvNZyuEa2o2/uxDCJawOj9m4k +-> ssh-rsa kFDS0A +NKl5eefpdKltFPeg5bO8vw4xa6qVo5nRMF4xTO7t6wcRagADcDWYp0ZfYoHABOFH +yBL1YQ2VXAMmbchJKrIy4N9oy26cGifxzFBgkPlnKOxUUXuaXgv2vMTTOUUB5mlp +gax7uq+J1qLtkc/yfvt/OOWv9qRf9vHhIWuG6/vbv+8ATWbMANLZB6GPBlW5dWJG +A4ZV88Zd/zenB3d+bo5Gh9/RxazGfb98GwMFoHv67WUn/W542IDZyywTz/8cQB7I +8POfee3cuiQ1K19vn4rbHldVxYCmbESS3KR6gzPk0HAi6KFxW29NqHsX//ObPkL3 +wYsKyYtsJLOy1gAKIcHG/6kysh3MstFq3Q977kuskk79JXIjiiPNFfQOh/WZKXvl +EwuaTTvyzzXuPBRSaTMYUv3NwlT7IBeZ1D/hOmmmN4GmbE0qIp9hDQbwSrf4+3Z3 +irVMOee5SmLYwsj5cZPU7AdNs3Q1o0C2ooTA/WYFMdUKeI1ZhtNAekbuXseH2zr4 +N/j+XMSx7KAIB0Pb5yqkI/DliZpacG5DT6f+qgDYyEh0XEf7Eazn02EnquayB1Sr +sgdZ7SO+ntPzc2l/JbhFN5SpH6iQJVohwkjBXQUQyJuLZBYdh4M0x4KF0P6xVO+P +iBGM3/9jm86AOa6yhlfh8Z6h9ckKk5DNkMTJn+2fQc4 +-> ssh-ed25519 YFSOsg ZpPUH11hi+hg1Euil1aJNXqrOKjQrucI8Mi9KVrMnwE +xPoiMVzjfWUpUUC3EZUiogLJZfKWs2/jwGZfsx27CKQ +-> ssh-ed25519 iHV63A t4j7mr+hoW5fR9+ry3/tqKvQERZs/h7Qn9LEeeSWFhc +XZjUNUWkWnJG7l8vahfppxZ/kjH1VRf8YNpt8x2H67M +-> ssh-ed25519 BVsyTA SztbpuYbTH+FkumMGCAQ4fQ/rRRZgGg2yCPHjS8qtTI +F98vVoeITz/WJnJamw1I4zLHBcF46FYxKibwmbInFoA +-> %R9cvM-grease 8#EQ8Q l:Yu\ +VBsYA1Kyd/sz6RVeZNHBMvKlYmwKcuvWKyGOLzzcaz6C6kzHNgtWXcLRC0A9wMDt +xQkX8fYdijHTcclcGerWUa8iqnpd7rAgo8RjG5e5JzhW +--- k9Ai5b4pxmq4DnN/3a6UyllvEzFaEFv0ePExwfUpplA +5<lEN WՀϢ%b<"a)8*ŔcC0|VqvS \ No newline at end of file diff --git a/secrets/mediawiki-oidc-client-secret.age b/secrets/mediawiki-oidc-client-secret.age new file mode 100644 index 0000000..104b3c7 --- /dev/null +++ b/secrets/mediawiki-oidc-client-secret.age @@ -0,0 +1,27 @@ +age-encryption.org/v1 +-> ssh-ed25519 iDKjwg wNZLc0SqLieSDPQzQEcJML08uiCKPLJoI95maDa4a3E +KXWlP0ZPWl3WiSX04UKtwHdhezMdLT3nskLl7E7OSHs +-> ssh-ed25519 uYcDNw yA4rP44m2CJgvuSG4NrRFY1BWAXbdzov5AK/eYDu42Q +vfZ6m1Vw0WNsnCmXe4jOtSvHMHXVxRBvP2Fkqki/xK8 +-> ssh-rsa kFDS0A +Milr41weYJCyX92mWcSBSJEeUetq76tzjwsCjJtfpvG5ASsiu/Wj7jtngOO9wER2 +8kgh3DVQVlZV9kwHoC8zM3C+qYU4HQf74Sr9TXXcZko9HBZA17O3I5IBnp5cmVsq +ZBE1gpuT+J/xSA14w4Kf7LbobNpYuMrEGoquWAH9ESjPt7HY067rGe8nBy2RoAM5 +FyXQ8uoPw6wDB5Ak6HGT3pdzazjtDugJdaO/9CT07lI+XvSAD5CBvtfjoWAdTphC ++6S1t9gcNZrd+oQ3LZ1mSnvjVc+O4YHjzy56zo3Zh1KJLxMbdkO1st72fsNTNXjI +gj3ZYmodz/lfTxQABreQdo9AUCBBQkoyGv2uilYbJPTTeUxCXUnGGkDqW4e0p/8z +ukHiqeeMw4XqPXAduVlNIpsvW1s0sDB3Kx8t+KJirr4PHfIIulHbnjPxKQyXaj86 +nzSYSuzftOquAz8CIokgRyFhgJtRD2lzNhXbt6GvU4VLagtmbFQmhyqVJzzvmnE3 +7cu6Fcc07IiA7CuhweAmWA8/vjBtbyQMqVAHVn+ijT4WKb7gDfcL/w/MZaq5XOa0 +9zyoTa7y7ttC3AqzDWlfOEK9TC+ysKB6LgTwktNS3u0Msh2DYNqLsyN+ktDyb27F +YzT4Wu5ZoYcCkgNwvAyU2hPfYzv66mQo1I0BXKYaiQg +-> ssh-ed25519 YFSOsg BJMjSn6gwtaOheT9Fnes45QZ5BSBGnhhGTPFO5DJIU0 +cyhAM4/waWjH/N6WWy/8w4M4PQt+QzpgMy+7M5DBTj0 +-> ssh-ed25519 iHV63A JTvN/gJpphteU1WpESnZ9iTeePj986kuYxI2poVYdxc +kJCBRrqzEW7c/Y6HiiJLmBzlsBtvZsK++NsEVoZHScs +-> ssh-ed25519 BVsyTA 9cJBL0f0XAQWat68M3mMVSAKpnKNNzAqAmcuQ8fJiic +TSA6SRwonr8e1kMrGyf89F/TPmU2S1SmOlH2KbJmFTc +-> *OkMh]47-grease ,|3o ^Ai N WuMh +YpKgkp1VxwVinaiFO0pFDw +--- 4278uiwRYOTQM1T7Cs/1Hzn3AiRkyvXuqtE+9wyfD+A + ssh-ed25519 iDKjwg MGfeCP81T9itCIgFoOcDoJfLtvfOb1dEtx4SjRfQMDU +QJcTZDMx6qZfTtQxRpDAb5oA7PWqAgVDiZ5m9PeD3OU +-> ssh-ed25519 uYcDNw 3uX4IxJVdepJ/258XhKUEOeX00nbKQ3+8WskCE/Oex0 +WaTAvd0zrcyFFwz7QWwaEsBrtp08g3wbANJvoL+hkfc +-> ssh-rsa kFDS0A +kgdsJuX6ZiMPJx5OjJuu0pjLqIr7vmw6SSRAWVR2RgxUbZ2L0khOUCOSbeHExpju +RtadRLVKgxGkGAYqaivcUj0fu71RbxAfsCkY6hwrXGAwWLLcviTeZpRJUcVWWdkW +DkZKVukqq2XeB33CqVcTanEVgTmwfuASVb5WL/FBrDpITV0oTcyJB5k57Qor7utC +9PBYJmkq8ZDbpcZQM210XYCJdOhK4J4j0Rbq3Er6a9mlxVWuGUiBUUXluwDBN7iG +sEha1Y6GvWfaqy3Y0Y+XxkNx3KsRnRvT3h9lmCM/RVaIGIeOTgF/ZRSKoUuMZ9nY ++XCXTGOhUZZBb/d0Edh+0EF7JCNOHA0Uygu+8RjxxNTMxLDV2eR5N+yYH4tbPuQj +QI3Wo8H5iDwwCnyDwmXwkRWd9aEhfG16S3NqbyCfEA/xIUgQnIEx7DEjLJwDrb4v +IVL6cxqSU/GCV2x7HyHf4syZBSQ6oC2Cy5sEJ5WV1m7+S35Vh5UQcxh+oNk1Gxji +Y6yhem70RFLauzxldNcpI/xKTsj+mfrI21+fb6InVSHzlME0ggcMdz5mp799TEeg +GYO+lIlfKIPWcQYI6Ci+Qbs1bGZ8kJy82C6arW6rooPQTdqnOgJE++1lj9dZO6bx +W9oEdGnkIN/QH8RWVLi9bgznVmlzLLpYqM/d+bpEA+k +-> ssh-ed25519 YFSOsg ccuBr0eGaJ/t2lWMhKNP/c2TtpmGYaenxQSQI9DJv3c +uLGi3j4gt5xRj3MOsLUjkkA9dCS12feyLQf1YZtDvgg +-> ssh-ed25519 iHV63A GHevWTk7/M0TtlIo/uZnCn84jq9I2jP9ehkt6PxRgEc +nF5O/yCV/3zduBtGw6VbwPS2jFHJlUgHiSytDOPSzaU +-> ssh-ed25519 BVsyTA Tw/06YNSoYYlrtfocjh0pitrWJc8zNAr8RLc42mMjWI +RaA9t5VwYWYHFquZuXmNrGVkdDOJDh3dgVG+31UxhM8 +-> %zh9-grease 6 rETV7H +1TID2TYG2RCwwRws8vOvdfDM0zQcqRTDqfJbZsbOAiZQnOU3Lt8g+rwcSgOB7kX4 +lx5lPRHxCa+86NljA+tW5l5u1JZurA +--- wBDm8U0KDrRkdoeUfQq0Zk81611Im9hlSo96NE4FB9w +ȕ7]DBўܳD[DC JJrE+ݿp3xtJLӲ1 \ No newline at end of file diff --git a/secrets/secrets.nix b/secrets/secrets.nix index fa761b0..7baeeae 100644 --- a/secrets/secrets.nix +++ b/secrets/secrets.nix @@ -54,4 +54,9 @@ in { "drone-db-secrets.age".publicKeys = flora6Keys ++ baseKeys; "drone-secrets.age".publicKeys = flora6Keys ++ baseKeys; + + "mediawiki-database-password.age".publicKeys = nachtigallKeys ++ baseKeys; + "mediawiki-admin-password.age".publicKeys = nachtigallKeys ++ baseKeys; + "mediawiki-oidc-client-secret.age".publicKeys = nachtigallKeys ++ baseKeys; + "mediawiki-secret-key.age".publicKeys = nachtigallKeys ++ baseKeys; } diff --git a/terraform/dns.tf b/terraform/dns.tf index 79200e1..4a425ce 100644 --- a/terraform/dns.tf +++ b/terraform/dns.tf @@ -118,6 +118,11 @@ resource "namecheap_domain_records" "pub-solar" { type = "CNAME" address = "nachtigall.pub.solar." } + record { + hostname = "wiki" + type = "CNAME" + address = "nachtigall.pub.solar." + } record { hostname = "mastodon" type = "CNAME"