X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=nixops%2Fmodules%2Ftask%2Fdefault.nix;h=01d032da1d9f22c3d314344088a384f9f79bb041;hb=1a7188052f235fb632700478fad0108e4306107d;hp=2fd61aab0c48b9a4b53b0230aed8b589495a55e1;hpb=99b0b74ac87c77b5f39e21c65141d8fcc6753ca2;p=perso%2FImmae%2FConfig%2FNix.git diff --git a/nixops/modules/task/default.nix b/nixops/modules/task/default.nix index 2fd61aa..01d032d 100644 --- a/nixops/modules/task/default.nix +++ b/nixops/modules/task/default.nix @@ -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 { SetHandler "proxy:unix:/var/run/phpfpm/task.sock|fcgi://localhost" - 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 '' '' - 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" ''; };