{ 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"; }; }