summaryrefslogtreecommitdiff
path: root/hosts/surtr/http/webdav/default.nix
blob: f94935eebf258201d31da9610ec641199150e083 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
{ config, lib, pkgs, flakeInputs, ... }:

with lib;

let
  webdavSocket = config.services.uwsgi.runDir + "/webdav.sock";

  webdavApp = flakeInputs.mach-nix.lib.${config.nixpkgs.system}.buildPythonPackage {
    ignoreDataOutdated = true;
    pname = "py-webdav";
    version = builtins.readFile ./py-webdav/VERSION;
    src = ./py-webdav;
    python = "python3";
    requirements = ''
      PyNaCl ==1.5.*
      WsgiDAV ==4.0.*
    '';
    # psycopg >=3.0.15,<3.1
    # _.psycopg.patches = [];
  };
in {
  config = {
    security.pam.services."webdav".text = ''
      auth requisite  pam_succeed_if.so user ingroup webdav quiet_success
      auth required   pam_unix.so likeauth nullok nodelay quiet
      account sufficient pam_unix.so quiet
    '';
    users.groups."webdav" = {};

    services.nginx = {
      # upstreams."py-webdav" = {
      #   servers = {
      #     "unix://${webdavSocket}" = {};
      #   };
      # };

      virtualHosts."webdav.141.li" = {
        forceSSL = true;
        kTLS = true;
        http3 = true;
        sslCertificate = "/run/credentials/nginx.service/webdav.141.li.pem";
        sslCertificateKey = "/run/credentials/nginx.service/webdav.141.li.key.pem";
        sslTrustedCertificate = "/run/credentials/nginx.service/webdav.141.li.chain.pem";
        locations = {
          "/".extraConfig = ''
            root /srv/files/$remote_user;

            auth_pam "WebDAV";
            auth_pam_service_name "webdav";
          '';

          # "/py/".extraConfig = ''
          #   rewrite ^/py(.*) $1 break;

          #   include ${config.services.nginx.package}/conf/uwsgi_params;
          #   uwsgi_param SCRIPT_NAME /py;
          #   uwsgi_pass py-webdav;
          # '';
        };
        extraConfig = ''
          dav_methods     PUT DELETE MKCOL COPY MOVE;
          dav_ext_methods PROPFIND OPTIONS;
          dav_access      user:rw;
          autoindex on;

          client_max_body_size    0;
          create_full_put_path    on;

          add_header Strict-Transport-Security "max-age=63072000" always;
        '';
      };
    };
    security.acme.rfc2136Domains."webdav.141.li" = {
      restartUnits = ["nginx.service"];
    };

    systemd.services.nginx.serviceConfig = {
      LoadCredential = [
        "webdav.141.li.key.pem:${config.security.acme.certs."webdav.141.li".directory}/key.pem"
        "webdav.141.li.pem:${config.security.acme.certs."webdav.141.li".directory}/fullchain.pem"
        "webdav.141.li.chain.pem:${config.security.acme.certs."webdav.141.li".directory}/chain.pem"
      ];

      NoNewPrivileges = lib.mkForce false;
      PrivateDevices = lib.mkForce false;
      ProtectHostname = lib.mkForce false;
      ProtectKernelTunables = lib.mkForce false;
      ProtectKernelModules = lib.mkForce false;
      RestrictAddressFamilies = lib.mkForce [ ];
      LockPersonality = lib.mkForce false;
      MemoryDenyWriteExecute = lib.mkForce false;
      RestrictRealtime = lib.mkForce false;
      RestrictSUIDSGID = lib.mkForce false;
      SystemCallArchitectures = lib.mkForce "";
      ProtectClock = lib.mkForce false;
      ProtectKernelLogs = lib.mkForce false;
      RestrictNamespaces = lib.mkForce false;
      SystemCallFilter = lib.mkForce "";
      ReadWritePaths = [ "/srv/files" ];
    };


    # services.uwsgi.instance.vassals.webdav = {
    #   type = "normal";
    #   socket = webdavSocket;
    #   listen = 1024;
    #   master = true;
    #   vacuum = true;
    #   chown-socket = "${config.services.nginx.user}:${config.services.uwsgi.group}";

    #   plugins = ["python3"];
    #   pythonPackages = self: [webdavApp];
    #   module = "webdav";
    #   callable = "app";
    # };
  };
}