aboutsummaryrefslogblamecommitdiff
path: root/virtual/eldiron.nix
blob: ed414298a2d44334c2af1368a0631d8b4303f5cd (plain) (tree)
1
2
3
4
5
6
7
8
9
10





                                    



                                       


                      
                                                  




























                                                                                



                                                                                                     

                                 
                                  



          

                                                             





                          
                                             






















                                                                               
                    


                                       







                                            



















                                                                                 










                                                 
                                                        
                                           
            
          




                                                        
                                           
                                        

            


















                                                                            
























                                                                                        
                







                                                                          
                         
                   
                






































                                                                          
{
  network = {
    description = "Immae's network";
    enableRollback = true;
  };

  eldiron = { config, pkgs, ... }:
    let mypkgs = import ./packages.nix;
    in
  {
    networking = {
      firewall = {
        enable = true;
        allowedTCPPorts = [ 22 80 443 3306 5432 ];
      };
    };

    deployment = {
      targetEnv = "hetzner";
      hetzner = {
        #robotUser = "defined in HETZNER_ROBOT_USER";
        #robotPass = "defined in HETZNER_ROBOT_PASS";
        mainIPv4 = "176.9.151.89";
        partitions = ''
          clearpart --all --initlabel --drives=sda,sdb

          part swap1 --recommended --label=swap1 --fstype=swap --ondisk=sda
          part swap2 --recommended --label=swap2 --fstype=swap --ondisk=sdb

          part raid.1 --grow --ondisk=sda
          part raid.2 --grow --ondisk=sdb

          raid / --level=1 --device=md0 --fstype=ext4 --label=root raid.1 raid.2
        '';
      };
    };

    # FIXME: how to run it? currently set as timer
    security.acme.certs = {
      "eldiron" = {
        webroot = "/var/lib/acme/acme-challenge";
        email = "ismael@bouya.org";
        domain = "eldiron.immae.eu";
        plugins = [ "cert.pem" "chain.pem" "fullchain.pem" "full.pem" "key.pem" "account_key.json" ];
        postRun = ''
          "systemctl reload httpd.service"
        '';
        extraDomains = {
          "db-1.immae.eu" = null;
          "tools.immae.eu" = null;
        };
      };
    };

    services.ympd = mypkgs.ympd.config // { enable = true; };

    # FIXME: open_basedir
    services.phpfpm = {
      extraConfig = ''
        log_level = notice
        '';
      poolConfigs = {
        adminer = mypkgs.adminer.phpFpm.pool;
        www = ''
          listen = /var/run/phpfpm/www.sock
          user = wwwrun
          group = wwwrun
          listen.owner = wwwrun
          listen.group = wwwrun
          pm = ondemand
          pm.max_children = 5
          pm.process_idle_timeout = 60
          ;php_admin_flag[log_errors] = on
          php_admin_value[open_basedir] = "/var/www"
          '';
      };
    };

    services.httpd = let
      withSSL = domain: {
        enableSSL = true;
        sslServerCert = "/var/lib/acme/${domain}/full.pem"; # FIXME: cert only?
        sslServerKey = "/var/lib/acme/${domain}/key.pem";
        sslServerChain = "/var/lib/acme/${domain}/fullchain.pem";
      };
    in rec {
      enable = true;
      logPerVirtualHost = true;
      multiProcessingModule = "worker";
      adminAddr = "httpd@immae.eu";
      # FIXME: http2
      extraModules = pkgs.lib.lists.unique (
        mypkgs.adminer.apache.modules ++
        [
          "macro"
          "ldap"
          "authnz_ldap"
        ]);
      extraConfig = ''
        <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
            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>
        '';
      virtualHosts = [
        (withSSL "eldiron" // {
          listen = [ { ip = "*"; port = 443; } ];
          hostName = "eldiron.immae.eu";
          # FIXME: directory needs to exist
          documentRoot = "/var/www";
        })
        (withSSL "eldiron" // {
          listen = [ { ip = "*"; port = 443; } ];
          hostName = "db-1.immae.eu";
          documentRoot = null;
          extraConfig = builtins.concatStringsSep "\n" [
            mypkgs.adminer.apache.vhostConf
          ];
        })
        (withSSL "eldiron" // {
          listen = [ { ip = "*"; port = 443; } ];
          hostName = "tools.immae.eu";
          documentRoot = null;
          extraConfig = builtins.concatStringsSep "\n" [
            mypkgs.adminer.apache.vhostConf
            mypkgs.ympd.apache.vhostConf
          ];
        })
        { # Should go last, default fallback
          listen = [ { ip = "*"; port = 80; } ];
          hostName = "redirectSSL";
          serverAliases = [ "*" ];
          enableSSL = false;
          # FIXME: directory needs to exist
          documentRoot = "/var/lib/acme/acme-challenge";
          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
            '';
        }
        ];
    };

    # FIXME: environment variables ?
    security.pam.services = let
      pam_ldap = pkgs.pam_ldap;
      pam_ldap_mysql = pkgs.writeText "mysql.conf" ''
        host ldap.immae.eu
        base dc=immae,dc=eu
        binddn cn=mysql,cn=pam,ou=services,dc=immae,dc=eu
        bindpw ${builtins.getEnv "NIXOPS_MYSQL_PAM_PASSWORD"}
        pam_filter memberOf=cn=users,cn=mysql,cn=pam,ou=services,dc=immae,dc=eu
        '';
    in [
      {
        name = "mysql";
        text = ''
          # https://mariadb.com/kb/en/mariadb/pam-authentication-plugin/
          auth    required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_mysql}
          account required ${pam_ldap}/lib/security/pam_ldap.so config=${pam_ldap_mysql}
          '';
      }
    ];

    # FIXME: initial sync
    # FIXME: backup
    # FIXME: restart after pam
    # FIXME: pam access doesn’t work (because of php module)
    # FIXME: ssl
    services.mysql = rec {
      enable = true;
      package = pkgs.mariadb.overrideAttrs(old: rec {
        cmakeFlags = old.cmakeFlags ++ [ "-DWITH_AUTHENTICATION_PAM=ON" ];
        buildInputs = old.buildInputs ++ [ pkgs.pam ];
      });
    };

    # FIXME: initial sync
    # FIXME: backup
    # FIXME: ssl
    services.postgresql = rec {
      enable = true;
      package = pkgs.postgresql100.overrideAttrs(old: rec {
        passthru = old.passthru // { psqlSchema = "11.0"; };
        name = "postgresql-11.1";
        src = pkgs.fetchurl {
          url = "mirror://postgresql/source/v11.1/${name}.tar.bz2";
          sha256 = "026v0sicsh7avzi45waf8shcbhivyxmi7qgn9fd1x0vl520mx0ch";
        };
      });
      enableTCPIP = true;
      extraConfig = ''
        max_connections = 100
        wal_level = logical
        shared_buffers = 128MB
        max_wal_size = 1GB
        min_wal_size = 80MB
        log_timezone = 'Europe/Paris'
        datestyle = 'iso, mdy'
        timezone = 'Europe/Paris'
        lc_messages = 'en_US.UTF-8'
        lc_monetary = 'en_US.UTF-8'
        lc_numeric = 'en_US.UTF-8'
        lc_time = 'en_US.UTF-8'
        default_text_search_config = 'pg_catalog.english'
        # ssl = on
        # ssl_cert_file = '/var/lib/acme/eldiron/fullchain.pem'
        # ssl_key_file = '/var/lib/acme/eldiron/key.pem'
        '';
      authentication = ''
        local	all	postgres				ident
        local	all	all					md5
        host	all	all		178.33.252.96/32	md5
        host	all	all		188.165.209.148/32	md5
        #host	all	all		all			pam
      '';
    };
  };
}