From 4288c2f2431fb782b0d512b1b3749187f2374b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Isma=C3=ABl=20Bouya?= Date: Wed, 22 May 2019 20:01:33 +0200 Subject: Move websites/tools to modules --- modules/private/default.nix | 11 + modules/private/websites/aten/integration.nix | 5 +- modules/private/websites/aten/production.nix | 5 +- modules/private/websites/capitaines/production.nix | 5 +- modules/private/websites/chloe/integration.nix | 5 +- modules/private/websites/chloe/production.nix | 5 +- .../websites/connexionswing/integration.nix | 5 +- .../private/websites/connexionswing/production.nix | 5 +- modules/private/websites/default.nix | 274 +++++++++++++++++-- modules/private/websites/emilia/production.nix | 5 +- modules/private/websites/florian/app.nix | 5 +- .../websites/ludivinecassal/integration.nix | 5 +- .../private/websites/ludivinecassal/production.nix | 5 +- .../private/websites/naturaloutil/production.nix | 9 +- .../private/websites/piedsjaloux/integration.nix | 5 +- .../private/websites/piedsjaloux/production.nix | 5 +- modules/private/websites/tools/cloud/default.nix | 188 +++++++++++++ modules/private/websites/tools/dav/davical.nix | 139 ++++++++++ modules/private/websites/tools/dav/default.nix | 53 ++++ modules/private/websites/tools/db/default.nix | 21 ++ .../private/websites/tools/diaspora/default.nix | 181 ++++++++++++ modules/private/websites/tools/ether/default.nix | 175 ++++++++++++ modules/private/websites/tools/git/default.nix | 43 +++ modules/private/websites/tools/git/gitweb.nix | 64 +++++ modules/private/websites/tools/git/mantisbt.nix | 96 +++++++ .../private/websites/tools/mastodon/default.nix | 128 +++++++++ modules/private/websites/tools/mgoblin/default.nix | 122 +++++++++ .../private/websites/tools/peertube/default.nix | 179 ++++++++++++ modules/private/websites/tools/tools/adminer.nix | 47 ++++ modules/private/websites/tools/tools/default.nix | 302 +++++++++++++++++++++ modules/private/websites/tools/tools/dokuwiki.nix | 61 +++++ modules/private/websites/tools/tools/kanboard.nix | 86 ++++++ modules/private/websites/tools/tools/ldap.nix | 74 +++++ modules/private/websites/tools/tools/rainloop.nix | 59 ++++ modules/private/websites/tools/tools/rompr.nix | 77 ++++++ .../private/websites/tools/tools/roundcubemail.nix | 121 +++++++++ modules/private/websites/tools/tools/shaarli.nix | 65 +++++ modules/private/websites/tools/tools/ttrss.nix | 131 +++++++++ modules/private/websites/tools/tools/wallabag.nix | 148 ++++++++++ modules/private/websites/tools/tools/ympd.nix | 40 +++ modules/private/websites/tools/tools/yourls.nix | 93 +++++++ 41 files changed, 2975 insertions(+), 77 deletions(-) create mode 100644 modules/private/websites/tools/cloud/default.nix create mode 100644 modules/private/websites/tools/dav/davical.nix create mode 100644 modules/private/websites/tools/dav/default.nix create mode 100644 modules/private/websites/tools/db/default.nix create mode 100644 modules/private/websites/tools/diaspora/default.nix create mode 100644 modules/private/websites/tools/ether/default.nix create mode 100644 modules/private/websites/tools/git/default.nix create mode 100644 modules/private/websites/tools/git/gitweb.nix create mode 100644 modules/private/websites/tools/git/mantisbt.nix create mode 100644 modules/private/websites/tools/mastodon/default.nix create mode 100644 modules/private/websites/tools/mgoblin/default.nix create mode 100644 modules/private/websites/tools/peertube/default.nix create mode 100644 modules/private/websites/tools/tools/adminer.nix create mode 100644 modules/private/websites/tools/tools/default.nix create mode 100644 modules/private/websites/tools/tools/dokuwiki.nix create mode 100644 modules/private/websites/tools/tools/kanboard.nix create mode 100644 modules/private/websites/tools/tools/ldap.nix create mode 100644 modules/private/websites/tools/tools/rainloop.nix create mode 100644 modules/private/websites/tools/tools/rompr.nix create mode 100644 modules/private/websites/tools/tools/roundcubemail.nix create mode 100644 modules/private/websites/tools/tools/shaarli.nix create mode 100644 modules/private/websites/tools/tools/ttrss.nix create mode 100644 modules/private/websites/tools/tools/wallabag.nix create mode 100644 modules/private/websites/tools/tools/ympd.nix create mode 100644 modules/private/websites/tools/tools/yourls.nix (limited to 'modules') diff --git a/modules/private/default.nix b/modules/private/default.nix index 16258e4..242eeb9 100644 --- a/modules/private/default.nix +++ b/modules/private/default.nix @@ -36,6 +36,17 @@ set = { piedsjalouxInte = ./websites/piedsjaloux/integration.nix; piedsjalouxProd = ./websites/piedsjaloux/production.nix; + cloudTool = ./websites/tools/cloud; + davTool = ./websites/tools/dav; + dbTool = ./websites/tools/db; + diasporaTool = ./websites/tools/diaspora; + etherTool = ./websites/tools/ether; + gitTool = ./websites/tools/git; + mastodonTool = ./websites/tools/mastodon; + mgoblinTool = ./websites/tools/mgoblin; + peertubeTool = ./websites/tools/peertube; + toolsTool = ./websites/tools/tools; + irc = ./irc.nix; }; in diff --git a/modules/private/websites/aten/integration.nix b/modules/private/websites/aten/integration.nix index 5ccc0c1..748e388 100644 --- a/modules/private/websites/aten/integration.nix +++ b/modules/private/websites/aten/integration.nix @@ -18,10 +18,7 @@ in { systemd.services.phpfpm-aten_dev.wants = aten.phpFpm.serviceDeps; services.phpfpm.poolConfigs.aten_dev = aten.phpFpm.pool; system.activationScripts.aten_dev = aten.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${aten.app.webRoot} $out/webapps/${aten.apache.webappName} - ''; + myServices.websites.webappDirs."${aten.apache.webappName}" = aten.app.webRoot; services.websites.integration.modules = aten.apache.modules; services.websites.integration.vhostConfs.aten = { certName = "eldiron"; diff --git a/modules/private/websites/aten/production.nix b/modules/private/websites/aten/production.nix index 7938241..7a4adb5 100644 --- a/modules/private/websites/aten/production.nix +++ b/modules/private/websites/aten/production.nix @@ -20,10 +20,7 @@ in { systemd.services.phpfpm-aten_prod.wants = aten.phpFpm.serviceDeps; services.phpfpm.poolConfigs.aten_prod = aten.phpFpm.pool; system.activationScripts.aten_prod = aten.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${aten.app.webRoot} $out/webapps/${aten.apache.webappName} - ''; + myServices.websites.webappDirs."${aten.apache.webappName}" = aten.app.webRoot; services.websites.production.modules = aten.apache.modules; services.websites.production.vhostConfs.aten = { certName = "aten"; diff --git a/modules/private/websites/capitaines/production.nix b/modules/private/websites/capitaines/production.nix index fe9c619..57d8787 100644 --- a/modules/private/websites/capitaines/production.nix +++ b/modules/private/websites/capitaines/production.nix @@ -9,10 +9,7 @@ in { options.myServices.websites.capitaines.production.enable = lib.mkEnableOption "enable Capitaines's website"; config = lib.mkIf cfg.enable { - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${siteDir} $out/webapps/${webappName} - ''; + myServices.websites.webappDirs."${webappName}" = siteDir; services.websites.production.vhostConfs.capitaines_mastodon = { certName = "capitaines"; diff --git a/modules/private/websites/chloe/integration.nix b/modules/private/websites/chloe/integration.nix index d49a85c..c42a428 100644 --- a/modules/private/websites/chloe/integration.nix +++ b/modules/private/websites/chloe/integration.nix @@ -23,10 +23,7 @@ in { ''; }; system.activationScripts.chloe_dev = chloe.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${chloe.app.webRoot} $out/webapps/${chloe.apache.webappName} - ''; + myServices.websites.webappDirs."${chloe.apache.webappName}" = chloe.app.webRoot; services.websites.integration.modules = chloe.apache.modules; services.websites.integration.vhostConfs.chloe = { certName = "eldiron"; diff --git a/modules/private/websites/chloe/production.nix b/modules/private/websites/chloe/production.nix index d4b2299..0bf2d8f 100644 --- a/modules/private/websites/chloe/production.nix +++ b/modules/private/websites/chloe/production.nix @@ -25,10 +25,7 @@ in { ''; }; system.activationScripts.chloe_prod = chloe.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${chloe.app.webRoot} $out/webapps/${chloe.apache.webappName} - ''; + myServices.websites.webappDirs."${chloe.apache.webappName}" = chloe.app.webRoot; services.websites.production.modules = chloe.apache.modules; services.websites.production.vhostConfs.chloe = { certName = "chloe"; diff --git a/modules/private/websites/connexionswing/integration.nix b/modules/private/websites/connexionswing/integration.nix index 6570977..1d8488a 100644 --- a/modules/private/websites/connexionswing/integration.nix +++ b/modules/private/websites/connexionswing/integration.nix @@ -22,10 +22,7 @@ in { phpOptions = config.services.phpfpm.phpOptions + connexionswing.phpFpm.phpConfig; }; system.activationScripts.connexionswing_dev = connexionswing.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${connexionswing.app.webRoot} $out/webapps/${connexionswing.apache.webappName} - ''; + myServices.websites.webappDirs."${connexionswing.apache.webappName}" = connexionswing.app.webRoot; services.websites.integration.modules = connexionswing.apache.modules; services.websites.integration.vhostConfs.connexionswing = { certName = "eldiron"; diff --git a/modules/private/websites/connexionswing/production.nix b/modules/private/websites/connexionswing/production.nix index b51c549..555f129 100644 --- a/modules/private/websites/connexionswing/production.nix +++ b/modules/private/websites/connexionswing/production.nix @@ -24,10 +24,7 @@ in { phpOptions = config.services.phpfpm.phpOptions + connexionswing.phpFpm.phpConfig; }; system.activationScripts.connexionswing_prod = connexionswing.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${connexionswing.app.webRoot} $out/webapps/${connexionswing.apache.webappName} - ''; + myServices.websites.webappDirs."${connexionswing.apache.webappName}" = connexionswing.app.webRoot; services.websites.production.modules = connexionswing.apache.modules; services.websites.production.vhostConfs.connexionswing = { certName = "connexionswing"; diff --git a/modules/private/websites/default.nix b/modules/private/websites/default.nix index 80d902e..8b02977 100644 --- a/modules/private/websites/default.nix +++ b/modules/private/websites/default.nix @@ -1,39 +1,265 @@ -{ ... }: +{ lib, pkgs, config, myconfig, ... }: +let + www_root = "/run/current-system/webapps/_www"; + theme_root = "/run/current-system/webapps/_theme"; + apacheConfig = { + gzip = { + modules = [ "deflate" "filter" ]; + extraConfig = '' + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript + ''; + }; + macros = { + modules = [ "macro" ]; + }; + stats = { + extraConfig = '' + + Alias /webstats ${config.services.webstats.dataDir}/%{domain} + + DirectoryIndex index.html + AllowOverride None + Require all granted + + + Use LDAPConnect + Require ldap-group cn=%{domain},ou=stats,cn=httpd,ou=services,dc=immae,dc=eu + + + ''; + }; + ldap = { + modules = [ "ldap" "authnz_ldap" ]; + extraConfig = '' + + LDAPSharedCacheSize 500000 + LDAPCacheEntries 1024 + LDAPCacheTTL 600 + LDAPOpCacheEntries 1024 + LDAPOpCacheTTL 600 + + + Include /var/secrets/apache-ldap + ''; + }; + global = { + extraConfig = (pkgs.webapps.apache-default.override { inherit www_root;}).apacheConfig; + }; + apaxy = { + extraConfig = (pkgs.webapps.apache-theme.override { inherit theme_root; }).apacheConfig; + }; + http2 = { + modules = [ "http2" ]; + extraConfig = '' + Protocols h2 http/1.1 + ''; + }; + customLog = { + extraConfig = '' + LogFormat "%v:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedVhost + ''; + }; + }; + makeModules = lib.lists.flatten (lib.attrsets.mapAttrsToList (n: v: v.modules or []) apacheConfig); + makeExtraConfig = (builtins.filter (x: x != null) (lib.attrsets.mapAttrsToList (n: v: v.extraConfig or null) apacheConfig)); +in { - config.myServices.websites.aten.integration.enable = true; - config.myServices.websites.aten.production.enable = true; + options.myServices.websites.webappDirs = lib.mkOption { + type = lib.types.attrsOf lib.types.path; + description = '' + Webapp paths to create in /run/current-system/webapps + ''; + default = {}; + }; + + config = { + users.users.wwwrun.extraGroups = [ "keys" ]; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + + nixpkgs.overlays = [ (self: super: rec { + #openssl = self.openssl_1_1; + php = php72; + php72 = (super.php72.override { + mysql.connector-c = self.mariadb; + config.php.mysqlnd = false; + config.php.mysqli = false; + }).overrideAttrs(old: rec { + # Didn't manage to build with mysqli + mysql_config connector + configureFlags = old.configureFlags ++ [ + "--with-mysqli=shared,mysqlnd" + ]; + # preConfigure = (old.preConfigure or "") + '' + # export CPPFLAGS="$CPPFLAGS -I${pkgs.mariadb}/include/mysql/server"; + # sed -i -e 's/#include "mysqli_priv.h"/#include "mysqli_priv.h"\n#include /' \ + # ext/mysqli/mysqli.c ext/mysqli/mysqli_prop.c + # ''; + }); + phpPackages = super.php72Packages.override { inherit php; }; + }) ]; + + secrets.keys = [{ + dest = "apache-ldap"; + user = "wwwrun"; + group = "wwwrun"; + permissions = "0400"; + text = '' + + + AuthLDAPURL ldap://ldap.immae.eu:389/dc=immae,dc=eu STARTTLS + AuthLDAPBindDN cn=httpd,ou=services,dc=immae,dc=eu + AuthLDAPBindPassword "${myconfig.env.httpd.ldap.password}" + AuthType Basic + AuthName "Authentification requise (Acces LDAP)" + AuthBasicProvider ldap + + + ''; + }]; + + system.activationScripts = { + httpd = '' + install -d -m 0755 ${config.security.acme.directory}/acme-challenge + install -d -m 0750 -o wwwrun -g wwwrun /var/lib/php/sessions + ''; + }; + + services.phpfpm = { + phpPackage = pkgs.php; + phpOptions = '' + session.save_path = "/var/lib/php/sessions" + post_max_size = 20M + ; 15 days (seconds) + session.gc_maxlifetime = 1296000 + ; 30 days (minutes) + session.cache_expire = 43200 + ''; + extraConfig = '' + log_level = notice + ''; + }; + + services.websites.production = { + enable = true; + adminAddr = "httpd@immae.eu"; + httpdName = "Prod"; + ips = + let ips = myconfig.env.servers.eldiron.ips.production; + in [ips.ip4] ++ (ips.ip6 or []); + modules = makeModules; + extraConfig = makeExtraConfig; + fallbackVhost = { + certName = "eldiron"; + hosts = ["eldiron.immae.eu" ]; + root = www_root; + extraConfig = [ "DirectoryIndex index.htm" ]; + }; + }; + + services.websites.integration = { + enable = true; + adminAddr = "httpd@immae.eu"; + httpdName = "Inte"; + ips = + let ips = myconfig.env.servers.eldiron.ips.integration; + in [ips.ip4] ++ (ips.ip6 or []); + modules = makeModules; + extraConfig = makeExtraConfig; + fallbackVhost = { + certName = "eldiron"; + hosts = ["eldiron.immae.eu" ]; + root = www_root; + extraConfig = [ "DirectoryIndex index.htm" ]; + }; + }; + + services.websites.tools = { + enable = true; + adminAddr = "httpd@immae.eu"; + httpdName = "Tools"; + ips = + let ips = myconfig.env.servers.eldiron.ips.main; + in [ips.ip4] ++ (ips.ip6 or []); + modules = makeModules; + extraConfig = makeExtraConfig ++ + [ '' + RedirectMatch ^/licen[cs]es?_et_tip(ping)?$ https://www.immae.eu/licences_et_tip.html + RedirectMatch ^/licen[cs]es?_and_tip(ping)?$ https://www.immae.eu/licenses_and_tipping.html + RedirectMatch ^/licen[cs]es?$ https://www.immae.eu/licenses_and_tipping.html + RedirectMatch ^/tip(ping)?$ https://www.immae.eu/licenses_and_tipping.html + RedirectMatch ^/(mentions|mentions_legales|legal)$ https://www.immae.eu/mentions.html + RedirectMatch ^/CGU$ https://www.immae.eu/CGU + '' + ]; + nosslVhost = { + enable = true; + host = "nossl.immae.eu"; + }; + fallbackVhost = { + certName = "eldiron"; + hosts = ["eldiron.immae.eu" ]; + root = www_root; + extraConfig = [ "DirectoryIndex index.htm" ]; + }; + }; + + system.extraSystemBuilderCmds = lib.mkIf (builtins.length (builtins.attrValues config.myServices.websites.webappDirs) > 0) '' + mkdir -p $out/webapps + ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList (name: path: "ln -s ${path} $out/webapps/${name}") config.myServices.websites.webappDirs)} + ''; + + myServices.websites = { + webappDirs = { + _www = pkgs.webapps.apache-default.www; + _theme = pkgs.webapps.apache-theme.theme; + }; + + aten.integration.enable = true; + aten.production.enable = true; + + capitaines.production.enable = true; - config.myServices.websites.capitaines.production.enable = true; + chloe.integration.enable = true; + chloe.production.enable = true; - config.myServices.websites.chloe.integration.enable = true; - config.myServices.websites.chloe.production.enable = true; + connexionswing.integration.enable = true; + connexionswing.production.enable = true; - config.myServices.websites.connexionswing.integration.enable = true; - config.myServices.websites.connexionswing.production.enable = true; + denisejerome.production.enable = true; - config.myServices.websites.denisejerome.production.enable = true; + emilia.production.enable = true; - config.myServices.websites.emilia.production.enable = true; + florian.app.enable = true; + florian.integration.enable = true; + florian.production.enable = true; - config.myServices.websites.florian.app.enable = true; - config.myServices.websites.florian.integration.enable = true; - config.myServices.websites.florian.production.enable = true; + immae.production.enable = true; + immae.release.enable = true; + immae.temp.enable = true; - config.myServices.websites.immae.production.enable = true; - config.myServices.websites.immae.release.enable = true; - config.myServices.websites.immae.temp.enable = true; + leila.production.enable = true; - config.myServices.websites.leila.production.enable = true; + ludivinecassal.integration.enable = true; + ludivinecassal.production.enable = true; - config.myServices.websites.ludivinecassal.integration.enable = true; - config.myServices.websites.ludivinecassal.production.enable = true; + nassime.production.enable = true; - config.myServices.websites.nassime.production.enable = true; + naturaloutil.production.enable = true; - config.myServices.websites.naturaloutil.production.enable = true; + papa.surveillance.enable = true; - config.myServices.websites.papa.surveillance.enable = true; + piedsjaloux.integration.enable = true; + piedsjaloux.production.enable = true; - config.myServices.websites.piedsjaloux.integration.enable = true; - config.myServices.websites.piedsjaloux.production.enable = true; + tools.cloud.enable = true; + tools.dav.enable = true; + tools.db.enable = true; + tools.diaspora.enable = true; + tools.etherpad-lite.enable = true; + tools.git.enable = true; + tools.mastodon.enable = true; + tools.mediagoblin.enable = true; + tools.peertube.enable = true; + tools.tools.enable = true; + }; + }; } diff --git a/modules/private/websites/emilia/production.nix b/modules/private/websites/emilia/production.nix index 2e705a1..13f008f 100644 --- a/modules/private/websites/emilia/production.nix +++ b/modules/private/websites/emilia/production.nix @@ -46,10 +46,7 @@ in { system.activationScripts.emilia = '' install -m 0755 -o wwwrun -g wwwrun -d ${varDir} ''; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${siteDir} $out/webapps/${webappName} - ''; + myServices.websites.webappDirs."${webappName}" = siteDir; services.websites.production.vhostConfs.emilia = { certName = "emilia"; certMainHost = "saison-photo.org"; diff --git a/modules/private/websites/florian/app.nix b/modules/private/websites/florian/app.nix index 905c66a..3a6d152 100644 --- a/modules/private/websites/florian/app.nix +++ b/modules/private/websites/florian/app.nix @@ -20,10 +20,7 @@ in { systemd.services.phpfpm-tellesflorian_dev.preStart = lib.mkAfter tellesflorian.phpFpm.preStart; services.phpfpm.poolConfigs.tellesflorian_dev = tellesflorian.phpFpm.pool; system.activationScripts.tellesflorian_dev = tellesflorian.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${tellesflorian.app.webRoot} $out/webapps/${tellesflorian.apache.webappName} - ''; + myServices.websites.webappDirs."${tellesflorian.apache.webappName}" = tellesflorian.app.webRoot; services.websites.integration.modules = adminer.apache.modules ++ tellesflorian.apache.modules; services.websites.integration.vhostConfs.tellesflorian = { certName = "eldiron"; diff --git a/modules/private/websites/ludivinecassal/integration.nix b/modules/private/websites/ludivinecassal/integration.nix index a53f1fe..ed0dc9f 100644 --- a/modules/private/websites/ludivinecassal/integration.nix +++ b/modules/private/websites/ludivinecassal/integration.nix @@ -19,10 +19,7 @@ in { systemd.services.phpfpm-ludivinecassal_dev.preStart = lib.mkAfter ludivinecassal.phpFpm.preStart; services.phpfpm.poolConfigs.ludivinecassal_dev = ludivinecassal.phpFpm.pool; system.activationScripts.ludivinecassal_dev = ludivinecassal.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${ludivinecassal.app.webRoot} $out/webapps/${ludivinecassal.apache.webappName} - ''; + myServices.websites.webappDirs."${ludivinecassal.apache.webappName}" = ludivinecassal.app.webRoot; services.websites.integration.modules = ludivinecassal.apache.modules; services.websites.integration.vhostConfs.ludivine = { certName = "eldiron"; diff --git a/modules/private/websites/ludivinecassal/production.nix b/modules/private/websites/ludivinecassal/production.nix index 8fe6812..3df5613 100644 --- a/modules/private/websites/ludivinecassal/production.nix +++ b/modules/private/websites/ludivinecassal/production.nix @@ -20,10 +20,7 @@ in { systemd.services.phpfpm-ludivinecassal_prod.preStart = lib.mkAfter ludivinecassal.phpFpm.preStart; services.phpfpm.poolConfigs.ludivinecassal_prod = ludivinecassal.phpFpm.pool; system.activationScripts.ludivinecassal_prod = ludivinecassal.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${ludivinecassal.app.webRoot} $out/webapps/${ludivinecassal.apache.webappName} - ''; + myServices.websites.webappDirs."${ludivinecassal.apache.webappName}" = ludivinecassal.app.webRoot; services.websites.production.modules = ludivinecassal.apache.modules; services.websites.production.vhostConfs.ludivine = { certName = "ludivinecassal"; diff --git a/modules/private/websites/naturaloutil/production.nix b/modules/private/websites/naturaloutil/production.nix index 2315b30..f59957d 100644 --- a/modules/private/websites/naturaloutil/production.nix +++ b/modules/private/websites/naturaloutil/production.nix @@ -33,6 +33,12 @@ in { ?> ''; }]; + system.activationScripts.naturaloutil = { + deps = [ "httpd" ]; + text = '' + install -m 0755 -o wwwrun -g wwwrun -d /var/lib/php/sessions/naturaloutil + ''; + }; systemd.services.phpfpm-jerome.after = lib.mkAfter [ "mysql.service" ]; systemd.services.phpfpm-jerome.wants = [ "mysql.service" ]; services.phpfpm.pools.jerome = { @@ -48,7 +54,8 @@ in { pm.process_idle_timeout = 60 env[BDD_CONNECT] = "/var/secrets/webapps/prod-naturaloutil" - php_admin_value[open_basedir] = "/var/secrets/webapps/prod-naturaloutil:${varDir}:/tmp" + php_admin_value[open_basedir] = "/var/lib/php/sessions/naturaloutil:/var/secrets/webapps/prod-naturaloutil:${varDir}:/tmp" + php_admin_value[session.save_path] = "/var/lib/php/sessions/naturaloutil" ''; phpOptions = config.services.phpfpm.phpOptions + '' extension=${pkgs.php}/lib/php/extensions/mysqli.so diff --git a/modules/private/websites/piedsjaloux/integration.nix b/modules/private/websites/piedsjaloux/integration.nix index 83b428a..5f574e1 100644 --- a/modules/private/websites/piedsjaloux/integration.nix +++ b/modules/private/websites/piedsjaloux/integration.nix @@ -18,10 +18,7 @@ in { systemd.services.phpfpm-piedsjaloux_dev.preStart = lib.mkAfter piedsjaloux.phpFpm.preStart; services.phpfpm.poolConfigs.piedsjaloux_dev = piedsjaloux.phpFpm.pool; system.activationScripts.piedsjaloux_dev = piedsjaloux.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${piedsjaloux.app.webRoot} $out/webapps/${piedsjaloux.apache.webappName} - ''; + myServices.websites.webappDirs."${piedsjaloux.apache.webappName}" = piedsjaloux.app.webRoot; services.websites.integration.modules = piedsjaloux.apache.modules; services.websites.integration.vhostConfs.piedsjaloux = { certName = "eldiron"; diff --git a/modules/private/websites/piedsjaloux/production.nix b/modules/private/websites/piedsjaloux/production.nix index 0efd56b..e3bd2dd 100644 --- a/modules/private/websites/piedsjaloux/production.nix +++ b/modules/private/websites/piedsjaloux/production.nix @@ -20,10 +20,7 @@ in { systemd.services.phpfpm-piedsjaloux_prod.preStart = lib.mkAfter piedsjaloux.phpFpm.preStart; services.phpfpm.poolConfigs.piedsjaloux_prod = piedsjaloux.phpFpm.pool; system.activationScripts.piedsjaloux_prod = piedsjaloux.activationScript; - system.extraSystemBuilderCmds = '' - mkdir -p $out/webapps - ln -s ${piedsjaloux.app.webRoot} $out/webapps/${piedsjaloux.apache.webappName} - ''; + myServices.websites.webappDirs."${piedsjaloux.apache.webappName}" = piedsjaloux.app.webRoot; services.websites.production.modules = piedsjaloux.apache.modules; services.websites.production.vhostConfs.piedsjaloux = { certName = "piedsjaloux"; diff --git a/modules/private/websites/tools/cloud/default.nix b/modules/private/websites/tools/cloud/default.nix new file mode 100644 index 0000000..ceb8f77 --- /dev/null +++ b/modules/private/websites/tools/cloud/default.nix @@ -0,0 +1,188 @@ +{ lib, pkgs, config, myconfig, ... }: +let + nextcloud = pkgs.webapps.nextcloud.withApps (builtins.attrValues pkgs.webapps.nextcloud-apps); + env = myconfig.env.tools.nextcloud; + varDir = "/var/lib/nextcloud"; + webappName = "tools_nextcloud"; + apacheRoot = "/run/current-system/webapps/${webappName}"; + cfg = config.myServices.websites.tools.cloud; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" ( + [ nextcloud varDir ] + ++ builtins.attrValues pkgs.webapps.nextcloud-apps); + socket = "/var/run/phpfpm/nextcloud.sock"; + phpConfig = '' + extension=${pkgs.phpPackages.redis}/lib/php/extensions/redis.so + extension=${pkgs.phpPackages.apcu}/lib/php/extensions/apcu.so + zend_extension=${pkgs.php}/lib/php/extensions/opcache.so + ''; + pool = '' + user = wwwrun + group = wwwrun + listen.owner = wwwrun + listen.group = wwwrun + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + php_admin_value[output_buffering] = 0 + php_admin_value[max_execution_time] = 1800 + php_admin_value[zend_extension] = "opcache" + ;already enabled by default? + ;php_value[opcache.enable] = 1 + php_value[opcache.enable_cli] = 1 + php_value[opcache.interned_strings_buffer] = 8 + php_value[opcache.max_accelerated_files] = 10000 + php_value[opcache.memory_consumption] = 128 + php_value[opcache.save_comments] = 1 + php_value[opcache.revalidate_freq] = 1 + php_admin_value[memory_limit] = 512M + + php_admin_value[open_basedir] = "/run/wrappers/bin/sendmail:${basedir}:/proc/meminfo:/dev/urandom:/proc/self/fd:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +in { + options.myServices.websites.tools.cloud = { + enable = lib.mkEnableOption "enable cloud website"; + }; + + config = lib.mkIf cfg.enable { + services.websites.tools.modules = [ "proxy_fcgi" ]; + + services.websites.tools.vhostConfs.cloud = { + certName = "eldiron"; + addToCerts = true; + hosts = ["cloud.immae.eu" ]; + root = apacheRoot; + extraConfig = [ + '' + SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 + + AcceptPathInfo On + DirectoryIndex index.php + Options FollowSymlinks + Require all granted + AllowOverride all + + + Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains; preload" + + + CGIPassAuth on + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + + '' + ]; + }; + + secrets.keys = [{ + dest = "webapps/tools-nextcloud"; + user = "wwwrun"; + group = "wwwrun"; + permissions = "0600"; + text = '' + '${env.instance_id}1', + 'datadirectory' => '/var/lib/nextcloud/', + 'passwordsalt' => '${env.password_salt}', + 'debug' => false, + 'dbtype' => 'pgsql', + 'version' => '16.0.0.9', + 'dbname' => '${env.postgresql.database}', + 'dbhost' => '${env.postgresql.socket}', + 'dbtableprefix' => 'oc_', + 'dbuser' => '${env.postgresql.user}', + 'dbpassword' => '${env.postgresql.password}', + 'installed' => true, + 'maxZipInputSize' => 0, + 'allowZipDownload' => true, + 'forcessl' => true, + 'theme' => ${"''"}, + 'maintenance' => false, + 'trusted_domains' => + array ( + 0 => 'cloud.immae.eu', + ), + 'secret' => '${env.secret}', + 'appstoreenabled' => false, + 'appstore.experimental.enabled' => true, + 'loglevel' => 2, + 'trashbin_retention_obligation' => 'auto', + 'htaccess.RewriteBase' => '/', + 'mail_smtpmode' => 'sendmail', + 'mail_smtphost' => '127.0.0.1', + 'mail_smtpname' => ''', + 'mail_smtppassword' => ''', + 'mail_from_address' => 'nextcloud', + 'mail_smtpauth' => false, + 'mail_domain' => 'tools.immae.eu', + 'memcache.local' => '\\OC\\Memcache\\APCu', + 'memcache.locking' => '\\OC\\Memcache\\Redis', + 'filelocking.enabled' => true, + 'redis' => + array ( + 'host' => '${env.redis.socket}', + 'port' => 0, + 'dbindex' => ${env.redis.db_index}, + ), + 'overwrite.cli.url' => 'https://cloud.immae.eu', + 'ldapIgnoreNamingRules' => false, + 'ldapProviderFactory' => '\\OCA\\User_LDAP\\LDAPProviderFactory', + 'has_rebuilt_cache' => true, + ); + ''; + }]; + users.users.root.packages = let + occ = pkgs.writeScriptBin "nextcloud-occ" '' + #! ${pkgs.stdenv.shell} + cd ${nextcloud} + NEXTCLOUD_CONFIG_DIR="${nextcloud}/config" \ + exec \ + sudo -u wwwrun ${pkgs.php}/bin/php \ + -c ${pkgs.php}/etc/php.ini \ + occ $* + ''; + in [ occ ]; + + system.activationScripts.nextcloud = { + deps = [ "secrets" ]; + text = let + confs = lib.attrsets.mapAttrs (n: v: pkgs.writeText "${n}.json" (builtins.toJSON v)) nextcloud.otherConfig; + in + '' + install -m 0755 -o wwwrun -g wwwrun -d ${varDir} + install -m 0750 -o wwwrun -g wwwrun -d ${varDir}/phpSessions + ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList (n: v: + "install -D -m 0644 -o wwwrun -g wwwrun -T ${v} ${varDir}/config/${n}.json" + ) confs)} + install -D -m 0600 -o wwwrun -g wwwrun -T /var/secrets/webapps/tools-nextcloud ${varDir}/config/config.php + ''; + }; + # FIXME: add a warning when config.php changes + system.extraSystemBuilderCmds = '' + mkdir -p $out/webapps + ln -s ${nextcloud} $out/webapps/${webappName} + ''; + + services.phpfpm.pools.nextcloud = { + listen = phpFpm.socket; + extraConfig = phpFpm.pool; + phpOptions = config.services.phpfpm.phpOptions + phpFpm.phpConfig; + }; + + services.cron = { + enable = true; + systemCronJobs = [ + '' + LOCALE_ARCHIVE=/run/current-system/sw/lib/locale/locale-archive + */15 * * * * wwwrun ${pkgs.php}/bin/php -f ${nextcloud}/cron.php + '' + ]; + }; + }; +} diff --git a/modules/private/websites/tools/dav/davical.nix b/modules/private/websites/tools/dav/davical.nix new file mode 100644 index 0000000..98cebee --- /dev/null +++ b/modules/private/websites/tools/dav/davical.nix @@ -0,0 +1,139 @@ +{ stdenv, fetchurl, gettext, writeText, env, awl, davical }: +rec { + activationScript = { + deps = [ "httpd" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d /var/lib/php/sessions/davical + ''; + }; + keys = [{ + dest = "webapps/dav-davical"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + pg_connect[] = "dbname=${env.postgresql.database} user=${env.postgresql.user} host=${env.postgresql.socket} password=${env.postgresql.password}"; + + $c->readonly_webdav_collections = false; + + $c->admin_email ='davical@tools.immae.eu'; + + $c->restrict_setup_to_admin = true; + + $c->collections_always_exist = false; + + $c->external_refresh = 60; + + $c->enable_scheduling = true; + + $c->iMIP = (object) array("send_email" => true); + + $c->authenticate_hook['optional'] = false; + $c->authenticate_hook['call'] = 'LDAP_check'; + $c->authenticate_hook['config'] = array( + 'host' => 'ldap.immae.eu', + 'port' => '389', + 'startTLS' => 'yes', + 'bindDN'=> 'cn=davical,ou=services,dc=immae,dc=eu', + 'passDN'=> '${env.ldap.password}', + 'protocolVersion' => '3', + 'baseDNUsers'=> array('ou=users,dc=immae,dc=eu', 'ou=group_users,dc=immae,dc=eu'), + 'filterUsers' => 'memberOf=cn=users,cn=davical,ou=services,dc=immae,dc=eu', + 'baseDNGroups' => 'ou=groups,dc=immae,dc=eu', + 'filterGroups' => 'memberOf=cn=groups,cn=davical,ou=services,dc=immae,dc=eu', + 'mapping_field' => array( + "username" => "uid", + "fullname" => "cn", + "email" => "mail", + "modified" => "modifyTimestamp", + ), + 'format_updated'=> array('Y' => array(0,4),'m' => array(4,2),'d'=> array(6,2),'H' => array(8,2),'M'=>array(10,2),'S' => array(12,2)), + /** used to set default value for all users, will be overcharged by ldap if defined also in mapping_field **/ + // 'default_value' => array("date_format_type" => "E","locale" => "fr_FR"), + 'group_mapping_field' => array( + "username" => "cn", + "updated" => "modifyTimestamp", + "fullname" => "givenName", + "displayname" => "givenName", + "members" => "memberUid", + "email" => "mail", + ), + ); + + $c->do_not_sync_from_ldap = array('admin' => true); + include('drivers_ldap.php'); + ''; + }]; + webapp = davical.override { davical_config = "/var/secrets/webapps/dav-davical"; }; + webRoot = "${webapp}/htdocs"; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_davical"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /davical "${root}" + Alias /caldav.php "${root}/caldav.php" + + DirectoryIndex index.php index.html + AcceptPathInfo On + AllowOverride None + Require all granted + + + CGIPassAuth on + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + RewriteEngine On + + Header unset Access-Control-Allow-Origin + Header unset Access-Control-Allow-Methods + Header unset Access-Control-Allow-Headers + Header unset Access-Control-Allow-Credentials + Header unset Access-Control-Expose-Headers + + Header always set Access-Control-Allow-Origin "*" + Header always set Access-Control-Allow-Methods "GET,POST,OPTIONS,PROPFIND,PROPPATCH,REPORT,PUT,MOVE,DELETE,LOCK,UNLOCK" + Header always set Access-Control-Allow-Headers "User-Agent,Authorization,Content-type,Depth,If-match,If-None-Match,Lock-Token,Timeout,Destination,Overwrite,Prefer,X-client,X-Requested-With" + Header always set Access-Control-Allow-Credentials false + Header always set Access-Control-Expose-Headers "Etag,Preference-Applied" + + RewriteCond %{HTTP:Access-Control-Request-Method} !^$ + RewriteCond %{REQUEST_METHOD} OPTIONS + RewriteRule ^(.*)$ $1 [R=200,L] + + + ''; + }; + phpFpm = rec { + serviceDeps = [ "postgresql.service" "openldap.service" ]; + basedir = builtins.concatStringsSep ":" [ webapp "/var/secrets/webapps/dav-davical" awl ]; + socket = "/var/run/phpfpm/davical.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = dynamic + pm.max_children = 60 + pm.start_servers = 2 + pm.min_spare_servers = 1 + pm.max_spare_servers = 10 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = DavicalPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp:/var/lib/php/sessions/davical" + php_admin_value[include_path] = "${awl}/inc:${webapp}/inc" + php_admin_value[session.save_path] = "/var/lib/php/sessions/davical" + php_flag[magic_quotes_gpc] = Off + php_flag[register_globals] = Off + php_admin_value[error_reporting] = "E_ALL & ~E_NOTICE" + php_admin_value[default_charset] = "utf-8" + php_flag[magic_quotes_runtime] = Off + ''; + }; +} diff --git a/modules/private/websites/tools/dav/default.nix b/modules/private/websites/tools/dav/default.nix new file mode 100644 index 0000000..fb0baae --- /dev/null +++ b/modules/private/websites/tools/dav/default.nix @@ -0,0 +1,53 @@ +{ lib, pkgs, config, myconfig, ... }: +let + infcloud = rec { + webappName = "tools_infcloud"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /carddavmate ${root} + Alias /caldavzap ${root} + Alias /infcloud ${root} + + AllowOverride All + Options FollowSymlinks + Require all granted + DirectoryIndex index.html + + ''; + }; + davical = pkgs.callPackage ./davical.nix { + env = myconfig.env.tools.davical; + inherit (pkgs.webapps) davical awl; + }; + + cfg = config.myServices.websites.tools.dav; +in { + options.myServices.websites.tools.dav = { + enable = lib.mkEnableOption "enable dav website"; + }; + + config = lib.mkIf cfg.enable { + system.activationScripts.davical = davical.activationScript; + secrets.keys = davical.keys; + services.websites.tools.modules = davical.apache.modules; + + services.websites.tools.vhostConfs.dav = { + certName = "eldiron"; + addToCerts = true; + hosts = ["dav.immae.eu" ]; + root = null; + extraConfig = [ + infcloud.vhostConf + davical.apache.vhostConf + ]; + }; + + services.phpfpm.poolConfigs = { + davical = davical.phpFpm.pool; + }; + + myServices.websites.webappDirs."${davical.apache.webappName}" = davical.webRoot; + myServices.websites.webappDirs."${infcloud.webappName}" = pkgs.webapps.infcloud; + }; +} + diff --git a/modules/private/websites/tools/db/default.nix b/modules/private/websites/tools/db/default.nix new file mode 100644 index 0000000..361e204 --- /dev/null +++ b/modules/private/websites/tools/db/default.nix @@ -0,0 +1,21 @@ +{ lib, pkgs, config, ... }: +let + adminer = pkgs.callPackage ../../commons/adminer.nix {}; + + cfg = config.myServices.websites.tools.db; +in { + options.myServices.websites.tools.db = { + enable = lib.mkEnableOption "enable database's website"; + }; + + config = lib.mkIf cfg.enable { + services.websites.tools.modules = adminer.apache.modules; + services.websites.tools.vhostConfs.db-1 = { + certName = "eldiron"; + addToCerts = true; + hosts = ["db-1.immae.eu" ]; + root = null; + extraConfig = [ adminer.apache.vhostConf ]; + }; + }; +} diff --git a/modules/private/websites/tools/diaspora/default.nix b/modules/private/websites/tools/diaspora/default.nix new file mode 100644 index 0000000..efa1fab --- /dev/null +++ b/modules/private/websites/tools/diaspora/default.nix @@ -0,0 +1,181 @@ +{ lib, pkgs, config, myconfig, ... }: +let + env = myconfig.env.tools.diaspora; + root = "/run/current-system/webapps/tools_diaspora"; + cfg = config.myServices.websites.tools.diaspora; + dcfg = config.services.diaspora; +in { + options.myServices.websites.tools.diaspora = { + enable = lib.mkEnableOption "enable diaspora's website"; + }; + + config = lib.mkIf cfg.enable { + users.users.diaspora.extraGroups = [ "keys" ]; + + secrets.keys = [ + { + dest = "webapps/diaspora/diaspora.yml"; + user = "diaspora"; + group = "diaspora"; + permissions = "0400"; + text = '' + configuration: + environment: + url: "https://diaspora.immae.eu/" + certificate_authorities: '${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt' + redis: '${env.redis_url}' + sidekiq: + s3: + assets: + logging: + logrotate: + debug: + server: + listen: '${dcfg.sockets.rails}' + rails_environment: 'production' + chat: + server: + bosh: + log: + map: + mapbox: + privacy: + piwik: + statistics: + camo: + settings: + enable_registrations: false + welcome_message: + invitations: + open: false + paypal_donations: + community_spotlight: + captcha: + enable: false + terms: + maintenance: + remove_old_users: + default_metas: + csp: + services: + twitter: + tumblr: + wordpress: + mail: + enable: true + sender_address: 'diaspora@tools.immae.eu' + method: 'sendmail' + smtp: + sendmail: + location: '/run/wrappers/bin/sendmail' + admins: + account: "ismael" + podmin_email: 'diaspora@tools.immae.eu' + relay: + outbound: + inbound: + ldap: + enable: true + host: ldap.immae.eu + port: 636 + only_ldap: true + mail_attribute: mail + skip_email_confirmation: true + use_bind_dn: true + bind_dn: "cn=diaspora,ou=services,dc=immae,dc=eu" + bind_pw: "${env.ldap.password}" + search_base: "dc=immae,dc=eu" + search_filter: "(&(memberOf=cn=users,cn=diaspora,ou=services,dc=immae,dc=eu)(uid=%{username}))" + production: + environment: + development: + environment: + ''; + } + { + dest = "webapps/diaspora/database.yml"; + user = "diaspora"; + group = "diaspora"; + permissions = "0400"; + text = '' + postgresql: &postgresql + adapter: postgresql + host: "${env.postgresql.socket}" + port: "${env.postgresql.port}" + username: "${env.postgresql.user}" + password: "${env.postgresql.password}" + encoding: unicode + common: &common + <<: *postgresql + combined: &combined + <<: *common + development: + <<: *combined + database: diaspora_development + production: + <<: *combined + database: ${env.postgresql.database} + test: + <<: *combined + database: "diaspora_test" + integration1: + <<: *combined + database: diaspora_integration1 + integration2: + <<: *combined + database: diaspora_integration2 + ''; + } + { + dest = "webapps/diaspora/secret_token.rb"; + user = "diaspora"; + group = "diaspora"; + permissions = "0400"; + text = '' + Diaspora::Application.config.secret_key_base = '${env.secret_token}' + ''; + } + ]; + + services.diaspora = { + enable = true; + package = pkgs.webapps.diaspora.override { ldap = true; }; + dataDir = "/var/lib/diaspora_immae"; + adminEmail = "diaspora@tools.immae.eu"; + configDir = "/var/secrets/webapps/diaspora"; + }; + + services.websites.tools.modules = [ + "headers" "proxy" "proxy_http" + ]; + system.extraSystemBuilderCmds = '' + mkdir -p $out/webapps + ln -s ${dcfg.workdir}/public/ $out/webapps/tools_diaspora + ''; + services.websites.tools.vhostConfs.diaspora = { + certName = "eldiron"; + addToCerts = true; + hosts = [ "diaspora.immae.eu" ]; + root = root; + extraConfig = [ '' + RewriteEngine On + RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f + RewriteRule ^/(.*)$ unix://${dcfg.sockets.rails}|http://diaspora.immae.eu/%{REQUEST_URI} [P,NE,QSA,L] + + ProxyRequests Off + ProxyVia On + ProxyPreserveHost On + RequestHeader set X_FORWARDED_PROTO https + + + Require all granted + + + + Require all granted + Options -MultiViews + + '' ]; + }; + }; +} diff --git a/modules/private/websites/tools/ether/default.nix b/modules/private/websites/tools/ether/default.nix new file mode 100644 index 0000000..ebcbf61 --- /dev/null +++ b/modules/private/websites/tools/ether/default.nix @@ -0,0 +1,175 @@ +{ lib, pkgs, config, myconfig, ... }: +let + env = myconfig.env.tools.etherpad-lite; + cfg = config.myServices.websites.tools.etherpad-lite; + # Make sure we’re not rebuilding whole libreoffice just because of a + # dependency + libreoffice = (import { overlays = []; }).libreoffice-fresh; + ecfg = config.services.etherpad-lite; +in { + options.myServices.websites.tools.etherpad-lite = { + enable = lib.mkEnableOption "enable etherpad's website"; + }; + + config = lib.mkIf cfg.enable { + secrets.keys = [ + { + dest = "webapps/tools-etherpad-apikey"; + permissions = "0400"; + text = env.api_key; + } + { + dest = "webapps/tools-etherpad-sessionkey"; + permissions = "0400"; + text = env.session_key; + } + { + dest = "webapps/tools-etherpad"; + permissions = "0400"; + text = '' + { + "title": "Etherpad", + "favicon": "favicon.ico", + + "ip": "", + "port" : "${ecfg.sockets.node}", + "showSettingsInAdminPage" : false, + "dbType" : "postgres", + "dbSettings" : { + "user" : "${env.postgresql.user}", + "host" : "${env.postgresql.socket}", + "password": "${env.postgresql.password}", + "database": "${env.postgresql.database}", + "charset" : "utf8mb4" + }, + + "defaultPadText" : "Welcome to Etherpad!\n\nThis pad text is synchronized as you type, so that everyone viewing this page sees the same text. This allows you to collaborate seamlessly on documents!\n\nGet involved with Etherpad at http:\/\/etherpad.org\n", + "padOptions": { + "noColors": false, + "showControls": true, + "showChat": true, + "showLineNumbers": true, + "useMonospaceFont": false, + "userName": false, + "userColor": false, + "rtl": false, + "alwaysShowChat": false, + "chatAndUsers": false, + "lang": "en-gb" + }, + + "suppressErrorsInPadText" : false, + "requireSession" : false, + "editOnly" : false, + "sessionNoPassword" : false, + "minify" : true, + "maxAge" : 21600, + "abiword" : null, + "soffice" : "${libreoffice}/bin/soffice", + "tidyHtml" : "${pkgs.html-tidy}/bin/tidy", + "allowUnknownFileEnds" : true, + "requireAuthentication" : false, + "requireAuthorization" : false, + "trustProxy" : false, + "disableIPlogging" : false, + "automaticReconnectionTimeout" : 0, + "scrollWhenFocusLineIsOutOfViewport": { + "percentage": { + "editionAboveViewport": 0, + "editionBelowViewport": 0 + }, + "duration": 0, + "scrollWhenCaretIsInTheLastLineOfViewport": false, + "percentageToScrollWhenUserPressesArrowUp": 0 + }, + "users": { + "ldapauth": { + "url": "ldaps://${env.ldap.host}", + "accountBase": "${env.ldap.base}", + "accountPattern": "(&(memberOf=cn=users,cn=etherpad,ou=services,dc=immae,dc=eu)(uid={{username}}))", + "displayNameAttribute": "cn", + "searchDN": "cn=etherpad,ou=services,dc=immae,dc=eu", + "searchPWD": "${env.ldap.password}", + "groupSearchBase": "${env.ldap.base}", + "groupAttribute": "member", + "groupAttributeIsDN": true, + "searchScope": "sub", + "groupSearch": "(memberOf=cn=groups,cn=etherpad,ou=services,dc=immae,dc=eu)", + "anonymousReadonly": false + } + }, + "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], + "loadTest": false, + "indentationOnNewLine": false, + "toolbar": { + "left": [ + ["bold", "italic", "underline", "strikethrough"], + ["orderedlist", "unorderedlist", "indent", "outdent"], + ["undo", "redo"], + ["clearauthorship"] + ], + "right": [ + ["importexport", "timeslider", "savedrevision"], + ["settings", "embed"], + ["showusers"] + ], + "timeslider": [ + ["timeslider_export", "timeslider_returnToPad"] + ] + }, + "loglevel": "INFO", + "logconfig" : { "appenders": [ { "type": "console" } ] } + } + ''; + } + ]; + services.etherpad-lite = { + enable = true; + modules = builtins.attrValues pkgs.webapps.etherpad-lite-modules; + sessionKeyFile = "/var/secrets/webapps/tools-etherpad-sessionkey"; + apiKeyFile = "/var/secrets/webapps/tools-etherpad-apikey"; + configFile = "/var/secrets/webapps/tools-etherpad"; + }; + + systemd.services.etherpad-lite.serviceConfig.SupplementaryGroups = "keys"; + + services.websites.tools.modules = [ + "headers" "proxy" "proxy_http" "proxy_wstunnel" + ]; + services.websites.tools.vhostConfs.etherpad-lite = { + certName = "eldiron"; + addToCerts = true; + hosts = [ "ether.immae.eu" ]; + root = null; + extraConfig = [ '' + Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;" + RequestHeader set X-Forwarded-Proto "https" + + RewriteEngine On + + RewriteMap redirects "txt:${pkgs.writeText "redirects.txt" myconfig.env.tools.etherpad-lite.redirects}" + RewriteCond %{QUERY_STRING} "!noredirect" + RewriteCond %{REQUEST_URI} "^(.*)$" + RewriteCond ''${redirects:$1|Unknown} "!Unknown" + RewriteRule "^(.*)$" ''${redirects:$1} [L,NE,R=301,QSD] + + RewriteCond %{REQUEST_URI} ^/socket.io [NC] + RewriteCond %{QUERY_STRING} transport=websocket [NC] + RewriteRule /(.*) unix://${ecfg.sockets.node}|ws://ether.immae.eu/$1 [P,NE,QSA,L] + + + ProxyVia On + ProxyRequests Off + ProxyPreserveHost On + ProxyPass / unix://${ecfg.sockets.node}|http://ether.immae.eu/ + ProxyPassReverse / unix://${ecfg.sockets.node}|http://ether.immae.eu/ + + Options FollowSymLinks MultiViews + AllowOverride None + Require all granted + + + '' ]; + }; + }; +} diff --git a/modules/private/websites/tools/git/default.nix b/modules/private/websites/tools/git/default.nix new file mode 100644 index 0000000..3e8b605 --- /dev/null +++ b/modules/private/websites/tools/git/default.nix @@ -0,0 +1,43 @@ +{ lib, pkgs, config, myconfig, ... }: +let + mantisbt = pkgs.callPackage ./mantisbt.nix { + inherit (pkgs.webapps) mantisbt_2 mantisbt_2-plugins; + env = myconfig.env.tools.mantisbt; + }; + gitweb = pkgs.callPackage ./gitweb.nix { gitoliteDir = config.services.myGitolite.gitoliteDir; }; + + cfg = config.myServices.websites.tools.git; +in { + options.myServices.websites.tools.git = { + enable = lib.mkEnableOption "enable git's website"; + }; + + config = lib.mkIf cfg.enable { + secrets.keys = mantisbt.keys; + services.websites.tools.modules = + gitweb.apache.modules ++ + mantisbt.apache.modules; + myServices.websites.webappDirs."${gitweb.apache.webappName}" = gitweb.webRoot; + myServices.websites.webappDirs."${mantisbt.apache.webappName}" = mantisbt.webRoot; + + system.activationScripts.mantisbt = mantisbt.activationScript; + services.websites.tools.vhostConfs.git = { + certName = "eldiron"; + addToCerts = true; + hosts = ["git.immae.eu" ]; + root = gitweb.apache.root; + extraConfig = [ + gitweb.apache.vhostConf + mantisbt.apache.vhostConf + '' + RewriteEngine on + RewriteCond %{REQUEST_URI} ^/releases + RewriteRule /releases(.*) https://release.immae.eu$1 [P,L] + '' + ]; + }; + services.phpfpm.poolConfigs = { + mantisbt = mantisbt.phpFpm.pool; + }; + }; +} diff --git a/modules/private/websites/tools/git/gitweb.nix b/modules/private/websites/tools/git/gitweb.nix new file mode 100644 index 0000000..2ee7a63 --- /dev/null +++ b/modules/private/websites/tools/git/gitweb.nix @@ -0,0 +1,64 @@ +{ gitweb, writeText, gitolite, git, gitoliteDir, highlight }: +rec { + varDir = gitoliteDir; + webRoot = gitweb; + config = writeText "gitweb.conf" '' + $git_temp = "/tmp"; + + # The directories where your projects are. Must not end with a + # slash. + $projectroot = "${varDir}/repositories"; + + $projects_list = "${varDir}/projects.list"; + $strict_export = "true"; + + # Base URLs for links displayed in the web interface. + our @git_base_url_list = qw(ssh://gitolite@git.immae.eu https://git.immae.eu); + + $feature{'blame'}{'default'} = [1]; + $feature{'avatar'}{'default'} = ['gravatar']; + $feature{'highlight'}{'default'} = [1]; + + @stylesheets = ("gitweb-theme/gitweb.css"); + $logo = "gitweb-theme/git-logo.png"; + $favicon = "gitweb-theme/git-favicon.png"; + $javascript = "gitweb-theme/gitweb.js"; + $logo_url = "https://git.immae.eu/"; + $projects_list_group_categories = "true"; + $projects_list_description_width = 60; + $project_list_default_category = "__Others__"; + $highlight_bin = "${highlight}/bin/highlight"; + ''; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "cgid" ]; + webappName = "tools_gitweb"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + SetEnv GIT_PROJECT_ROOT ${varDir}/repositories/ + ScriptAliasMatch \ + "(?x)^/(.*/(HEAD | \ + info/refs | \ + objects/(info/[^/]+ | \ + [0-9a-f]{2}/[0-9a-f]{38} | \ + pack/pack-[0-9a-f]{40}\.(pack|idx)) | \ + git-(upload|receive)-pack))$" \ + ${git}/libexec/git-core/git-http-backend/$1 + + + Require all granted + + + DirectoryIndex gitweb.cgi + Require all granted + AllowOverride None + Options ExecCGI FollowSymLinks + + SetHandler cgi-script + SetEnv GITWEB_CONFIG "${config}" + + + ''; + }; +} diff --git a/modules/private/websites/tools/git/mantisbt.nix b/modules/private/websites/tools/git/mantisbt.nix new file mode 100644 index 0000000..a1b830e --- /dev/null +++ b/modules/private/websites/tools/git/mantisbt.nix @@ -0,0 +1,96 @@ +{ env, mantisbt_2, mantisbt_2-plugins }: +rec { + activationScript = { + deps = [ "httpd" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d /var/lib/php/sessions/mantisbt + ''; + }; + keys = [{ + dest = "webapps/tools-mantisbt"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride All + Options FollowSymlinks + Require all granted + + + #Reenable during upgrade + Require all denied + + ''; + }; + phpFpm = rec { + serviceDeps = [ "postgresql.service" "openldap.service" ]; + basedir = builtins.concatStringsSep ":" ( + [ webRoot "/var/secrets/webapps/tools-mantisbt" ] + ++ webRoot.plugins); + socket = "/var/run/phpfpm/mantisbt.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + php_admin_value[upload_max_filesize] = 5000000 + + php_admin_value[open_basedir] = "${basedir}:/tmp:/var/lib/php/sessions/mantisbt" + php_admin_value[session.save_path] = "/var/lib/php/sessions/mantisbt" + ''; + }; +} diff --git a/modules/private/websites/tools/mastodon/default.nix b/modules/private/websites/tools/mastodon/default.nix new file mode 100644 index 0000000..d742a33 --- /dev/null +++ b/modules/private/websites/tools/mastodon/default.nix @@ -0,0 +1,128 @@ +{ lib, pkgs, config, myconfig, ... }: +let + env = myconfig.env.tools.mastodon; + root = "/run/current-system/webapps/tools_mastodon"; + cfg = config.myServices.websites.tools.mastodon; + mcfg = config.services.mastodon; +in { + options.myServices.websites.tools.mastodon = { + enable = lib.mkEnableOption "enable mastodon's website"; + }; + + config = lib.mkIf cfg.enable { + secrets.keys = [{ + dest = "webapps/tools-mastodon"; + user = "mastodon"; + group = "mastodon"; + permissions = "0400"; + text = '' + REDIS_HOST=${env.redis.host} + REDIS_PORT=${env.redis.port} + REDIS_DB=${env.redis.db} + DB_HOST=${env.postgresql.socket} + DB_USER=${env.postgresql.user} + DB_NAME=${env.postgresql.database} + DB_PASS=${env.postgresql.password} + DB_PORT=${env.postgresql.port} + + LOCAL_DOMAIN=mastodon.immae.eu + LOCAL_HTTPS=true + ALTERNATE_DOMAINS=immae.eu + + PAPERCLIP_SECRET=${env.paperclip_secret} + SECRET_KEY_BASE=${env.secret_key_base} + OTP_SECRET=${env.otp_secret} + + VAPID_PRIVATE_KEY=${env.vapid.private} + VAPID_PUBLIC_KEY=${env.vapid.public} + + SMTP_DELIVERY_METHOD=sendmail + SMTP_FROM_ADDRESS=mastodon@tools.immae.eu + SENDMAIL_LOCATION="/run/wrappers/bin/sendmail" + PAPERCLIP_ROOT_PATH=${mcfg.dataDir} + + STREAMING_CLUSTER_NUM=1 + + RAILS_LOG_LEVEL=warn + + # LDAP authentication (optional) + LDAP_ENABLED=true + LDAP_HOST=ldap.immae.eu + LDAP_PORT=636 + LDAP_METHOD=simple_tls + LDAP_BASE="dc=immae,dc=eu" + LDAP_BIND_DN="cn=mastodon,ou=services,dc=immae,dc=eu" + LDAP_PASSWORD="${env.ldap.password}" + LDAP_UID="uid" + LDAP_SEARCH_FILTER="(&(%{uid}=%{email})(memberOf=cn=users,cn=mastodon,ou=services,dc=immae,dc=eu))" + ''; + }]; + services.mastodon = { + enable = true; + configFile = "/var/secrets/webapps/tools-mastodon"; + socketsPrefix = "live_immae"; + dataDir = "/var/lib/mastodon_immae"; + }; + + services.websites.tools.modules = [ + "headers" "proxy" "proxy_wstunnel" "proxy_http" + ]; + system.extraSystemBuilderCmds = '' + mkdir -p $out/webapps + ln -s ${mcfg.workdir}/public/ $out/webapps/tools_mastodon + ''; + services.websites.tools.vhostConfs.mastodon = { + certName = "eldiron"; + addToCerts = true; + hosts = ["mastodon.immae.eu" ]; + root = root; + extraConfig = [ '' + Header always set Referrer-Policy "strict-origin-when-cross-origin" + Header always set Strict-Transport-Security "max-age=31536000" + + + Header always set Cache-Control "public, max-age=31536000, immutable" + Require all granted + + + ProxyPreserveHost On + RequestHeader set X-Forwarded-Proto "https" + + RewriteEngine On + + ProxyPass /500.html ! + ProxyPass /sw.js ! + ProxyPass /embed.js ! + ProxyPass /robots.txt ! + ProxyPass /manifest.json ! + ProxyPass /browserconfig.xml ! + ProxyPass /mask-icon.svg ! + ProxyPassMatch ^(/.*\.(png|ico|gif)$) ! + ProxyPassMatch ^/(assets|avatars|emoji|headers|packs|sounds|system|.well-known/acme-challenge) ! + + RewriteRule ^/api/v1/streaming/(.+)$ unix://${mcfg.sockets.node}|http://mastodon.immae.eu/api/v1/streaming/$1 [P,NE,QSA,L] + RewriteRule ^/api/v1/streaming/$ unix://${mcfg.sockets.node}|ws://mastodon.immae.eu/ [P,NE,QSA,L] + ProxyPass / unix://${mcfg.sockets.rails}|http://mastodon.immae.eu/ + ProxyPassReverse / unix://${mcfg.sockets.rails}|http://mastodon.immae.eu/ + + Alias /system ${mcfg.dataDir} + + + Require all granted + Options -MultiViews + + + + Require all granted + Options -MultiViews +FollowSymlinks + + + ErrorDocument 500 /500.html + ErrorDocument 501 /500.html + ErrorDocument 502 /500.html + ErrorDocument 503 /500.html + ErrorDocument 504 /500.html + '' ]; + }; + }; +} diff --git a/modules/private/websites/tools/mgoblin/default.nix b/modules/private/websites/tools/mgoblin/default.nix new file mode 100644 index 0000000..5da81f6 --- /dev/null +++ b/modules/private/websites/tools/mgoblin/default.nix @@ -0,0 +1,122 @@ +{ lib, pkgs, config, myconfig, ... }: +let + env = myconfig.env.tools.mediagoblin; + cfg = config.myServices.websites.tools.mediagoblin; + mcfg = config.services.mediagoblin; +in { + options.myServices.websites.tools.mediagoblin = { + enable = lib.mkEnableOption "enable mediagoblin's website"; + }; + + config = lib.mkIf cfg.enable { + secrets.keys = [{ + dest = "webapps/tools-mediagoblin"; + user = "mediagoblin"; + group = "mediagoblin"; + permissions = "0400"; + text = '' + [DEFAULT] + data_basedir = "${mcfg.dataDir}" + + [mediagoblin] + direct_remote_path = /mgoblin_static/ + email_sender_address = "mediagoblin@tools.immae.eu" + + #sql_engine = sqlite:///%(data_basedir)s/mediagoblin.db + sql_engine = ${env.psql_url} + + email_debug_mode = false + allow_registration = false + allow_reporting = true + + theme = airymodified + + user_privilege_scheme = "uploader,commenter,reporter" + + # We need to redefine them here since we override data_basedir + # cf /usr/share/webapps/mediagoblin/mediagoblin/config_spec.ini + workbench_path = %(data_basedir)s/media/workbench + crypto_path = %(data_basedir)s/crypto + theme_install_dir = %(data_basedir)s/themes/ + theme_linked_assets_dir = %(data_basedir)s/theme_static/ + plugin_linked_assets_dir = %(data_basedir)s/plugin_static/ + + [storage:queuestore] + base_dir = %(data_basedir)s/media/queue + + [storage:publicstore] + base_dir = %(data_basedir)s/media/public + base_url = /mgoblin_media/ + + [celery] + CELERY_RESULT_DBURI = ${env.redis_url} + BROKER_URL = ${env.redis_url} + CELERYD_CONCURRENCY = 1 + + [plugins] + [[mediagoblin.plugins.geolocation]] + [[mediagoblin.plugins.ldap]] + [[[immae.eu]]] + LDAP_SERVER_URI = 'ldaps://ldap.immae.eu:636' + LDAP_SEARCH_BASE = 'dc=immae,dc=eu' + LDAP_BIND_DN = 'cn=mediagoblin,ou=services,dc=immae,dc=eu' + LDAP_BIND_PW = '${env.ldap.password}' + LDAP_SEARCH_FILTER = '(&(memberOf=cn=users,cn=mediagoblin,ou=services,dc=immae,dc=eu)(uid={username}))' + EMAIL_SEARCH_FIELD = 'mail' + [[mediagoblin.plugins.basicsearch]] + [[mediagoblin.plugins.piwigo]] + [[mediagoblin.plugins.processing_info]] + [[mediagoblin.media_types.image]] + [[mediagoblin.media_types.video]] + ''; + }]; + + users.users.mediagoblin.extraGroups = [ "keys" ]; + + services.mediagoblin = { + enable = true; + plugins = builtins.attrValues pkgs.webapps.mediagoblin-plugins; + configFile = "/var/secrets/webapps/tools-mediagoblin"; + }; + + services.websites.tools.modules = [ + "proxy" "proxy_http" + ]; + users.users.wwwrun.extraGroups = [ "mediagoblin" ]; + services.websites.tools.vhostConfs.mgoblin = { + certName = "eldiron"; + addToCerts = true; + hosts = ["mgoblin.immae.eu" ]; + root = null; + extraConfig = [ '' + Alias /mgoblin_media ${mcfg.dataDir}/media/public + + Options -Indexes +FollowSymLinks +MultiViews +Includes + Require all granted + + + Alias /theme_static ${mcfg.dataDir}/theme_static + + Options -Indexes +FollowSymLinks +MultiViews +Includes + Require all granted + + + Alias /plugin_static ${mcfg.dataDir}/plugin_static + + Options -Indexes +FollowSymLinks +MultiViews +Includes + Require all granted + + + ProxyPreserveHost on + ProxyVia On + ProxyRequests Off + ProxyPass /mgoblin_media ! + ProxyPass /theme_static ! + ProxyPass /plugin_static ! + ProxyPassMatch ^/.well-known/acme-challenge ! + ProxyPass / unix://${mcfg.sockets.paster}|http://mgoblin.immae.eu/ + ProxyPassReverse / unix://${mcfg.sockets.paster}|http://mgoblin.immae.eu/ + '' ]; + }; + }; +} diff --git a/modules/private/websites/tools/peertube/default.nix b/modules/private/websites/tools/peertube/default.nix new file mode 100644 index 0000000..dee1b81 --- /dev/null +++ b/modules/private/websites/tools/peertube/default.nix @@ -0,0 +1,179 @@ +{ lib, pkgs, config, myconfig, ... }: +let + env = myconfig.env.tools.peertube; + cfg = config.myServices.websites.tools.peertube; + pcfg = config.services.peertube; +in { + options.myServices.websites.tools.peertube = { + enable = lib.mkEnableOption "enable Peertube's website"; + }; + + config = lib.mkIf cfg.enable { + services.peertube = { + enable = true; + configFile = "/var/secrets/webapps/tools-peertube"; + package = pkgs.webapps.peertube.override { ldap = true; }; + }; + users.users.peertube.extraGroups = [ "keys" ]; + + secrets.keys = [{ + dest = "webapps/tools-peertube"; + user = "peertube"; + group = "peertube"; + permissions = "0640"; + text = '' + listen: + hostname: 'localhost' + port: ${env.listenPort} + webserver: + https: true + hostname: 'peertube.immae.eu' + port: 443 + trust_proxy: + - 'loopback' + database: + hostname: '${env.postgresql.socket}' + port: 5432 + suffix: '_prod' + username: '${env.postgresql.user}' + password: '${env.postgresql.password}' + pool: + max: 5 + redis: + socket: '${env.redis.socket}' + auth: null + db: ${env.redis.db_index} + ldap: + enable: true + ldap_only: false + url: ldaps://${env.ldap.host}/${env.ldap.base} + bind_dn: ${env.ldap.dn} + bind_password: ${env.ldap.password} + base: ${env.ldap.base} + mail_entry: "mail" + user_filter: "${env.ldap.filter}" + smtp: + transport: sendmail + sendmail: '/run/wrappers/bin/sendmail' + hostname: null + port: 465 # If you use StartTLS: 587 + username: null + password: null + tls: true # If you use StartTLS: false + disable_starttls: false + ca_file: null # Used for self signed certificates + from_address: 'peertube@tools.immae.eu' + storage: + tmp: '${pcfg.dataDir}/storage/tmp/' + avatars: '${pcfg.dataDir}/storage/avatars/' + videos: '${pcfg.dataDir}/storage/videos/' + redundancy: '${pcfg.dataDir}/storage/videos/' + logs: '${pcfg.dataDir}/storage/logs/' + previews: '${pcfg.dataDir}/storage/previews/' + thumbnails: '${pcfg.dataDir}/storage/thumbnails/' + torrents: '${pcfg.dataDir}/storage/torrents/' + captions: '${pcfg.dataDir}/storage/captions/' + cache: '${pcfg.dataDir}/storage/cache/' + log: + level: 'info' + search: + remote_uri: + users: true + anonymous: false + trending: + videos: + interval_days: 7 + redundancy: + videos: + check_interval: '1 hour' # How often you want to check new videos to cache + strategies: # Just uncomment strategies you want + # Following are saved in local-production.json + cache: + previews: + size: 500 # Max number of previews you want to cache + captions: + size: 500 # Max number of video captions/subtitles you want to cache + admin: + email: 'peertube@tools.immae.eu' + contact_form: + enabled: true + signup: + enabled: false + limit: 10 + requires_email_verification: false + filters: + cidr: + whitelist: [] + blacklist: [] + user: + video_quota: -1 + video_quota_daily: -1 + transcoding: + enabled: false + allow_additional_extensions: true + threads: 1 + resolutions: + 240p: false + 360p: false + 480p: true + 720p: true + 1080p: true + hls: + enabled: false + import: + videos: + http: + enabled: true + torrent: + enabled: false + instance: + name: 'Immae’s PeerTube' + short_description: 'PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.' + description: ''' + terms: ''' + default_client_route: '/videos/trending' + default_nsfw_policy: 'blur' + customizations: + javascript: ''' + css: ''' + robots: | + User-agent: * + Disallow: + securitytxt: + "# If you would like to report a security issue\n# you may report it to:\nContact: https://github.com/Chocobozzz/PeerTube/blob/develop/SECURITY.md\nContact: mailto:" + services: + # You can provide a reporting endpoint for Content Security Policy violations + csp-logger: + twitter: + username: '@_immae' + whitelisted: false + ''; + }]; + + services.websites.tools.modules = [ + "headers" "proxy" "proxy_http" "proxy_wstunnel" + ]; + services.websites.tools.vhostConfs.peertube = { + certName = "eldiron"; + addToCerts = true; + hosts = [ "peertube.immae.eu" ]; + root = null; + extraConfig = [ '' + RewriteEngine On + + RewriteCond %{REQUEST_URI} ^/socket.io [NC] + RewriteCond %{QUERY_STRING} transport=websocket [NC] + RewriteRule /(.*) ws://localhost:${env.listenPort}/$1 [P,NE,QSA,L] + + RewriteCond %{REQUEST_URI} ^/tracker/socket [NC] + RewriteRule /(.*) ws://localhost:${env.listenPort}/$1 [P,NE,QSA,L] + + ProxyPass / http://localhost:${env.listenPort}/ + ProxyPassReverse / http://localhost:${env.listenPort}/ + + ProxyPreserveHost On + RequestHeader set X-Real-IP %{REMOTE_ADDR}s + '' ]; + }; + }; +} diff --git a/modules/private/websites/tools/tools/adminer.nix b/modules/private/websites/tools/tools/adminer.nix new file mode 100644 index 0000000..cd51e7f --- /dev/null +++ b/modules/private/websites/tools/tools/adminer.nix @@ -0,0 +1,47 @@ +{ adminer }: +rec { + activationScript = { + deps = [ "httpd" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d /var/lib/php/sessions/adminer + install -m 0755 -o ${apache.user} -g ${apache.group} -d /var/lib/php/tmp/adminer + ''; + }; + webRoot = adminer; + phpFpm = rec { + socket = "/var/run/phpfpm/adminer.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 5 + pm.process_idle_timeout = 60 + ;php_admin_flag[log_errors] = on + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = AdminerPHPSESSID + php_admin_value[open_basedir] = "${webRoot}:/tmp:/var/lib/php/sessions/adminer:/var/lib/php/tmp/adminer" + php_admin_value[session.save_path] = "/var/lib/php/sessions/adminer" + php_admin_value[upload_tmp_dir] = "/var/lib/php/tmp/adminer" + ''; + }; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "_adminer"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /adminer ${root} + + DirectoryIndex index.php + Require all granted + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + ''; + }; +} diff --git a/modules/private/websites/tools/tools/default.nix b/modules/private/websites/tools/tools/default.nix new file mode 100644 index 0000000..94a2be1 --- /dev/null +++ b/modules/private/websites/tools/tools/default.nix @@ -0,0 +1,302 @@ +{ lib, pkgs, config, myconfig, ... }: +let + adminer = pkgs.callPackage ./adminer.nix { + inherit (pkgs.webapps) adminer; + }; + ympd = pkgs.callPackage ./ympd.nix { + env = myconfig.env.tools.ympd; + }; + ttrss = pkgs.callPackage ./ttrss.nix { + inherit (pkgs.webapps) ttrss ttrss-plugins; + env = myconfig.env.tools.ttrss; + }; + roundcubemail = pkgs.callPackage ./roundcubemail.nix { + inherit (pkgs.webapps) roundcubemail roundcubemail-plugins roundcubemail-skins; + env = myconfig.env.tools.roundcubemail; + }; + rainloop = pkgs.callPackage ./rainloop.nix {}; + kanboard = pkgs.callPackage ./kanboard.nix { + env = myconfig.env.tools.kanboard; + }; + wallabag = pkgs.callPackage ./wallabag.nix { + inherit (pkgs.webapps) wallabag; + env = myconfig.env.tools.wallabag; + }; + yourls = pkgs.callPackage ./yourls.nix { + inherit (pkgs.webapps) yourls yourls-plugins; + env = myconfig.env.tools.yourls; + }; + rompr = pkgs.callPackage ./rompr.nix { + inherit (pkgs.webapps) rompr; + env = myconfig.env.tools.rompr; + }; + shaarli = pkgs.callPackage ./shaarli.nix { + env = myconfig.env.tools.shaarli; + }; + dokuwiki = pkgs.callPackage ./dokuwiki.nix { + inherit (pkgs.webapps) dokuwiki dokuwiki-plugins; + }; + ldap = pkgs.callPackage ./ldap.nix { + inherit (pkgs.webapps) phpldapadmin; + env = myconfig.env.tools.phpldapadmin; + }; + + cfg = config.myServices.websites.tools.tools; +in { + options.myServices.websites.tools.tools = { + enable = lib.mkEnableOption "enable tools website"; + }; + + config = lib.mkIf cfg.enable { + secrets.keys = + kanboard.keys + ++ ldap.keys + ++ roundcubemail.keys + ++ shaarli.keys + ++ ttrss.keys + ++ wallabag.keys + ++ yourls.keys; + + services.websites.integration.modules = + rainloop.apache.modules; + + services.websites.tools.modules = + [ "proxy_fcgi" ] + ++ adminer.apache.modules + ++ ympd.apache.modules + ++ ttrss.apache.modules + ++ roundcubemail.apache.modules + ++ wallabag.apache.modules + ++ yourls.apache.modules + ++ rompr.apache.modules + ++ shaarli.apache.modules + ++ dokuwiki.apache.modules + ++ ldap.apache.modules + ++ kanboard.apache.modules; + + services.websites.integration.vhostConfs.devtools = { + certName = "eldiron"; + addToCerts = true; + hosts = ["devtools.immae.eu" ]; + root = "/var/lib/ftp/devtools.immae.eu"; + extraConfig = [ + '' + + DirectoryIndex index.php index.htm index.html + AllowOverride all + Require all granted + + SetHandler "proxy:unix:/var/run/phpfpm/devtools.sock|fcgi://localhost" + + + '' + rainloop.apache.vhostConf + ]; + }; + + services.websites.tools.vhostConfs.tools = { + certName = "eldiron"; + addToCerts = true; + hosts = ["tools.immae.eu" ]; + root = "/var/lib/ftp/tools.immae.eu"; + extraConfig = [ + '' + + DirectoryIndex index.php index.htm index.html + AllowOverride all + Require all granted + + SetHandler "proxy:unix:/var/run/phpfpm/tools.sock|fcgi://localhost" + + + '' + adminer.apache.vhostConf + ympd.apache.vhostConf + ttrss.apache.vhostConf + roundcubemail.apache.vhostConf + wallabag.apache.vhostConf + yourls.apache.vhostConf + rompr.apache.vhostConf + shaarli.apache.vhostConf + dokuwiki.apache.vhostConf + ldap.apache.vhostConf + kanboard.apache.vhostConf + ]; + }; + + services.websites.tools.vhostConfs.outils = { + certName = "eldiron"; + addToCerts = true; + hosts = [ "outils.immae.eu" ]; + root = null; + extraConfig = [ + '' + RedirectMatch 301 ^/mediagoblin(.*)$ https://mgoblin.immae.eu$1 + + RedirectMatch 301 ^/ether(.*)$ https://ether.immae.eu$1 + + RedirectMatch 301 ^/nextcloud(.*)$ https://cloud.immae.eu$1 + RedirectMatch 301 ^/owncloud(.*)$ https://cloud.immae.eu$1 + + RedirectMatch 301 ^/carddavmate(.*)$ https://dav.immae.eu/infcloud$1 + RedirectMatch 301 ^/caldavzap(.*)$ https://dav.immae.eu/infcloud$1 + RedirectMatch 301 ^/caldav.php(.*)$ https://dav.immae.eu/caldav.php$1 + RedirectMatch 301 ^/davical(.*)$ https://dav.immae.eu/davical$1 + + RedirectMatch 301 ^/taskweb(.*)$ https://task.immae.eu/taskweb$1 + + RedirectMatch 301 ^/(.*)$ https://tools.immae.eu/$1 + '' + ]; + }; + + systemd.services = { + phpfpm-dokuwiki = { + after = lib.mkAfter dokuwiki.phpFpm.serviceDeps; + wants = dokuwiki.phpFpm.serviceDeps; + }; + phpfpm-kanboard = { + after = lib.mkAfter kanboard.phpFpm.serviceDeps; + wants = kanboard.phpFpm.serviceDeps; + }; + phpfpm-ldap = { + after = lib.mkAfter ldap.phpFpm.serviceDeps; + wants = ldap.phpFpm.serviceDeps; + }; + phpfpm-rainloop = { + after = lib.mkAfter rainloop.phpFpm.serviceDeps; + wants = rainloop.phpFpm.serviceDeps; + }; + phpfpm-roundcubemail = { + after = lib.mkAfter roundcubemail.phpFpm.serviceDeps; + wants = roundcubemail.phpFpm.serviceDeps; + }; + phpfpm-shaarli = { + after = lib.mkAfter shaarli.phpFpm.serviceDeps; + wants = shaarli.phpFpm.serviceDeps; + }; + phpfpm-ttrss = { + after = lib.mkAfter ttrss.phpFpm.serviceDeps; + wants = ttrss.phpFpm.serviceDeps; + }; + phpfpm-wallabag = { + after = lib.mkAfter wallabag.phpFpm.serviceDeps; + wants = wallabag.phpFpm.serviceDeps; + preStart = lib.mkAfter wallabag.phpFpm.preStart; + }; + phpfpm-yourls = { + after = lib.mkAfter yourls.phpFpm.serviceDeps; + wants = yourls.phpFpm.serviceDeps; + }; + ympd = { + description = "Standalone MPD Web GUI written in C"; + wantedBy = [ "multi-user.target" ]; + script = '' + export MPD_PASSWORD=$(cat /var/secrets/mpd) + ${pkgs.ympd}/bin/ympd --host ${ympd.config.host} --port ${toString ympd.config.port} --webport ${ympd.config.webPort} --user nobody + ''; + }; + tt-rss = { + description = "Tiny Tiny RSS feeds update daemon"; + serviceConfig = { + User = "wwwrun"; + ExecStart = "${pkgs.php}/bin/php ${ttrss.webRoot}/update.php --daemon"; + StandardOutput = "syslog"; + StandardError = "syslog"; + PermissionsStartOnly = true; + }; + + wantedBy = [ "multi-user.target" ]; + requires = ["postgresql.service"]; + after = ["network.target" "postgresql.service"]; + }; + }; + + services.phpfpm.pools.roundcubemail = { + listen = roundcubemail.phpFpm.socket; + extraConfig = roundcubemail.phpFpm.pool; + phpOptions = config.services.phpfpm.phpOptions + roundcubemail.phpFpm.phpConfig; + }; + + services.phpfpm.pools.devtools = { + listen = "/var/run/phpfpm/devtools.sock"; + extraConfig = '' + user = wwwrun + group = wwwrun + listen.owner = wwwrun + listen.group = wwwrun + pm = dynamic + pm.max_children = 60 + pm.start_servers = 2 + pm.min_spare_servers = 1 + pm.max_spare_servers = 10 + + php_admin_value[open_basedir] = "/run/wrappers/bin/sendmail:/var/lib/ftp/devtools.immae.eu:/tmp" + ''; + phpOptions = config.services.phpfpm.phpOptions + '' + extension=${pkgs.phpPackages.redis}/lib/php/extensions/redis.so + extension=${pkgs.phpPackages.apcu}/lib/php/extensions/apcu.so + zend_extension=${pkgs.php}/lib/php/extensions/opcache.so + ''; + }; + + services.phpfpm.poolConfigs = { + adminer = adminer.phpFpm.pool; + ttrss = ttrss.phpFpm.pool; + wallabag = wallabag.phpFpm.pool; + yourls = yourls.phpFpm.pool; + rompr = rompr.phpFpm.pool; + shaarli = shaarli.phpFpm.pool; + dokuwiki = dokuwiki.phpFpm.pool; + ldap = ldap.phpFpm.pool; + rainloop = rainloop.phpFpm.pool; + kanboard = kanboard.phpFpm.pool; + tools = '' + listen = /var/run/phpfpm/tools.sock + user = wwwrun + group = wwwrun + listen.owner = wwwrun + listen.group = wwwrun + pm = dynamic + pm.max_children = 60 + pm.start_servers = 2 + pm.min_spare_servers = 1 + pm.max_spare_servers = 10 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = ToolsPHPSESSID + php_admin_value[open_basedir] = "/run/wrappers/bin/sendmail:/var/lib/ftp/tools.immae.eu:/tmp" + ''; + }; + + system.activationScripts = { + adminer = adminer.activationScript; + ttrss = ttrss.activationScript; + roundcubemail = roundcubemail.activationScript; + wallabag = wallabag.activationScript; + yourls = yourls.activationScript; + rompr = rompr.activationScript; + shaarli = shaarli.activationScript; + dokuwiki = dokuwiki.activationScript; + rainloop = rainloop.activationScript; + kanboard = kanboard.activationScript; + ldap = ldap.activationScript; + }; + + myServices.websites.webappDirs = { + _adminer = adminer.webRoot; + "${dokuwiki.apache.webappName}" = dokuwiki.webRoot; + "${ldap.apache.webappName}" = "${ldap.webRoot}/htdocs"; + "${rompr.apache.webappName}" = rompr.webRoot; + "${roundcubemail.apache.webappName}" = roundcubemail.webRoot; + "${shaarli.apache.webappName}" = shaarli.webRoot; + "${ttrss.apache.webappName}" = ttrss.webRoot; + "${wallabag.apache.webappName}" = wallabag.webRoot; + "${yourls.apache.webappName}" = yourls.webRoot; + "${rainloop.apache.webappName}" = rainloop.webRoot; + "${kanboard.apache.webappName}" = kanboard.webRoot; + }; + + }; +} + diff --git a/modules/private/websites/tools/tools/dokuwiki.nix b/modules/private/websites/tools/tools/dokuwiki.nix new file mode 100644 index 0000000..c61d15f --- /dev/null +++ b/modules/private/websites/tools/tools/dokuwiki.nix @@ -0,0 +1,61 @@ +{ lib, stdenv, dokuwiki, dokuwiki-plugins }: +rec { + varDir = "/var/lib/dokuwiki"; + activationScript = { + deps = [ "wrappers" ]; + text = '' + if [ ! -d ${varDir} ]; then + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/animals + cp -a ${webRoot}/conf.dist ${varDir}/conf + cp -a ${webRoot}/data.dist ${varDir}/data + cp -a ${webRoot}/ + chown -R ${apache.user}:${apache.user} ${varDir}/config ${varDir}/data + chmod -R 755 ${varDir}/config ${varDir}/data + fi + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + ''; + }; + webRoot = dokuwiki.withPlugins (builtins.attrValues dokuwiki-plugins); + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_dokuwiki"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /dokuwiki "${root}" + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride All + Options +FollowSymlinks + Require all granted + + ''; + }; + phpFpm = rec { + serviceDeps = [ "openldap.service" ]; + basedir = builtins.concatStringsSep ":" ( + [ webRoot varDir ] ++ webRoot.plugins); + socket = "/var/run/phpfpm/dokuwiki.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = DokuwikiPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/kanboard.nix b/modules/private/websites/tools/tools/kanboard.nix new file mode 100644 index 0000000..68f92b8 --- /dev/null +++ b/modules/private/websites/tools/tools/kanboard.nix @@ -0,0 +1,86 @@ +{ env, kanboard }: +rec { + varDir = "/var/lib/kanboard"; + activationScript = { + deps = [ "wrappers" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir}/data + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + install -TDm644 ${webRoot}/dataold/.htaccess ${varDir}/data/.htaccess + install -TDm644 ${webRoot}/dataold/web.config ${varDir}/data/web.config + ''; + }; + keys = [{ + dest = "webapps/tools-kanboard"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + + ''; + }]; + webRoot = kanboard { kanboard_config = "/var/secrets/webapps/tools-kanboard"; }; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_kanboard"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /kanboard "${root}" + + DirectoryIndex index.php + AllowOverride All + Options FollowSymlinks + Require all granted + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + + Require all denied + + ''; + }; + phpFpm = rec { + serviceDeps = [ "postgresql.service" "openldap.service" ]; + basedir = builtins.concatStringsSep ":" [ webRoot varDir "/var/secrets/webapps/tools-kanboard" ]; + socket = "/var/run/phpfpm/kanboard.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = KanboardPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/ldap.nix b/modules/private/websites/tools/tools/ldap.nix new file mode 100644 index 0000000..4585ee3 --- /dev/null +++ b/modules/private/websites/tools/tools/ldap.nix @@ -0,0 +1,74 @@ +{ lib, php, env, writeText, phpldapadmin }: +rec { + activationScript = { + deps = [ "httpd" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d /var/lib/php/sessions/phpldapadmin + ''; + }; + keys = [{ + dest = "webapps/tools-ldap"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + custom->appearance['show_clear_password'] = true; + $config->custom->appearance['hide_template_warning'] = true; + $config->custom->appearance['theme'] = "tango"; + $config->custom->appearance['minimalMode'] = true; + + $servers = new Datastore(); + + $servers->newServer('ldap_pla'); + $servers->setValue('server','name','Immae’s LDAP'); + $servers->setValue('server','host','ldaps://${env.ldap.host}'); + $servers->setValue('login','auth_type','cookie'); + $servers->setValue('login','bind_id','${env.ldap.dn}'); + $servers->setValue('login','bind_pass','${env.ldap.password}'); + $servers->setValue('appearance','password_hash','ssha'); + $servers->setValue('login','attr','uid'); + $servers->setValue('login','fallback_dn',true); + ''; + }]; + webRoot = phpldapadmin.override { config = "/var/secrets/webapps/tools-ldap"; }; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_ldap"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /ldap "${root}" + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride None + Require all granted + + ''; + }; + phpFpm = rec { + serviceDeps = [ "openldap.service" ]; + basedir = builtins.concatStringsSep ":" [ webRoot "/var/secrets/webapps/tools-ldap" ]; + socket = "/var/run/phpfpm/ldap.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = LdapPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp:/var/lib/php/sessions/phpldapadmin" + php_admin_value[session.save_path] = "/var/lib/php/sessions/phpldapadmin" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/rainloop.nix b/modules/private/websites/tools/tools/rainloop.nix new file mode 100644 index 0000000..dbf0f24 --- /dev/null +++ b/modules/private/websites/tools/tools/rainloop.nix @@ -0,0 +1,59 @@ +{ lib, pkgs, writeText, stdenv, fetchurl }: +rec { + varDir = "/var/lib/rainloop"; + activationScript = { + deps = [ "wrappers" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/data + ''; + }; + webRoot = pkgs.rainloop-community.override { dataPath = "${varDir}/data"; }; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_rainloop"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /rainloop "${root}" + + DirectoryIndex index.php + AllowOverride All + Options -FollowSymlinks + Require all granted + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + + + Require all denied + + ''; + }; + phpFpm = rec { + serviceDeps = [ "postgresql.service" ]; + basedir = builtins.concatStringsSep ":" [ webRoot varDir ]; + socket = "/var/run/phpfpm/rainloop.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = RainloopPHPSESSID + php_admin_value[upload_max_filesize] = 200M + php_admin_value[post_max_size] = 200M + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/rompr.nix b/modules/private/websites/tools/tools/rompr.nix new file mode 100644 index 0000000..fea59fc --- /dev/null +++ b/modules/private/websites/tools/tools/rompr.nix @@ -0,0 +1,77 @@ +{ lib, env, rompr }: +rec { + varDir = "/var/lib/rompr"; + activationScript = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/prefs ${varDir}/albumart ${varDir}/phpSessions + ''; + webRoot = rompr; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "headers" "mime" "proxy_fcgi" ]; + webappName = "tools_rompr"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /rompr ${root} + + + Options Indexes FollowSymLinks + DirectoryIndex index.php + AllowOverride all + Require all granted + Order allow,deny + Allow from all + ErrorDocument 404 /rompr/404.php + AddType image/x-icon .ico + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + + + Header Set Cache-Control "max-age=0, no-store" + Header Set Cache-Control "no-cache, must-revalidate" + + + + Header Set Cache-Control "max-age=0, no-store" + Header Set Cache-Control "no-cache, must-revalidate" + + + + Use LDAPConnect + Require ldap-group cn=users,cn=mpd,ou=services,dc=immae,dc=eu + + ''; + }; + phpFpm = rec { + basedir = builtins.concatStringsSep ":" [ webRoot varDir ]; + socket = "/var/run/phpfpm/rompr.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = RomprPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + php_flag[magic_quotes_gpc] = Off + php_flag[track_vars] = On + php_flag[register_globals] = Off + php_admin_flag[allow_url_fopen] = On + php_value[include_path] = ${webRoot} + php_admin_value[upload_tmp_dir] = "${varDir}/prefs" + php_admin_value[post_max_size] = 32M + php_admin_value[upload_max_filesize] = 32M + php_admin_value[memory_limit] = 256M + ''; + }; +} diff --git a/modules/private/websites/tools/tools/roundcubemail.nix b/modules/private/websites/tools/tools/roundcubemail.nix new file mode 100644 index 0000000..8974d1b --- /dev/null +++ b/modules/private/websites/tools/tools/roundcubemail.nix @@ -0,0 +1,121 @@ +{ env, roundcubemail, roundcubemail-plugins, roundcubemail-skins, phpPackages, apacheHttpd }: +rec { + varDir = "/var/lib/roundcubemail"; + activationScript = { + deps = [ "wrappers" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/cache ${varDir}/logs + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + ''; + }; + keys = [{ + dest = "webapps/tools-roundcube"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + array("verify_peer" => false)); + $config['smtp_server'] = 'tls://mail.immae.eu'; + $config['smtp_port'] = '25'; + $config['managesieve_host'] = 'mail.immae.eu'; + $config['managesieve_port'] = '4190'; + $config['managesieve_usetls'] = true; + $config['managesieve_conn_options'] = array("ssl" => array("verify_peer" => false)); + + $config['imap_cache'] = 'db'; + $config['messages_cache'] = 'db'; + + $config['support_url'] = '''; + + $config['des_key'] = '${env.secret}'; + + $config['skin'] = 'elastic'; + $config['plugins'] = array( + 'attachment_reminder', + 'emoticons', + 'filesystem_attachments', + 'hide_blockquote', + 'identicon', + 'identity_select', + 'jqueryui', + 'managesieve', + 'newmail_notifier', + 'vcard_attachments', + 'zipdownload', + + 'automatic_addressbook', + 'message_highlight', + 'carddav', + // Ne marche pas ?: 'ident_switch', + // Ne marche pas ?: 'thunderbird_labels', + ); + + $config['language'] = 'fr_FR'; + + $config['drafts_mbox'] = 'Mail/Drafts'; + $config['junk_mbox'] = 'Mail/Spam'; + $config['sent_mbox'] = 'Mail/sent'; + $config['trash_mbox'] = '''; + $config['default_folders'] = array('INBOX', 'Mail/Drafts', 'Mail/sent', 'Mail/Spam', '''); + $config['draft_autosave'] = 60; + $config['enable_installer'] = false; + $config['log_driver'] = 'file'; + $config['temp_dir'] = '${varDir}/cache'; + $config['mime_types'] = '${apacheHttpd}/conf/mime.types'; + ''; + }]; + webRoot = (roundcubemail.override { roundcube_config = "/var/secrets/webapps/tools-roundcube"; }).withPlugins + (builtins.attrValues roundcubemail-plugins) (builtins.attrValues roundcubemail-skins); + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_roundcubemail"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /roundcube "${root}" + + DirectoryIndex index.php + AllowOverride All + Options FollowSymlinks + Require all granted + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + ''; + }; + phpFpm = rec { + serviceDeps = [ "postgresql.service" ]; + basedir = builtins.concatStringsSep ":" ( + [ webRoot "/var/secrets/webapps/tools-roundcube" varDir ] + ++ webRoot.plugins + ++ webRoot.skins); + phpConfig = '' + date.timezone = 'CET' + extension=${phpPackages.imagick}/lib/php/extensions/imagick.so + ''; + socket = "/var/run/phpfpm/roundcubemail.sock"; + pool = '' + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = RoundcubemailPHPSESSID + php_admin_value[upload_max_filesize] = 200M + php_admin_value[post_max_size] = 200M + php_admin_value[open_basedir] = "${basedir}:${apacheHttpd}/conf/mime.types:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/shaarli.nix b/modules/private/websites/tools/tools/shaarli.nix new file mode 100644 index 0000000..2e89a47 --- /dev/null +++ b/modules/private/websites/tools/tools/shaarli.nix @@ -0,0 +1,65 @@ +{ lib, env, stdenv, fetchurl, shaarli }: +let + varDir = "/var/lib/shaarli"; +in rec { + activationScript = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/cache ${varDir}/pagecache ${varDir}/tmp ${varDir}/data \ + ${varDir}/phpSessions + ''; + webRoot = shaarli varDir; + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" "rewrite" "env" ]; + webappName = "tools_shaarli"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /Shaarli "${root}" + + Include /var/secrets/webapps/tools-shaarli + + DirectoryIndex index.php index.htm index.html + Options Indexes FollowSymLinks MultiViews Includes + AllowOverride All + Require all granted + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + ''; + }; + keys = [{ + dest = "webapps/tools-shaarli"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + SetEnv SHAARLI_LDAP_PASSWORD "${env.ldap.password}" + SetEnv SHAARLI_LDAP_DN "${env.ldap.dn}" + SetEnv SHAARLI_LDAP_HOST "ldaps://${env.ldap.host}" + SetEnv SHAARLI_LDAP_BASE "${env.ldap.base}" + SetEnv SHAARLI_LDAP_FILTER "${env.ldap.search}" + ''; + }]; + phpFpm = rec { + serviceDeps = [ "openldap.service" ]; + basedir = builtins.concatStringsSep ":" [ webRoot varDir ]; + socket = "/var/run/phpfpm/shaarli.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = ShaarliPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/ttrss.nix b/modules/private/websites/tools/tools/ttrss.nix new file mode 100644 index 0000000..05c8cab --- /dev/null +++ b/modules/private/websites/tools/tools/ttrss.nix @@ -0,0 +1,131 @@ +{ php, env, ttrss, ttrss-plugins }: +rec { + varDir = "/var/lib/ttrss"; + activationScript = { + deps = [ "wrappers" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/lock ${varDir}/cache ${varDir}/feed-icons + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir}/cache/export/ \ + ${varDir}/cache/feeds/ \ + ${varDir}/cache/images/ \ + ${varDir}/cache/js/ \ + ${varDir}/cache/simplepie/ \ + ${varDir}/cache/upload/ + touch ${varDir}/feed-icons/index.html + install -m 0750 -o ${apache.user} -g ${apache.group} -d ${varDir}/phpSessions + ''; + }; + keys = [{ + dest = "webapps/tools-ttrss"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + + DirectoryIndex index.php + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride All + Options FollowSymlinks + Require all granted + + ''; + }; + phpFpm = rec { + serviceDeps = [ "postgresql.service" "openldap.service" ]; + basedir = builtins.concatStringsSep ":" ( + [ webRoot "/var/secrets/webapps/tools-ttrss" varDir ] + ++ webRoot.plugins); + socket = "/var/run/phpfpm/ttrss.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = TtrssPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp" + php_admin_value[session.save_path] = "${varDir}/phpSessions" + ''; + }; +} diff --git a/modules/private/websites/tools/tools/wallabag.nix b/modules/private/websites/tools/tools/wallabag.nix new file mode 100644 index 0000000..d6e5882 --- /dev/null +++ b/modules/private/websites/tools/tools/wallabag.nix @@ -0,0 +1,148 @@ +{ env, wallabag }: +rec { + varDir = "/var/lib/wallabag"; + keys = [{ + dest = "webapps/tools-wallabag"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + # This file is auto-generated during the composer install + parameters: + database_driver: pdo_pgsql + database_driver_class: Wallabag\CoreBundle\Doctrine\DBAL\Driver\CustomPostgreSQLDriver + database_host: ${env.postgresql.socket} + database_port: ${env.postgresql.port} + database_name: ${env.postgresql.database} + database_user: ${env.postgresql.user} + database_password: ${env.postgresql.password} + database_path: null + database_table_prefix: wallabag_ + database_socket: null + database_charset: utf8 + domain_name: https://tools.immae.eu/wallabag + mailer_transport: sendmail + mailer_host: 127.0.0.1 + mailer_user: null + mailer_password: null + locale: fr + secret: ${env.secret} + twofactor_auth: true + twofactor_sender: wallabag@tools.immae.eu + fosuser_registration: false + fosuser_confirmation: true + from_email: wallabag@tools.immae.eu + rss_limit: 50 + rabbitmq_host: localhost + rabbitmq_port: 5672 + rabbitmq_user: guest + rabbitmq_password: guest + rabbitmq_prefetch_count: 10 + redis_scheme: unix + redis_host: null + redis_port: null + redis_path: ${env.redis.socket} + redis_password: null + sites_credentials: { } + ldap_enabled: true + ldap_host: ldap.immae.eu + ldap_port: 636 + ldap_tls: false + ldap_ssl: true + ldap_bind_requires_dn: true + ldap_base: 'dc=immae,dc=eu' + ldap_manager_dn: 'cn=wallabag,ou=services,dc=immae,dc=eu' + ldap_manager_pw: ${env.ldap.password} + ldap_filter: '(&(memberOf=cn=users,cn=wallabag,ou=services,dc=immae,dc=eu))' + ldap_admin_filter: '(&(memberOf=cn=admins,cn=wallabag,ou=services,dc=immae,dc=eu)(uid=%s))' + ldap_username_attribute: uid + ldap_email_attribute: mail + ldap_name_attribute: cn + ldap_enabled_attribute: null + services: + swiftmailer.mailer.default.transport: + class: Swift_SendmailTransport + arguments: ['/run/wrappers/bin/sendmail -bs'] + ''; + }]; + webappDir = wallabag.override { ldap = true; wallabag_config = "/var/secrets/webapps/tools-wallabag"; }; + activationScript = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d ${varDir} \ + ${varDir}/var ${varDir}/data/db ${varDir}/assets/images + ''; + webRoot = "${webappDir}/web"; + # Domain migration: Table wallabag_entry contains whole + # https://tools.immae.eu/wallabag domain name in preview_picture + apache = rec { + user = "wwwrun"; + group = "wwwrun"; + modules = [ "proxy_fcgi" ]; + webappName = "tools_wallabag"; + root = "/run/current-system/webapps/${webappName}"; + vhostConf = '' + Alias /wallabag "${root}" + + AllowOverride None + Require all granted + # For OAuth (apps) + CGIPassAuth On + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + + Options -MultiViews + RewriteEngine On + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^(.*)$ app.php [QSA,L] + + + + + RewriteEngine Off + + + + AllowOverride None + Require all granted + + ''; + }; + phpFpm = rec { + preStart = '' + if [ ! -f "${varDir}/currentWebappDir" -o \ + ! -f "${varDir}/currentKey" -o \ + "${webappDir}" != "$(cat ${varDir}/currentWebappDir 2>/dev/null)" ] \ + || ! sha512sum -c --status ${varDir}/currentKey; then + pushd ${webappDir} > /dev/null + /run/wrappers/bin/sudo -u wwwrun ./bin/console --env=prod cache:clear + rm -rf /var/lib/wallabag/var/cache/pro_ + /run/wrappers/bin/sudo -u wwwrun ./bin/console --env=prod doctrine:migrations:migrate --no-interaction + popd > /dev/null + echo -n "${webappDir}" > ${varDir}/currentWebappDir + sha512sum /var/secrets/webapps/tools-wallabag > ${varDir}/currentKey + fi + ''; + serviceDeps = [ "postgresql.service" "openldap.service" ]; + basedir = builtins.concatStringsSep ":" [ webappDir "/var/secrets/webapps/tools-wallabag" varDir ]; + socket = "/var/run/phpfpm/wallabag.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = dynamic + pm.max_children = 60 + pm.start_servers = 2 + pm.min_spare_servers = 1 + pm.max_spare_servers = 10 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = WallabagPHPSESSID + php_admin_value[open_basedir] = "/run/wrappers/bin/sendmail:${basedir}:/tmp" + php_value[max_execution_time] = 300 + ''; + }; +} diff --git a/modules/private/websites/tools/tools/ympd.nix b/modules/private/websites/tools/tools/ympd.nix new file mode 100644 index 0000000..b54c486 --- /dev/null +++ b/modules/private/websites/tools/tools/ympd.nix @@ -0,0 +1,40 @@ +{ env }: +let + ympd = rec { + config = { + webPort = "localhost:${env.listenPort}"; + host = env.mpd.host; + port = env.mpd.port; + }; + apache = { + modules = [ + "proxy_wstunnel" + ]; + vhostConf = '' + + Use LDAPConnect + Require ldap-group cn=users,cn=mpd,ou=services,dc=immae,dc=eu + + + RedirectMatch permanent "^/mpd$" "/mpd/" + + ProxyPass http://${config.webPort}/ + ProxyPassReverse http://${config.webPort}/ + ProxyPreserveHost on + + + ProxyPass ws://${config.webPort}/ws + + + ProxyPass unix:///run/mpd/mp3.sock|http://tools.immae.eu/ + ProxyPassReverse unix:///run/mpd/mp3.sock|http://tools.immae.eu/ + + + ProxyPass unix:///run/mpd/ogg.sock|http://tools.immae.eu/ + ProxyPassReverse unix:///run/mpd/ogg.sock|http://tools.immae.eu/ + + ''; + }; + }; +in + ympd diff --git a/modules/private/websites/tools/tools/yourls.nix b/modules/private/websites/tools/tools/yourls.nix new file mode 100644 index 0000000..0a8e837 --- /dev/null +++ b/modules/private/websites/tools/tools/yourls.nix @@ -0,0 +1,93 @@ +{ env, yourls, yourls-plugins }: +rec { + activationScript = { + deps = [ "httpd" ]; + text = '' + install -m 0755 -o ${apache.user} -g ${apache.group} -d /var/lib/php/sessions/yourls + ''; + }; + keys = [{ + dest = "webapps/tools-yourls"; + user = apache.user; + group = apache.group; + permissions = "0400"; + text = '' + + + SetHandler "proxy:unix:${phpFpm.socket}|fcgi://localhost" + + + AllowOverride None + Require all granted + + RewriteEngine On + RewriteBase /url/ + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^.*$ /url/yourls-loader.php [L] + + DirectoryIndex index.php + + ''; + }; + phpFpm = rec { + serviceDeps = [ "mysql.service" "openldap.service" ]; + basedir = builtins.concatStringsSep ":" ( + [ webRoot "/var/secrets/webapps/tools-yourls" ] + ++ webRoot.plugins); + socket = "/var/run/phpfpm/yourls.sock"; + pool = '' + listen = ${socket} + user = ${apache.user} + group = ${apache.group} + listen.owner = ${apache.user} + listen.group = ${apache.group} + pm = ondemand + pm.max_children = 60 + pm.process_idle_timeout = 60 + + ; Needed to avoid clashes in browser cookies (same domain) + php_value[session.name] = YourlsPHPSESSID + php_admin_value[open_basedir] = "${basedir}:/tmp:/var/lib/php/sessions/yourls" + php_admin_value[session.save_path] = "/var/lib/php/sessions/yourls" + ''; + }; +} -- cgit v1.2.3