[Unit] Description=shithub web server After=network-online.target postgresql.service Wants=network-online.target Requires=postgresql.service [Service] Type=simple User=shithub Group=shithub EnvironmentFile=/etc/shithub/web.env # Run pending migrations BEFORE starting. ExecStartPre failure # prevents the unit from starting (correct behavior for a bad # migration). Recovery is documented in runbooks/upgrade.md. ExecStartPre=/usr/local/bin/shithubd migrate up ExecStart=/usr/local/bin/shithubd web Restart=on-failure RestartSec=2 LimitNOFILE=65535 # Hardening — match systemd-analyze security defaults where they # don't conflict with the app's needs (writes to data root, opens # port 8080). NoNewPrivileges=yes ProtectSystem=strict ProtectHome=yes PrivateTmp=yes ReadWritePaths=/data /var/lib/shithub ProtectKernelTunables=yes ProtectKernelModules=yes ProtectKernelLogs=yes ProtectControlGroups=yes RestrictNamespaces=yes RestrictRealtime=yes # RestrictSUIDSGID intentionally OFF: `git init --bare --shared=group` # (used by InitBare for every new bare repo) calls chmod g+s on the # directories it creates so cross-user writes (shithub user via the # HTTPS path, git user via SSH-git) inherit the shared group on new # pack files. With RestrictSUIDSGID=yes the kernel returned EPERM and # git emitted "Could not make .../branches/ writable by group", so # repo creation broke for any new owner namespace whose parent dir # wasn't pre-staged. shithubd doesn't write executable files to disk, # so the security loss is small; the alternative (stripping # --shared=group and chmod'ing perms by hand) re-introduces the # original SR2 #287 bug pattern. LockPersonality=yes MemoryDenyWriteExecute=yes SystemCallArchitectures=native [Install] WantedBy=multi-user.target