diff --git a/flake.nix b/flake.nix index 09205d1..5baed75 100755 --- a/flake.nix +++ b/flake.nix @@ -68,7 +68,7 @@ ./modules/hedgedoc.nix ./modules/padlist.nix ./modules/postgres.nix - ./modules/wiki.nix + ./modules/wiki ./modules/ftp.nix #./modules/stream.nix ./modules/nextcloud.nix diff --git a/modules/ese-website.nix b/modules/ese-website.nix index faf2d68..2c8034d 100644 --- a/modules/ese-website.nix +++ b/modules/ese-website.nix @@ -1,4 +1,4 @@ -{ config, pkgs, ... }: +{ config, pkgs, ... }: let domain = "ese.${config.networking.domain}"; cms-domain = "directus-ese.${config.networking.domain}"; @@ -64,6 +64,8 @@ in }; }; virtualHosts."${domain}" = { + enableACME = true; + forceSSL = true; locations."= /" = { return = "301 /2023/"; }; diff --git a/modules/nightline.nix b/modules/nightline.nix index fe994bd..fe08da4 100644 --- a/modules/nightline.nix +++ b/modules/nightline.nix @@ -29,9 +29,6 @@ in phpEnv."PATH" = lib.makeBinPath [ pkgs.php ]; }; - - - services.nginx.enable = true; services.nginx = { virtualHosts."${domain}" = { addSSL = true; diff --git a/modules/wiki/default.nix b/modules/wiki/default.nix new file mode 100644 index 0000000..372553e --- /dev/null +++ b/modules/wiki/default.nix @@ -0,0 +1,8 @@ +{ ... }: +{ + imports = [ + ./fsr.nix + ./vernetzung.nix + ./ese.nix + ]; +} diff --git a/modules/wiki/ese.nix b/modules/wiki/ese.nix new file mode 100644 index 0000000..165aa2e --- /dev/null +++ b/modules/wiki/ese.nix @@ -0,0 +1,85 @@ +{ config, lib, pkgs, ... }: +let + domain = "wiki.ese.${config.networking.domain}"; + user = "wiki-ese"; + group = "wiki-ese"; +in +{ + + users.users.${user} = { + group = group; + isSystemUser = true; + }; + users.groups.${group} = { }; + services.phpfpm.pools.wiki-ese = { + user = user; + group = group; + settings = { + "listen.owner" = config.services.nginx.user; + "pm" = "dynamic"; + "pm.max_children" = 32; + "pm.max_requests" = 500; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 2; + "pm.max_spare_servers" = 5; + "php_admin_value[error_log]" = "stderr"; + "php_admin_flag[log_errors]" = true; + "catch_workers_output" = true; + }; + phpEnv."PATH" = lib.makeBinPath [ pkgs.php ]; + }; + services.nginx = { + virtualHosts."${domain}" = { + addSSL = true; + enableACME = true; + root = "/srv/web/wiki.ese"; + extraConfig = '' + index index.php; + ''; + locations = { + "/" = { + tryFiles = "$uri $uri/ @rewrite"; + }; + "@rewrite".extraConfig = '' + rewrite ^/(.*)$ /index.php?title=$1&$args; + ''; + "^~ /maintenance/".return = "403"; + "~ \.php$" = { + extraConfig = '' + fastcgi_pass unix:${config.services.phpfpm.pools.wiki-ese.socket}; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_index index.php; + include ${pkgs.nginx}/conf/fastcgi_params; + include ${pkgs.nginx}/conf/fastcgi.conf; + fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; + ''; + }; + "/rest.php" = { + tryFiles = "$uri $uri/ /rest.php?$args"; + }; + "~* \.(js|css|png|jpg|jpeg|gif|ico)$" = { + tryFiles = "$uri /index.php"; + extraConfig = '' + expires max; + log_not_found off; + ''; + }; + "/_.gif" = { + extraConfig = '' + expires max; + empty_gif; + ''; + }; + "^~ /cache/".extraConfig ='' + deny all; + ''; + "/dumps" = { + root = "/srv/web/wiki-ese/local"; + extraConfig = '' + autoindex on; + ''; + }; + }; + }; + }; +} diff --git a/modules/wiki/fsr.nix b/modules/wiki/fsr.nix new file mode 100644 index 0000000..f8fe604 --- /dev/null +++ b/modules/wiki/fsr.nix @@ -0,0 +1,117 @@ +{ config, pkgs, ... }: +let + domain = "wiki.${config.networking.domain}"; + listenPort = 8080; +in +{ + sops.secrets = { + "mediawiki/initial_admin".owner = config.users.users.mediawiki.name; + "mediawiki/oidc_secret".owner = config.users.users.mediawiki.name; + }; + + systemd.services.mediawiki-init.after = [ "postgresql.service" ]; + services = { + mediawiki = { + enable = true; + passwordFile = config.sops.secrets."mediawiki/initial_admin".path; + database.type = "postgres"; + url = "https://${domain}"; + + httpd.virtualHost = { + adminAddr = "root@ifsr.de"; + listen = [{ + ip = "127.0.0.1"; + port = listenPort; + ssl = false; + }]; + # Short url support (e.g. https://wiki.ifsr.de/Page instead of .../index.php?title=Page) + # Recommended config taken from https://www.mediawiki.org/wiki/Manual:Short_URL/Apache + # See paragraph "If you are using a root url ..." + extraConfig = '' + RewriteEngine On + RewriteCond %{REQUEST_URI} !^/rest\.php + RewriteCond %{REQUEST_URI} !^/images + RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f + RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d + RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/index.php [L] + ''; + }; + + extraConfig = '' + $wgSitename = "FSR Wiki"; + $wgArticlePath = '/$1'; + + $wgLogo = "/images/3/3b/LogoiFSR.png"; + $wgLanguageCode = "de"; + + $wgGroupPermissions['*']['read'] = false; + $wgGroupPermissions['*']['edit'] = false; + $wgGroupPermissions['*']['createaccount'] = false; + $wgGroupPermissions['*']['autocreateaccount'] = true; + $wgGroupPermissions['sysop']['userrights'] = true; + $wgGroupPermissions['sysop']['deletelogentry'] = true; + $wgGroupPermissions['sysop']['deleterevision'] = true; + + $wgEnableAPI = true; + $wgAllowUserCss = true; + $wgUseAjax = true; + $wgEnableMWSuggest = true; + $wgDefaultSkin = 'timeless'; + + //TODO what about $wgUpgradeKey ? + + # Auth + # https://www.mediawiki.org/wiki/Extension:PluggableAuth + # https://www.mediawiki.org/wiki/Extension:OpenID_Connect + $wgPluggableAuth_EnableLocalLogin = true; + $wgPluggableAuth_Config["iFSR Login"] = [ + "plugin" => "OpenIDConnect", + "data" => [ + "providerURL" => "${config.services.portunus.domain}/dex", + "clientID" => "wiki", + "clientsecret" => file_get_contents('${config.sops.secrets."mediawiki/oidc_secret".path}'), + ], + ]; + ''; + + extensions = { + PluggableAuth = pkgs.fetchzip { + url = "https://extdist.wmflabs.org/dist/extensions/PluggableAuth-REL1_40-2d86d50.tar.gz"; + hash = "sha256-NAdjc8pqAjSZrsN2IQ/rESyZYEnesBT0cGg8CrIlvFM="; + }; + OpenIDConnect = pkgs.fetchzip { + url = "https://extdist.wmflabs.org/dist/extensions/OpenIDConnect-REL1_40-e97e0b1.tar.gz"; + hash = "sha256-UrxaszLL3e4PZmTOnGkNliQ8fjGVD37Xj7BjhvhQDJU="; + }; + VisualEditor = pkgs.fetchzip { + url = "https://extdist.wmflabs.org/dist/extensions/VisualEditor-REL1_40-c6aec49.tar.gz"; + hash = "sha256-p66C7ks0ocy5sL7LTkFQuDA3/2uSXdfldUXoOQ6afWM="; + }; + SyntaxHighlight = pkgs.fetchzip { + url = "https://extdist.wmflabs.org/dist/extensions/SyntaxHighlight_GeSHi-REL1_40-ded412b.tar.gz"; + hash = "sha256-mlNrcZhGADqzdLNeck0ATv44W3cTTOykQouHJTaj5cA="; + }; + }; + }; + + portunus.dex.oidcClients = [{ + id = "wiki"; + callbackURL = "https://${domain}/Spezial:PluggableAuthLogin"; + }]; + + nginx = { + recommendedProxySettings = true; + virtualHosts.${domain} = { + enableACME = true; + forceSSL = true; + locations."/" = { + proxyPass = "http://127.0.0.1:${toString listenPort}"; + proxyWebsockets = true; + }; + locations."~ ^/ese(/?[^\\n|\\r]*)$".return = "301 https://wiki.ese.ifsr.de$1"; + locations."~ ^/fsr(/?[^\\n|\\r]*)$".return = "301 https://wiki.ifsr.de$1"; + locations."~ ^/vernetzung(/?[^\\n|\\r]*)$".return = "301 https://vernetzung.ifsr.de$1"; + }; + }; + }; +} diff --git a/modules/wiki/vernetzung.nix b/modules/wiki/vernetzung.nix new file mode 100644 index 0000000..1ce0eef --- /dev/null +++ b/modules/wiki/vernetzung.nix @@ -0,0 +1,85 @@ +{ config, lib, pkgs, ... }: +let + domain = "vernetzung.${config.networking.domain}"; + user = "vernetzung"; + group = "vernetzung"; +in +{ + + users.users.${user} = { + group = group; + isSystemUser = true; + }; + users.groups.${group} = { }; + services.phpfpm.pools.vernetzung = { + user = user; + group = group; + settings = { + "listen.owner" = config.services.nginx.user; + "pm" = "dynamic"; + "pm.max_children" = 32; + "pm.max_requests" = 500; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 2; + "pm.max_spare_servers" = 5; + "php_admin_value[error_log]" = "stderr"; + "php_admin_flag[log_errors]" = true; + "catch_workers_output" = true; + }; + phpEnv."PATH" = lib.makeBinPath [ pkgs.php ]; + }; + services.nginx = { + virtualHosts."${domain}" = { + addSSL = true; + enableACME = true; + root = "/srv/web/vernetzung"; + extraConfig = '' + index index.php; + ''; + locations = { + "/" = { + tryFiles = "$uri $uri/ @rewrite"; + }; + "@rewrite".extraConfig = '' + rewrite ^/(.*)$ /index.php?title=$1&$args; + ''; + "^~ /maintenance/".return = "403"; + "~ \.php$" = { + extraConfig = '' + fastcgi_pass unix:${config.services.phpfpm.pools.vernetzung.socket}; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_index index.php; + include ${pkgs.nginx}/conf/fastcgi_params; + include ${pkgs.nginx}/conf/fastcgi.conf; + fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; + ''; + }; + "/rest.php" = { + tryFiles = "$uri $uri/ /rest.php?$args"; + }; + "~* \.(js|css|png|jpg|jpeg|gif|ico)$" = { + tryFiles = "$uri /index.php"; + extraConfig = '' + expires max; + log_not_found off; + ''; + }; + "/_.gif" = { + extraConfig = '' + expires max; + empty_gif; + ''; + }; + "^~ /cache/".extraConfig ='' + deny all; + ''; + "/dumps" = { + root = "/srv/web/vernetzung/local"; + extraConfig = '' + autoindex on; + ''; + }; + }; + }; + }; +}