]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - nixops/modules/websites/default.nix
Start moving websites configuration to modules
[perso/Immae/Config/Nix.git] / nixops / modules / websites / default.nix
index e40c8f4f17d866375c3bc15ef4435a22fcd4a9f7..5b839af9885c97a1b258133368b1723da1d7c381 100644 (file)
-{ lib, pkgs, config, mylibs, myconfig, ... }:
+{ lib, pkgs, config,  myconfig, ... }:
 let
   cfg = config.services.myWebsites;
   www_root = "/run/current-system/webapps/_www";
   theme_root = "/run/current-system/webapps/_theme";
-  makeService = name: cfg: let
-    toVhost = vhostConf: {
-      enableSSL = true;
-      sslServerCert = "/var/lib/acme/${vhostConf.certName}/cert.pem";
-      sslServerKey = "/var/lib/acme/${vhostConf.certName}/key.pem";
-      sslServerChain = "/var/lib/acme/${vhostConf.certName}/chain.pem";
-      logFormat = "combinedVhost";
-      listen = map (ip: { inherit ip; port = 443; }) cfg.ips;
-      hostName = builtins.head vhostConf.hosts;
-      serverAliases = builtins.tail vhostConf.hosts or [];
-      documentRoot = vhostConf.root;
-      extraConfig = builtins.concatStringsSep "\n" vhostConf.extraConfig;
-    };
-    nosslVhost = {
-      listen = map (ip: { inherit ip; port = 80; }) cfg.ips;
-      hostName = "nossl.immae.eu";
-      enableSSL = false;
-      logFormat = "combinedVhost";
-      documentRoot = www_root;
+  apacheConfig = {
+    gzip = {
+      modules = [ "deflate" "filter" ];
       extraConfig = ''
-        <Directory ${www_root}>
-          DirectoryIndex nossl.html
-          AllowOverride None
-          Require all granted
-
-          RewriteEngine on
-          RewriteRule ^/(.+)   /   [L]
-        </Directory>
-        '';
+        AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
+      '';
     };
-    redirectVhost = { # Should go last, catchall http -> https redirect
-      listen = map (ip: { inherit ip; port = 80; }) cfg.ips;
-      hostName = "redirectSSL";
-      serverAliases = [ "*" ];
-      enableSSL = false;
-      logFormat = "combinedVhost";
-      documentRoot = "/var/lib/acme/acme-challenge";
+    macros = {
+      modules = [ "macro" ];
+    };
+    stats = {
       extraConfig = ''
-        RewriteEngine on
-        RewriteCond "%{REQUEST_URI}"   "!^/\.well-known"
-        RewriteRule ^(.+)              https://%{HTTP_HOST}$1  [R=301]
-        # To redirect in specific "VirtualHost *:80", do
-        #   RedirectMatch 301 ^/((?!\.well-known.*$).*)$ https://host/$1
-        # rather than rewrite
+        <Macro Stats %{domain}>
+          Alias /webstats ${config.services.webstats.dataDir}/%{domain}
+          <Directory ${config.services.webstats.dataDir}/%{domain}>
+            DirectoryIndex index.html
+            AllowOverride None
+            Require all granted
+          </Directory>
+          <Location /webstats>
+            Use LDAPConnect
+            Require ldap-group cn=%{domain},ou=stats,cn=httpd,ou=services,dc=immae,dc=eu
+          </Location>
+        </Macro>
       '';
     };
-    fallbackVhost = toVhost { # Should go first, default choice
-      certName    = "eldiron";
-      hosts       = ["eldiron.immae.eu" ];
-      root        = www_root;
-      extraConfig = [ "DirectoryIndex index.htm" ];
+    ldap = {
+      modules = [ "ldap" "authnz_ldap" ];
+      extraConfig = ''
+        <IfModule ldap_module>
+          LDAPSharedCacheSize 500000
+          LDAPCacheEntries 1024
+          LDAPCacheTTL 600
+          LDAPOpCacheEntries 1024
+          LDAPOpCacheTTL 600
+        </IfModule>
+
+        Include /var/secrets/apache-ldap
+      '';
     };
-  in rec {
-    enable = true;
-    listen = map (ip: { inherit ip; port = 443; }) cfg.ips;
-    stateDir = "/run/httpd_${name}";
-    logPerVirtualHost = true;
-    multiProcessingModule = "worker";
-    adminAddr = "httpd@immae.eu";
-    logFormat = "combinedVhost";
-    extraModules = pkgs.lib.lists.unique (pkgs.lib.lists.flatten cfg.modules);
-    extraConfig = builtins.concatStringsSep "\n" cfg.extraConfig;
-    virtualHosts = [ fallbackVhost ]
-      ++ lib.optionals (name == "tools") [ nosslVhost ]
-      ++ (pkgs.lib.attrsets.mapAttrsToList (n: v: toVhost v) cfg.vhostConfs)
-      ++ [ redirectVhost ];
-  };
-  makeServiceOptions = name: {
-    enable = lib.mkEnableOption "enable websites in ${name}";
-    ips = lib.mkOption {
-      type = lib.types.listOf lib.types.string;
-      default = let
-        ips = myconfig.env.servers.eldiron.ips.${name};
-      in
-        [ips.ip4] ++ (ips.ip6 or []);
-      description = "${name} ips to listen to";
+    global = {
+      extraConfig = (pkgs.webapps.apache-default.override { inherit www_root;}).apacheConfig;
     };
-    modules = lib.mkOption {
-      type = lib.types.listOf (lib.types.str);
-      default = [];
+    apaxy = {
+      extraConfig = (pkgs.webapps.apache-theme.override { inherit theme_root; }).apacheConfig;
     };
-    extraConfig = lib.mkOption {
-      type = lib.types.listOf (lib.types.lines);
-      default = [];
+    http2 = {
+      modules = [ "http2" ];
+      extraConfig = ''
+        Protocols h2 http/1.1
+      '';
     };
-    vhostConfs = lib.mkOption {
-      type = lib.types.attrsOf (lib.types.submodule {
-        options = {
-          certName = lib.mkOption { type = lib.types.string; };
-          hosts    = lib.mkOption { type = lib.types.listOf lib.types.string; };
-          root     = lib.mkOption { type = lib.types.nullOr lib.types.path; };
-          extraConfig = lib.mkOption { type = lib.types.listOf lib.types.lines; default = []; };
-        };
-      });
+    customLog = {
+      extraConfig = ''
+        LogFormat "%v:%p %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedVhost
+      '';
     };
   };
-  makeModules = cfg: pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules or []) cfg.apacheConfig);
-  makeExtraConfig = cfg: (builtins.filter (x: x != null) (pkgs.lib.attrsets.mapAttrsToList (n: v: v.extraConfig or null) cfg.apacheConfig));
+  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
 {
   imports = [
@@ -130,43 +92,11 @@ in
     ./tools/mediagoblin.nix
     ./tools/diaspora.nix
     ./tools/ether.nix
-    ./tools/peertube
-    # built using:
-    # sed -e "s/services\.httpd/services\.httpdProd/g" .nix-defexpr/channels/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
-    # Removed allGranted
-    # And removed users / groups
-    ./apache/httpd_prod.nix
-    ./apache/httpd_inte.nix
-    # except for this one for users/groups
-    ./apache/httpd_tools.nix
+    ./tools/peertube.nix
     # Adapted from base phpfpm
     ./phpfpm
   ];
 
-  options.services.myWebsites = {
-    production = makeServiceOptions "production";
-    integration = makeServiceOptions "integration";
-    tools = makeServiceOptions "main";
-
-    apacheConfig = lib.mkOption {
-      type = lib.types.attrsOf (lib.types.submodule {
-        options = {
-          modules = lib.mkOption {
-            type = lib.types.listOf (lib.types.str);
-            default = [];
-          };
-          extraConfig = lib.mkOption {
-            type = lib.types.nullOr lib.types.lines;
-            default = null;
-          };
-        };
-      });
-      default = {};
-      description = "Extra global config";
-    };
-
-  };
-
   config = {
     users.users.wwwrun.extraGroups = [ "keys" ];
     networking.firewall.allowedTCPPorts = [ 80 443 ];
@@ -203,32 +133,32 @@ in
     services.myWebsites.tools.etherpad-lite.enable = true;
     services.myWebsites.tools.peertube.enable = true;
 
-    services.myWebsites.Chloe.production.enable = cfg.production.enable;
-    services.myWebsites.Ludivine.production.enable = cfg.production.enable;
-    services.myWebsites.Aten.production.enable = cfg.production.enable;
-    services.myWebsites.PiedsJaloux.production.enable = cfg.production.enable;
-    services.myWebsites.Connexionswing.production.enable = cfg.production.enable;
-    services.myWebsites.Jerome.production.enable = cfg.production.enable;
-    services.myWebsites.Nassime.production.enable = cfg.production.enable;
-    services.myWebsites.Florian.production.enable = cfg.production.enable;
-    services.myWebsites.Leila.production.enable = cfg.production.enable;
-    services.myWebsites.Papa.production.enable = cfg.production.enable;
-    services.myWebsites.DeniseJerome.production.enable = cfg.production.enable;
-    services.myWebsites.Emilia.production.enable = cfg.production.enable;
-    services.myWebsites.Capitaines.production.enable = cfg.production.enable;
-    services.myWebsites.Immae.production.enable = cfg.production.enable;
-    services.myWebsites.Release.production.enable = cfg.production.enable;
-    services.myWebsites.Temp.production.enable = cfg.production.enable;
+    services.myWebsites.Chloe.production.enable = true;
+    services.myWebsites.Ludivine.production.enable = true;
+    services.myWebsites.Aten.production.enable = true;
+    services.myWebsites.PiedsJaloux.production.enable = true;
+    services.myWebsites.Connexionswing.production.enable = true;
+    services.myWebsites.Jerome.production.enable = true;
+    services.myWebsites.Nassime.production.enable = true;
+    services.myWebsites.Florian.production.enable = true;
+    services.myWebsites.Leila.production.enable = true;
+    services.myWebsites.Papa.production.enable = true;
+    services.myWebsites.DeniseJerome.production.enable = true;
+    services.myWebsites.Emilia.production.enable = true;
+    services.myWebsites.Capitaines.production.enable = true;
+    services.myWebsites.Immae.production.enable = true;
+    services.myWebsites.Release.production.enable = true;
+    services.myWebsites.Temp.production.enable = true;
 
-    services.myWebsites.Chloe.integration.enable = cfg.integration.enable;
-    services.myWebsites.Ludivine.integration.enable = cfg.integration.enable;
-    services.myWebsites.Aten.integration.enable = cfg.integration.enable;
-    services.myWebsites.PiedsJaloux.integration.enable = cfg.integration.enable;
-    services.myWebsites.Connexionswing.integration.enable = cfg.integration.enable;
+    services.myWebsites.Chloe.integration.enable = true;
+    services.myWebsites.Ludivine.integration.enable = true;
+    services.myWebsites.Aten.integration.enable = true;
+    services.myWebsites.PiedsJaloux.integration.enable = true;
+    services.myWebsites.Connexionswing.integration.enable = true;
     services.myWebsites.TellesFlorian.integration.enable = true;
     services.myWebsites.Florian.integration.enable = true;
 
-    mySecrets.keys = [{
+    secrets.keys = [{
       dest = "apache-ldap";
       user = "wwwrun";
       group = "wwwrun";
@@ -247,160 +177,6 @@ in
         '';
     }];
 
-    services.myWebsites.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 = ''
-          <Macro Stats %{domain}>
-            Alias /awstats /var/lib/goaccess/%{domain}
-            <Directory /var/lib/goaccess/%{domain}>
-              DirectoryIndex index.html
-              AllowOverride None
-              Require all granted
-            </Directory>
-            <Location /awstats>
-              Use LDAPConnect
-              Require ldap-group cn=%{domain},ou=stats,cn=httpd,ou=services,dc=immae,dc=eu
-            </Location>
-          </Macro>
-        '';
-      };
-      ldap = {
-        modules = [ "ldap" "authnz_ldap" ];
-        extraConfig = ''
-          <IfModule ldap_module>
-            LDAPSharedCacheSize 500000
-            LDAPCacheEntries 1024
-            LDAPCacheTTL 600
-            LDAPOpCacheEntries 1024
-            LDAPOpCacheTTL 600
-          </IfModule>
-
-          Include /var/secrets/apache-ldap
-        '';
-      };
-      global = {
-        extraConfig = ''
-          ErrorDocument 500 /maintenance_immae.html
-          ErrorDocument 501 /maintenance_immae.html
-          ErrorDocument 502 /maintenance_immae.html
-          ErrorDocument 503 /maintenance_immae.html
-          ErrorDocument 504 /maintenance_immae.html
-          Alias /maintenance_immae.html ${www_root}/maintenance_immae.html
-          ProxyPass /maintenance_immae.html !
-
-          AliasMatch "(.*)/googleb6d69446ff4ca3e5.html" ${www_root}/googleb6d69446ff4ca3e5.html
-          <Directory ${www_root}>
-            AllowOverride None
-            Require all granted
-          </Directory>
-        '';
-      };
-      apaxy = {
-        extraConfig = ''
-          <Macro Apaxy %{folder} %{ignored}>
-            Alias /theme ${theme_root}
-            <Directory ${theme_root}>
-              Options -Indexes
-              AllowOverride None
-              Require all granted
-            </Directory>
-
-            # mod_autoindex
-            <Directory %{folder}>
-              Options Indexes
-              AllowOverride None
-              Require all granted
-
-              # Inspired from Apaxy by @adamwhitcroft
-
-              IndexOptions +Charset=UTF-8 +FancyIndexing +IgnoreCase +FoldersFirst +XHTML +HTMLTable +SuppressRules +SuppressDescription +NameWidth=* +IconsAreLinks +ShowForbidden
-
-              IndexHeadInsert "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
-
-              IndexIgnoreReset ON
-              IndexIgnore /theme .htaccess %{ignored}
-
-              AddIcon /theme/icons/blank.png ^^BLANKICON^^
-              AddIcon /theme/icons/folder.png ^^DIRECTORY^^
-              AddIcon /theme/icons/folder-home.png ..
-
-              AddIconByType (TXT,/theme/icons/text.png) text/*
-              AddIconByType (IMG,/theme/icons/image.png) image/*
-              AddIconByType (SND,/theme/icons/audio.png) audio/*
-              AddIconByType (VID,/theme/icons/video.png) video/*
-
-              AddIcon /theme/icons/archive.png .7z .bz2 .cab .gz .tar
-              AddIcon /theme/icons/audio.png .aac .aif .aifc .aiff .ape .au .flac .iff .m4a .mid .mp3 .mpa .ra .wav .wma .f4a .f4b .oga .ogg .xm .it .s3m .mod
-              AddIcon /theme/icons/bin.png .bin .hex
-              AddIcon /theme/icons/bmp.png .bmp
-              AddIcon /theme/icons/c.png .c
-              AddIcon /theme/icons/calc.png .xlsx .xlsm .xltx .xltm .xlam .xlr .xls .csv
-              AddIcon /theme/icons/cd.png .iso
-              AddIcon /theme/icons/cpp.png .cpp
-              AddIcon /theme/icons/css.png .css .sass .scss
-              AddIcon /theme/icons/deb.png .deb
-              AddIcon /theme/icons/doc.png .doc .docx .docm .dot .dotx .dotm .log .msg .odt .pages .rtf .tex .wpd .wps
-              AddIcon /theme/icons/draw.png .svg .svgz
-              AddIcon /theme/icons/eps.png .ai .eps
-              AddIcon /theme/icons/exe.png .exe
-              AddIcon /theme/icons/gif.png .gif
-              AddIcon /theme/icons/h.png .h
-              AddIcon /theme/icons/html.png .html .xhtml .shtml .htm .URL .url
-              AddIcon /theme/icons/ico.png .ico
-              AddIcon /theme/icons/java.png .jar
-              AddIcon /theme/icons/jpg.png .jpg .jpeg .jpe
-              AddIcon /theme/icons/js.png .js .json
-              AddIcon /theme/icons/markdown.png .md
-              AddIcon /theme/icons/package.png .pkg .dmg
-              AddIcon /theme/icons/pdf.png .pdf
-              AddIcon /theme/icons/php.png .php .phtml
-              AddIcon /theme/icons/playlist.png .m3u .m3u8 .pls .pls8
-              AddIcon /theme/icons/png.png .png
-              AddIcon /theme/icons/ps.png .ps
-              AddIcon /theme/icons/psd.png .psd
-              AddIcon /theme/icons/py.png .py
-              AddIcon /theme/icons/rar.png .rar
-              AddIcon /theme/icons/rb.png .rb
-              AddIcon /theme/icons/rpm.png .rpm
-              AddIcon /theme/icons/rss.png .rss
-              AddIcon /theme/icons/script.png .bat .cmd .sh
-              AddIcon /theme/icons/sql.png .sql
-              AddIcon /theme/icons/tiff.png .tiff .tif
-              AddIcon /theme/icons/text.png .txt .nfo
-              AddIcon /theme/icons/video.png .asf .asx .avi .flv .mkv .mov .mp4 .mpg .rm .srt .swf .vob .wmv .m4v .f4v .f4p .ogv
-              AddIcon /theme/icons/xml.png .xml
-              AddIcon /theme/icons/zip.png .zip
-              DefaultIcon /theme/icons/default.png
-
-              HeaderName /theme/header.html
-              ReadmeName /theme/footer.html
-              IndexStyleSheet /theme/style.css
-            </Directory>
-          </Macro>
-        '';
-      };
-      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
-        '';
-      };
-    };
-
     system.activationScripts = {
       httpd = ''
         install -d -m 0755 /var/lib/acme/acme-challenge
@@ -417,8 +193,8 @@ in
       adminer = pkgs.callPackage ./commons/adminer.nix {};
     in ''
       mkdir -p $out/webapps
-      ln -s ${../../www} $out/webapps/_www
-      ln -s ${./apache/theme} $out/webapps/_theme
+      ln -s ${pkgs.webapps.apache-default.www} $out/webapps/_www
+      ln -s ${pkgs.webapps.apache-theme.theme} $out/webapps/_theme
       ln -s ${adminer.webRoot} $out/webapps/${adminer.apache.webappName}
       '';
 
@@ -437,26 +213,68 @@ in
         '';
     };
 
-    services.httpdProd = makeService "production" config.services.myWebsites.production;
-    services.myWebsites.production.modules = makeModules cfg;
-    services.myWebsites.production.extraConfig = makeExtraConfig cfg;
+    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.httpdInte = makeService "integration" config.services.myWebsites.integration;
-    services.myWebsites.integration.modules = makeModules cfg;
-    services.myWebsites.integration.extraConfig = makeExtraConfig cfg;
+    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.httpdTools = makeService "tools" config.services.myWebsites.tools;
-    services.myWebsites.tools.modules = makeModules cfg;
-    services.myWebsites.tools.extraConfig = makeExtraConfig cfg ++
-    [ ''
-        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
-      ''
-      ]
-    ;
+    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" ];
+      };
+    };
   };
 }