From ffac1727b92167ca6847b7ae3adc71f091d8048f Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Sun, 10 Jul 2022 11:51:34 +0200 Subject: ... --- hosts/surtr/http/default.nix | 67 +++++++++++++++ hosts/surtr/http/webdav/default.nix | 96 ++++++++++++++++++++++ hosts/surtr/http/webdav/py-webdav/.gitignore | 1 + hosts/surtr/http/webdav/py-webdav/VERSION | 1 + hosts/surtr/http/webdav/py-webdav/setup.py | 17 ++++ .../surtr/http/webdav/py-webdav/webdav/__init__.py | 1 + hosts/surtr/http/webdav/py-webdav/webdav/webdav.py | 5 ++ 7 files changed, 188 insertions(+) create mode 100644 hosts/surtr/http/default.nix create mode 100644 hosts/surtr/http/webdav/default.nix create mode 100644 hosts/surtr/http/webdav/py-webdav/.gitignore create mode 100644 hosts/surtr/http/webdav/py-webdav/VERSION create mode 100644 hosts/surtr/http/webdav/py-webdav/setup.py create mode 100644 hosts/surtr/http/webdav/py-webdav/webdav/__init__.py create mode 100644 hosts/surtr/http/webdav/py-webdav/webdav/webdav.py (limited to 'hosts/surtr/http') diff --git a/hosts/surtr/http/default.nix b/hosts/surtr/http/default.nix new file mode 100644 index 00000000..a77252ff --- /dev/null +++ b/hosts/surtr/http/default.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: +{ + imports = [ + ./webdav + ]; + + config = { + services.nginx = { + enable = true; + # package = pkgs.nginxQuic; + recommendedGzipSettings = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + sslDhparam = config.security.dhparams.params.nginx.path; + commonHttpConfig = '' + ssl_ecdh_curve X25519:prime256v1:secp521r1:secp384r1; + + log_format main + '$remote_addr "$remote_user" ' + '"$host" "$request" $status $bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '$gzip_ratio'; + + access_log syslog:server=unix:/dev/log main; + error_log syslog:server=unix:/dev/log info; + + client_body_temp_path /run/nginx-client-bodies; + ''; + additionalModules = with pkgs.nginxModules; [ dav pam ]; + }; + systemd.services.nginx = { + preStart = lib.mkForce config.services.nginx.preStart; + serviceConfig = { + SupplementaryGroups = [ "shadow" ]; + ExecReload = lib.mkForce "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; + RuntimeDirectory = lib.mkForce [ "nginx" "nginx-client-bodies" ]; + RuntimeDirectoryMode = "0750"; + + 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 = { + enable = true; + plugins = ["python3"]; + instance = { + type = "emperor"; + vassals = {}; + }; + }; + }; +} diff --git a/hosts/surtr/http/webdav/default.nix b/hosts/surtr/http/webdav/default.nix new file mode 100644 index 00000000..f0aec1e9 --- /dev/null +++ b/hosts/surtr/http/webdav/default.nix @@ -0,0 +1,96 @@ +{ config, libs, pkgs, flakeInputs, ... }: +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.* + psycopg ==3.0.* + WsgiDAV ==4.0.* + ''; + }; +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; + 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.domains."webdav.141.li" = { + certCfg = { + postRun = '' + ${pkgs.systemd}/bin/systemctl try-restart 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" + ]; + + + 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"; + }; + }; +} diff --git a/hosts/surtr/http/webdav/py-webdav/.gitignore b/hosts/surtr/http/webdav/py-webdav/.gitignore new file mode 100644 index 00000000..ed8ebf58 --- /dev/null +++ b/hosts/surtr/http/webdav/py-webdav/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/hosts/surtr/http/webdav/py-webdav/VERSION b/hosts/surtr/http/webdav/py-webdav/VERSION new file mode 100644 index 00000000..6e8bf73a --- /dev/null +++ b/hosts/surtr/http/webdav/py-webdav/VERSION @@ -0,0 +1 @@ +0.1.0 diff --git a/hosts/surtr/http/webdav/py-webdav/setup.py b/hosts/surtr/http/webdav/py-webdav/setup.py new file mode 100644 index 00000000..dbe345c1 --- /dev/null +++ b/hosts/surtr/http/webdav/py-webdav/setup.py @@ -0,0 +1,17 @@ +import setuptools + +with open('VERSION', 'r', encoding='utf-8') as version_file: + version = version_file.read().strip() + +setuptools.setup( + name="py-webdav", + version=version, + package_dir={"": "."}, + packages=setuptools.find_packages(), + python_requires=">=3.8", + install_requires=[ + "PyNaCl ==1.5.*", + "psycopg ==3.0.*", + "WsgiDAV ==4.0.*", + ], +) diff --git a/hosts/surtr/http/webdav/py-webdav/webdav/__init__.py b/hosts/surtr/http/webdav/py-webdav/webdav/__init__.py new file mode 100644 index 00000000..398378e2 --- /dev/null +++ b/hosts/surtr/http/webdav/py-webdav/webdav/__init__.py @@ -0,0 +1 @@ +from .webdav import app diff --git a/hosts/surtr/http/webdav/py-webdav/webdav/webdav.py b/hosts/surtr/http/webdav/py-webdav/webdav/webdav.py new file mode 100644 index 00000000..783f5d82 --- /dev/null +++ b/hosts/surtr/http/webdav/py-webdav/webdav/webdav.py @@ -0,0 +1,5 @@ +def app(env, start_response): + start_response('200 Success', [('Content-Type', 'text/plain; charset=utf-8')]) + return [ bytes(f'{key}: {value}\n', 'utf8') + for key, value in env.items() + ] -- cgit v1.2.3