Linux
Supported: kernel 4.4+, glibc-based distros with systemd. Tested on Ubuntu 22.04+, Debian 12, Fedora 39+. Architectures: amd64, arm64.
Install
Section titled “Install”-
Open a shell.
-
Run the installer:
Terminal window curl -sSL https://proxy.sotatek.works/releases/download/latest/install.sh | bashexport PATH="$HOME/.local/bin:$PATH" && hash -rThe script downloads the matching binary, verifies the SHA256 checksum, places it under
/usr/local/bin/sotatek-proxy, and registers the machine-wide systemd service (it will ask forsudoat that step). The service starts immediately and on boot. -
Verify the daemon is up:
Terminal window sudo sotatek-proxy statuscurl http://127.0.0.1:3817/_proxy/healthz
-
Clone the repository:
Terminal window git clone https://github.com/sotatek-dev/sotatek-proxy.gitcd sotatek-proxy -
Build and install:
Terminal window bash scripts/install-from-source.shThe script detects your architecture (amd64 or arm64), runs
make build-linux-amd64/make build-linux-arm64, copies the binary to/usr/local/bin/sotatek-proxy, and registers the machine-wide systemd service (asks forsudo).Optional flags:
Flag Description --no-serviceBinary only — skip systemd unit registration --prefix DIROverride install directory -
Verify the daemon is up:
Terminal window sudo sotatek-proxy statuscurl http://127.0.0.1:3817/_proxy/healthz
How attribution works
Section titled “How attribution works”The daemon identifies the process that made each request, reads its working directory, and runs
git remote -v dropped to that user’s own uid — so it reads each user’s repository with that
user’s permissions, never with elevated privileges. The result is sent upstream as X-Git-Remote.
To make this possible the service holds CAP_SYS_PTRACE, CAP_SETUID and CAP_SETGID, and runs
sandboxed (NoNewPrivileges, ProtectSystem=strict, ProtectHome=read-only) as a non-root system
user.
Where things live
Section titled “Where things live”| What | Path |
|---|---|
| Binary | /usr/local/bin/sotatek-proxy |
| Config | /etc/sotatek-proxy/config.yaml (optional) |
| Logs | /var/log/sotatek-proxy/sotatek-proxy.log |
| Unit | /etc/systemd/system/sotatek-proxy.service |
| Runs as | system user sotatek-proxy (nologin) |
Service commands
Section titled “Service commands”sudo sotatek-proxy status # running / stoppedsudo sotatek-proxy start # start nowsudo sotatek-proxy stop # stop now (stays stopped across reboot)sotatek-proxy logs # tail last 100 linessudo sotatek-proxy uninstall # remove service, system user, config and logsYou can also use systemd directly:
systemctl status sotatek-proxyjournalctl -u sotatek-proxy -fWithout systemd (containers, WSL, Alpine)
Section titled “Without systemd (containers, WSL, Alpine)”Where systemd or useradd is unavailable, service installation is not supported. Run the proxy in
the foreground instead — it falls back to per-user paths (~/.config/sotatek-proxy/config.yaml,
~/.local/state/sotatek-proxy/) and needs no root:
sotatek-proxy daemonTroubleshooting
Section titled “Troubleshooting”If sotatek-proxy status returns command not found, /usr/local/bin is not on your PATH.
Add it to the right shell rc, then reload:
case "$(basename "${SHELL:-bash}")" in zsh) RC="$HOME/.zshrc" ;; *) RC="$HOME/.bashrc" ;;esacLINE='export PATH="/usr/local/bin:$PATH"'grep -qxF "$LINE" "$RC" 2>/dev/null || echo "$LINE" >> "$RC"source "$RC"Another process — usually an old per-user sotatek-proxy belonging to a different user — holds 3817. Find the owner:
sudo ss -tlnp 'sport = 3817'Stop that user’s old unit, then start the system service:
sudo -u <user> systemctl --user disable --now sotatek-proxysudo sotatek-proxy startThe daemon does not crash-loop on a busy port: it logs the owning user and exits, so
journalctl -u sotatek-proxy shows exactly who holds it.
sotatek-proxy logssystemctl status sotatek-proxyjournalctl -u sotatek-proxy --since "10 min ago"sudo sotatek-proxy daemon # foreground for debuggingIf requests reach the upstream without repository attribution, the service’s capabilities are likely not effective (hardened kernel, container without the caps, MAC policy). The daemon logs this at startup:
journalctl -u sotatek-proxy | grep -i "capability self-test"Requests still work — only the attribution header is dropped.
Uninstall
Section titled “Uninstall”sudo sotatek-proxy uninstallsudo rm /usr/local/bin/sotatek-proxy