]> git.immae.eu Git - perso/Immae/Config/Nix.git/blobdiff - nixops/modules/task/default.nix
Move secrets module outside of nixops
[perso/Immae/Config/Nix.git] / nixops / modules / task / default.nix
index 2fd61aab0c48b9a4b53b0230aed8b589495a55e1..01d032da1d9f22c3d314344088a384f9f79bb041 100644 (file)
@@ -1,7 +1,7 @@
 { lib, pkgs, config, myconfig, mylibs, ... }:
 let
   cfg = config.services.myTasks;
-  vardir = config.services.taskserver.dataDir;
+  server_vardir = config.services.taskserver.dataDir;
   fqdn = "task.immae.eu";
   user = config.services.taskserver.user;
   env = myconfig.env.tools.task;
@@ -22,8 +22,8 @@ let
 
     silent_certtool -p \
       --bits 4096 \
-      --outfile "${vardir}/userkeys/$user.key.pem"
-    ${pkgs.gnused}/bin/sed -i -n -e '/^-----BEGIN RSA PRIVATE KEY-----$/,$p' "${vardir}/userkeys/$user.key.pem"
+      --outfile "${server_vardir}/userkeys/$user.key.pem"
+    ${pkgs.gnused}/bin/sed -i -n -e '/^-----BEGIN RSA PRIVATE KEY-----$/,$p' "${server_vardir}/userkeys/$user.key.pem"
 
     silent_certtool -c \
       --template "${pkgs.writeText "taskserver-ca.template" ''
@@ -32,18 +32,17 @@ let
         signing_key
         expiration_days = 3650
       ''}" \
-      --load-ca-certificate "${vardir}/keys/ca.cert" \
-      --load-ca-privkey "${vardir}/keys/ca.key" \
-      --load-privkey "${vardir}/userkeys/$user.key.pem" \
-      --outfile "${vardir}/userkeys/$user.cert.pem"
+      --load-ca-certificate "${server_vardir}/keys/ca.cert" \
+      --load-ca-privkey "${server_vardir}/keys/ca.key" \
+      --load-privkey "${server_vardir}/userkeys/$user.key.pem" \
+      --outfile "${server_vardir}/userkeys/$user.cert.pem"
     EOF
     chmod a+x $out/bin/taskserver-user-certs
     patchShebangs $out/bin/taskserver-user-certs
     '';
-  taskwarrior-web = pkgs.callPackage ./taskwarrior-web.nix {
-    inherit (mylibs) fetchedGithub;
-    inherit env;
-  };
+  taskwarrior-web = pkgs.webapps.taskwarrior-web;
+  socketsDir = "/run/taskwarrior-web";
+  varDir = "/var/lib/taskwarrior-web";
   taskwebPages = let
     uidPages = lib.attrsets.zipAttrs (
       lib.lists.flatten
@@ -87,6 +86,21 @@ in {
   };
 
   config = lib.mkIf cfg.enable {
+    secrets.keys = [{
+      dest = "webapps/tools-taskwarrior-web";
+      user = "wwwrun";
+      group = "wwwrun";
+      permissions = "0400";
+      text = ''
+          SetEnv TASKD_HOST          "${fqdn}:${toString config.services.taskserver.listenPort}"
+          SetEnv TASKD_VARDIR        "${server_vardir}"
+          SetEnv TASKD_LDAP_HOST     "ldaps://${env.ldap.host}"
+          SetEnv TASKD_LDAP_DN       "${env.ldap.dn}"
+          SetEnv TASKD_LDAP_PASSWORD "${env.ldap.password}"
+          SetEnv TASKD_LDAP_BASE     "${env.ldap.base}"
+          SetEnv TASKD_LDAP_FILTER   "${env.ldap.search}"
+        '';
+    }];
     security.acme.certs."eldiron".extraDomains.${fqdn} = null;
     services.myWebsites.tools.modules = [ "proxy_fcgi" "sed" ];
     services.myWebsites.tools.vhostConfs.task = {
@@ -101,19 +115,13 @@ in {
           <FilesMatch "\.php$">
             SetHandler "proxy:unix:/var/run/phpfpm/task.sock|fcgi://localhost"
           </FilesMatch>
-          SetEnv TASKD_HOST          "${fqdn}:${toString config.services.taskserver.listenPort}"
-          SetEnv TASKD_VARDIR        "${vardir}"
-          SetEnv TASKD_LDAP_HOST     "ldaps://${env.ldap.host}"
-          SetEnv TASKD_LDAP_DN       "${env.ldap.dn}"
-          SetEnv TASKD_LDAP_PASSWORD "${env.ldap.password}"
-          SetEnv TASKD_LDAP_BASE     "${env.ldap.base}"
-          SetEnv TASKD_LDAP_FILTER   "${env.ldap.search}"
+          Include /var/secrets/webapps/tools-taskwarrior-web
         </Directory>
         ''
         ''
         <Macro Taskwarrior %{folderName}>
-          ProxyPass        "unix://${taskwarrior-web.socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/"
-          ProxyPassReverse "unix://${taskwarrior-web.socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/"
+          ProxyPass        "unix://${socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/"
+          ProxyPassReverse "unix://${socketsDir}/%{folderName}.sock|http://localhost-%{folderName}/"
           ProxyPassReverse http://${fqdn}/
 
           SetOutputFilter Sed
@@ -168,7 +176,7 @@ in {
         ; Needed to avoid clashes in browser cookies (same domain)
         env[PATH] = "/etc/profiles/per-user/${user}/bin"
         php_value[session.name] = TaskPHPSESSID
-        php_admin_value[open_basedir] = "${./www}:/tmp:${vardir}:/etc/profiles/per-user/${user}/bin/"
+        php_admin_value[open_basedir] = "${./www}:/tmp:${server_vardir}:/etc/profiles/per-user/${user}/bin/"
       '';
     };
 
@@ -190,9 +198,35 @@ in {
     system.activationScripts.taskserver = {
       deps = [ "users" ];
       text = ''
-        install -m 0750 -o ${user} -g ${group} -d ${vardir}
-        install -m 0750 -o ${user} -g ${group} -d ${vardir}/userkeys
-        install -m 0750 -o ${user} -g ${group} -d ${vardir}/keys
+        install -m 0750 -o ${user} -g ${group} -d ${server_vardir}
+        install -m 0750 -o ${user} -g ${group} -d ${server_vardir}/userkeys
+        install -m 0750 -o ${user} -g ${group} -d ${server_vardir}/keys
+
+        if [ ! -e "${server_vardir}/keys/ca.key" ]; then
+          silent_certtool() {
+            if ! output="$("${pkgs.gnutls.bin}/bin/certtool" "$@" 2>&1)"; then
+              echo "GNUTLS certtool invocation failed with output:" >&2
+              echo "$output" >&2
+            fi
+          }
+
+          silent_certtool -p \
+            --bits 4096 \
+            --outfile "${server_vardir}/keys/ca.key"
+
+          silent_certtool -s \
+            --template "${pkgs.writeText "taskserver-ca.template" ''
+              cn = ${fqdn}
+              expiration_days = -1
+              cert_signing_key
+              ca
+            ''}" \
+            --load-privkey "${server_vardir}/keys/ca.key" \
+            --outfile "${server_vardir}/keys/ca.cert"
+
+          chown :${group} "${server_vardir}/keys/ca.key"
+          chmod g+r "${server_vardir}/keys/ca.key"
+        fi
       '';
     };
 
@@ -201,21 +235,25 @@ in {
       allowedClientIDs = [ "^task [2-9]" "^Mirakel [1-9]" ];
       inherit fqdn;
       listenHost = "::";
+      pki.manual.ca.cert = "${server_vardir}/keys/ca.cert";
+      pki.manual.server.cert = "/var/lib/acme/task/fullchain.pem";
+      pki.manual.server.crl = "/var/lib/acme/task/invalid.crl";
+      pki.manual.server.key = "/var/lib/acme/task/key.pem";
       requestLimit = 104857600;
     };
 
     system.activationScripts.taskwarrior-web = {
       deps = [ "users" ];
       text = ''
-        install -m 0755 -o ${user} -g ${group} -d ${taskwarrior-web.socketsDir}
-        install -m 0750 -o ${user} -g ${group} -d ${taskwarrior-web.varDir}
+        install -m 0755 -o ${user} -g ${group} -d ${socketsDir}
+        install -m 0750 -o ${user} -g ${group} -d ${varDir}
         ${builtins.concatStringsSep "\n" (lib.attrsets.mapAttrsToList
-          (k: v: "install -m 0750 -o ${user} -g ${group} -d ${taskwarrior-web.varDir}/${k}")
+          (k: v: "install -m 0750 -o ${user} -g ${group} -d ${varDir}/${k}")
           env.taskwarrior-web
         )}
-        if [ ! -f ${vardir}/userkeys/taskwarrior-web.cert.pem ]; then
+        if [ ! -f ${server_vardir}/userkeys/taskwarrior-web.cert.pem ]; then
           ${taskserver-user-certs}/bin/taskserver-user-certs taskwarrior-web
-          chown taskd:taskd ${vardir}/userkeys/taskwarrior-web.cert.pem ${vardir}/userkeys/taskwarrior-web.key.pem
+          chown taskd:taskd ${server_vardir}/userkeys/taskwarrior-web.cert.pem ${server_vardir}/userkeys/taskwarrior-web.key.pem
         fi
       '';
     };
@@ -225,10 +263,32 @@ in {
         credentials = "${userConfig.org}/${name}/${userConfig.key}";
         dateFormat = userConfig.date;
         taskrc = pkgs.writeText "taskrc" ''
-          data.location=${taskwarrior-web.varDir}/${name}
-          taskd.certificate=${vardir}/userkeys/taskwarrior-web.cert.pem
-          taskd.key=${vardir}/userkeys/taskwarrior-web.key.pem
-          taskd.ca=${vardir}/keys/server.cert
+          data.location=${varDir}/${name}
+          taskd.certificate=${server_vardir}/userkeys/taskwarrior-web.cert.pem
+          taskd.key=${server_vardir}/userkeys/taskwarrior-web.key.pem
+          # IdenTrust DST Root CA X3
+          # obtained here: https://letsencrypt.org/fr/certificates/
+          taskd.ca=${pkgs.writeText "ca.cert" ''
+            -----BEGIN CERTIFICATE-----
+            MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+            MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+            DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+            PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+            Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+            AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+            rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+            OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+            xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+            7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+            aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+            HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+            SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+            ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+            AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+            R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+            JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+            Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+            -----END CERTIFICATE-----''}
           taskd.server=${fqdn}:${toString config.services.taskserver.listenPort}
           taskd.credentials=${credentials}
           dateformat=${dateFormat}
@@ -240,12 +300,12 @@ in {
         path = [ pkgs.taskwarrior ];
 
         environment.TASKRC = taskrc;
-        environment.BUNDLE_PATH = "${taskwarrior-web.gems}/lib/ruby/gems/2.5.0";
+        environment.BUNDLE_PATH = "${taskwarrior-web.gems}/${taskwarrior-web.gems.ruby.gemPath}";
         environment.BUNDLE_GEMFILE = "${taskwarrior-web.gems.confFiles}/Gemfile";
         environment.LC_ALL = "fr_FR.UTF-8";
 
         script = ''
-          exec ${taskwarrior-web.gems}/lib/ruby/gems/2.5.0/bin/bundle exec thin start -R config.ru -S ${taskwarrior-web.socketsDir}/${name}.sock
+          exec ${taskwarrior-web.gems}/${taskwarrior-web.gems.ruby.gemPath}/bin/bundle exec thin start -R config.ru -S ${socketsDir}/${name}.sock
         '';
 
         serviceConfig = {
@@ -254,14 +314,14 @@ in {
           Restart = "always";
           TimeoutSec = 60;
           Type = "simple";
-          WorkingDirectory = taskwarrior-web.rubyRoot;
+          WorkingDirectory = taskwarrior-web;
         };
 
-        unitConfig.RequiresMountsFor = taskwarrior-web.varDir;
+        unitConfig.RequiresMountsFor = varDir;
       }) env.taskwarrior-web) // {
         taskserver-ca.postStart = ''
-          chown :${group} "${vardir}/keys/ca.key"
-          chmod g+r "${vardir}/keys/ca.key"
+          chown :${group} "${server_vardir}/keys/ca.key"
+          chmod g+r "${server_vardir}/keys/ca.key"
         '';
       };