{ pkgs, inputs', lib, config, ... }: let inherit (lib) singleton mkForce ; certs = config.services.acme-sh.certs; in { users.users.wwwrun = { group = "wwwrun"; isSystemUser = true; uid = config.ids.uids.wwwrun; }; users.groups.wwwrun = { gid = config.ids.gids.wwwrun; }; systemd.services.apache-proxy = let apacheConfiguration = inputs'.nixng.nglib.generators.toApache [ { LoadModule = [ ["mpm_event_module" "modules/mod_mpm_event.so"] ["log_config_module" "modules/mod_log_config.so"] ["unixd_module" "modules/mod_unixd.so"] ["authz_core_module" "modules/mod_authz_core.so"] ["authn_core_module" "modules/mod_authn_core.so"] ["dir_module" "modules/mod_dir.so"] ["mime_module" "modules/mod_mime.so"] ["proxy_module" "modules/mod_proxy.so"] ["proxy_http_module" "modules/mod_proxy_http.so"] ["access_compat_module" "modules/mod_access_compat.so"] ["proxy_connect_module" "modules/mod_proxy_connect.so"] ["authn_file_module" "modules/mod_authn_file.so"] ["authz_user_module" "modules/mod_authz_user.so"] ["authz_host_module" "modules/mod_authz_host.so"] ["auth_basic_module" "modules/mod_auth_basic.so"] ["ssl_module" "modules/mod_ssl.so"] ]; } { Listen = "0.0.0.0:8883"; ServerRoot = "/var/empty"; ServerName = "altra"; PidFile = "/run/apache/apache.pid"; DocumentRoot = "/var/empty"; } { ErrorLog = "/var/log/apache/error.log"; TransferLog = "/var/log/apache/access.log"; } { MaxConnectionsPerChild = 1024; MaxMemFree = 8192; ThreadsPerChild = 64; MaxRequestWorkers = 2048; ServerLimit = 32; AsyncRequestWorkerFactor = 8; } { AddType = singleton [ "image/svg+xml" "svg" "svgz" ]; AddEncoding = [ "gzip" "svgz" ]; TypesConfig = "${pkgs.apacheHttpd}/conf/mime.types"; } { Directory."/" = { Require = ["all" "denied"]; Options = "SymlinksIfOwnerMatch"; }; VirtualHost."*:8883" = [ { ProxyRequests = "on"; AddDefaultCharset = "off"; AllowCONNECT = ["443" "8448" "8433" "8478" "3236" "8080"]; } { ServerName = "synapse-proxy.in.redalder.org"; SSLEngine = "on"; SSLCertificateFile = certs.apache-proxy.certPath; SSLCertificateKeyFile = certs.apache-proxy.keyPath; SSLCipherSuite = "HIGH:!aNULL:!MD5"; } { Proxy."*" = { Require = ["all" "denied"]; }; } { ProxyMatch."^([a-zA-Z\-_0-9]+\.)+[a-zA-Z\-_0-9]*:(443|8448|8443|8478|3236|8080).*$" = { AuthType = "Basic"; AuthName = "\"Password Required\""; AuthUserFile = "/var/secrets/htpasswd"; RequireAll."" = { Require = [ ["user synapse"] ["method CONNECT"] ]; RequireAny."" = { Require = [ ["ip 10.64.0.2"] ]; }; }; }; } { ProxyMatch."^http:\/\/([a-zA-Z\-_0-9]+\.)+[a-zA-Z\-_0-9]*(|:(80|8080))$" = { AuthType = "Basic"; AuthName = "\"Password Required\""; AuthUserFile = "/var/secrets/htpasswd"; RequireAll."" = { Require = [ ["user synapse"] ["not method CONNECT"] ]; RequireAny."" = { Require = [ ["ip 10.64.0.2"] ]; }; }; }; } ]; } ]; in { serviceConfig = { Type = "forking"; Restart = "always"; RestartSec = "10s"; # User and group User = "wwwrun"; Group = "wwwrun"; # Runtime directory and mode RuntimeDirectory = "apache"; RuntimeDirectoryMode = "0750"; # Cache directory and mode CacheDirectory = "apache"; CacheDirectoryMode = "0750"; # Logs directory and mode LogsDirectory = "apache"; LogsDirectoryMode = "0750"; # Proc filesystem ProcSubset = "pid"; ProtectProc = "invisible"; # New file permissions UMask = "0027"; # 0640 / 0750 # Capabilities AmbientCapabilities = ["CAP_NET_BIND_SERVICE" "CAP_SYS_RESOURCE"]; CapabilityBoundingSet = ["CAP_NET_BIND_SERVICE" "CAP_SYS_RESOURCE"]; # Security NoNewPrivileges = true; # Sandboxing (sorted by occurrence in https://www.freedesktop.org/software/systemd/man/systemd.exec.html) ProtectSystem = "strict"; ProtectHome = true; PrivateTmp = true; PrivateDevices = true; ProtectHostname = true; ProtectClock = true; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectKernelLogs = true; ProtectControlGroups = true; RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; RestrictNamespaces = true; LockPersonality = true; MemoryDenyWriteExecute = true; RestrictRealtime = true; RestrictSUIDSGID = true; RemoveIPC = true; PrivateMounts = true; # System Call Filtering SystemCallArchitectures = "native"; SystemCallFilter = ["~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid ~@ipc"]; }; wantedBy = ["multi-user.target"]; script = '' ls /proc/self/fd /dev ${pkgs.apacheHttpd}/bin/httpd -f ${pkgs.writeText "apache.conf" apacheConfiguration} ''; }; services.acme-sh.certs.apache-proxy = { production = true; user = "wwwrun"; domains."synapse-proxy.in.redalder.org" = "dns_hetzner"; mainDomain = "synapse-proxy.in.redalder.org"; postRun = "systemctl try-reload-or-restart --no-block apache-proxy.service"; }; systemd.services."acme-sh-apache-proxy" = { serviceConfig.EnvironmentFile = mkForce "/var/secrets/hetzner.env"; }; }