aboutsummaryrefslogblamecommitdiff
path: root/virtual/modules/websites.nix
blob: cbd7de07926b4083694ba690e2c36c86774d653b (plain) (tree)
1
2
3
                                             

                                   






















































                                                                                                







                                 




                                                                                                                                                


                                 

                                                                            



























































































                                                                                                                     









                                                                                                                                                                     

    
{ lib, pkgs, config, mylibs, myconfig, ... }:
let
  cfg = config.services.myWebsites;
  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}/fullchain.pem";
      logFormat = "combinedVhost";
      listen = [
        { ip = cfg.ip;  port = 443; }
      ];
      hostName = builtins.head vhostConf.hosts;
      serverAliases = builtins.tail vhostConf.hosts or [];
      documentRoot = vhostConf.root;
      extraConfig = builtins.concatStringsSep "\n" vhostConf.extraConfig;
    };
  in rec {
    enable = true;
    listen = [
      { ip = cfg.ip;  port = 443; }
    ];
    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 = pkgs.lib.attrsets.mapAttrsToList (n: v: toVhost v) cfg.vhostConfs;
  };
  makeServiceOptions = name: ip: {
    enable = lib.mkEnableOption "enable websites in ${name}";
    ip = lib.mkOption {
      type = lib.types.string;
      default = ip;
      description = "${name} ip to listen to";
    };
    modules = lib.mkOption {
      type = lib.types.listOf (lib.types.str);
      default = [];
    };
    extraConfig = lib.mkOption {
      type = lib.types.listOf (lib.types.lines);
      default = [];
    };
    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 = []; };
        };
      });
    };
  };
in
{
  imports = [
    ./websites/chloe.nix
    ./websites/ludivine.nix
    ./websites/aten.nix
    ./websites/piedsjaloux.nix
    ./websites/connexionswing.nix
    # built using:
    # sed -e "s/services\.httpd/services\.httpdProd/g" .nix-defexpr/channels/nixpkgs/nixos/modules/services/web-servers/apache-httpd/default.nix
    # And removed users / groups
    ./websites/apache/httpd_prod.nix
    ./websites/apache/httpd_inte.nix
  ];

  options.services.myWebsites = {
    production = makeServiceOptions "production" myconfig.ips.production;
    integration = makeServiceOptions "integration" myconfig.ips.integration;

    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 = {
    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.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.apacheConfig = {
      gzip = {
        modules = [ "deflate" "filter" ];
        extraConfig = ''
          AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript
        '';
      };
      macros = {
        modules = [ "macro" ];
      };
      ldap = {
        modules = [ "ldap" "authnz_ldap" ];
        # FIXME: starttls
        extraConfig = assert mylibs.checkEnv "NIXOPS_HTTP_LDAP_PASSWORD"; ''
          <IfModule ldap_module>
            LDAPSharedCacheSize 500000
            LDAPCacheEntries 1024
            LDAPCacheTTL 600
            LDAPOpCacheEntries 1024
            LDAPOpCacheTTL 600
          </IfModule>

          <Macro LDAPConnect>
            <IfModule authnz_ldap_module>
              AuthLDAPURL          ldap://ldap.immae.eu:389/dc=immae,dc=eu STARTTLS
              AuthLDAPBindDN       cn=httpd,ou=services,dc=immae,dc=eu
              AuthLDAPBindPassword "${builtins.getEnv "NIXOPS_HTTP_LDAP_PASSWORD"}"
              AuthType             Basic
              AuthName             "Authentification requise (Acces LDAP)"
              AuthBasicProvider    ldap
            </IfModule>
          </Macro>

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

    # FIXME: logrotate
    # FIXME: ipv6
    services.httpdProd = makeService "production" config.services.myWebsites.production;
    services.myWebsites.production.modules = pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules or []) cfg.apacheConfig);
    services.myWebsites.production.extraConfig = (builtins.filter (x: x != null) (pkgs.lib.attrsets.mapAttrsToList (n: v: v.extraConfig or null) cfg.apacheConfig));

    services.httpdInte = makeService "integration" config.services.myWebsites.integration;
    services.myWebsites.integration.modules = pkgs.lib.lists.flatten (pkgs.lib.attrsets.mapAttrsToList (n: v: v.modules or []) cfg.apacheConfig);
    services.myWebsites.integration.extraConfig = (builtins.filter (x: x != null) (pkgs.lib.attrsets.mapAttrsToList (n: v: v.extraConfig or null) cfg.apacheConfig));
  };
}