paivana-httpd.service (4323B)
1 [Unit] 2 Description=Paivana Taler paywall reverse proxy 3 After=network.target 4 Requires=paivana-httpd.socket 5 6 # Startup is deliberately fail-closed: paivana-httpd refuses to serve 7 # anything until it has loaded every paywall template from the merchant 8 # backend, because a template it could not load is a set of URLs it 9 # would hand out for free. A backend that is merely restarting must 10 # therefore be ridden out by restarting us, which is what the back-off 11 # below is for -- so the start rate limiter must NOT be allowed to give 12 # up and leave the unit failed. A configuration error is the opposite 13 # case and is handled by RestartPreventExitStatus. 14 StartLimitIntervalSec=0 15 16 [Service] 17 User=paivana-httpd 18 Type=simple 19 Restart=always 20 RestartMode=direct 21 22 # Exponential back-off: 1s, 2s, 4s ... capped at 5min. A merchant 23 # backend that comes back after a minute costs us a minute of downtime, 24 # while one that is gone for a day does not spin. 25 RestartSec=1s 26 RestartSteps=10 27 RestartMaxDelaySec=300s 28 29 # 9 is EXIT_NO_RESTART, 6 is EXIT_NOTCONFIGURED (src/include/platform.h). 30 # Neither is transient: retrying a missing DESTINATION_BASE_URL or an 31 # unparseable TRUSTED_PROXIES only fills the journal. 32 RestartPreventExitStatus=6 9 33 34 # Recycle hourly to bound process-lifetime library/cache growth. The 3600 s 35 # value is operational hygiene rather than a request deadline. Paivana first 36 # quiesces its copy of the socket and drains accepted requests; the socket unit 37 # continues queueing new connections for the replacement process. SECRET is 38 # mandatory and stable, so the restart does not invalidate paid access. 39 RuntimeMaxSec=3600s 40 41 # Paivana's current GNUnet/Taler event loop uses select(), whose fd_set has 42 # 1024 entries on this platform. Raising this value would let libraries open 43 # descriptors Paivana cannot poll. The default CONNECTION_LIMIT=384 budgets 44 # two descriptors per request and leaves the remaining 256 for listeners, 45 # scheduler/library state, resolver activity and transient overlap. 46 LimitNOFILE=1024 47 48 # SHUTDOWN_GRACE_PERIOD defaults to 60 s. The extra 15 s lets Paivana cancel 49 # remaining curl work, stop MHD and release templates before systemd sends 50 # SIGKILL; keep this value above the configured application grace period. 51 TimeoutStopSec=75s 52 # -f: we are served over a Unix socket by nginx/Apache (see the 53 # shipped site configs), so the client address has to come from the 54 # forwarding headers -- a Unix peer has no address of its own, and 55 # without this every visitor would be indistinguishable. It is only 56 # safe because those configs overwrite the headers rather than 57 # appending to a client-supplied value; do not enable it for a 58 # paivana-httpd that is reachable directly. 59 ExecStart=/usr/bin/paivana-httpd -c /etc/paivana/paivana.conf -f -L INFO 60 61 StandardOutput=journal 62 StandardError=journal 63 64 # libgnunetcurl records every completed outbound request at INFO. That is 65 # useful while debugging, but turns the production journal into an access log 66 # for every request Paivana proxies. Keep INFO for Paivana's lifecycle and 67 # recovery messages while limiting that library source file to actionable 68 # severities. The merchant client also emits one generic warning for every 69 # failed order poll; Paivana's sampled warning has timing, concurrency and fd 70 # context, so suppress the duplicate library warning in production. The final 71 # rule deliberately restores INFO for every other source file. 72 Environment="GNUNET_FORCE_LOG=;curl.c;;;WARNING/;merchant_api_get-private-orders-ORDER_ID.c;;;ERROR/;;;;INFO" 73 74 # Hardening. paivana-httpd needs a listening socket handed to it, 75 # outbound TCP to the merchant backend and the origin, and read access 76 # to its own configuration -- nothing else. DynamicUser is deliberately 77 # NOT used: paivana-httpd.socket names SocketUser=paivana-httpd, which 78 # needs a stable account. 79 PrivateTmp=yes 80 PrivateDevices=yes 81 ProtectSystem=strict 82 ProtectHome=yes 83 ProtectKernelTunables=yes 84 ProtectKernelModules=yes 85 ProtectControlGroups=yes 86 NoNewPrivileges=yes 87 RestrictSUIDSGID=yes 88 RestrictNamespaces=yes 89 LockPersonality=yes 90 MemoryDenyWriteExecute=yes 91 RestrictRealtime=yes 92 RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 93 CapabilityBoundingSet= 94 SystemCallArchitectures=native 95 SystemCallFilter=@system-service 96 SystemCallErrorNumber=EPERM 97 98 [Install] 99 WantedBy=multi-user.target