stun

module
v1.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0

README

EndlessNet STUN

endlessnet-stun is the autonomous, stateless STUN infrastructure service used by EndlessNet clients to discover their public UDP mapping. It accepts standard UDP Binding requests and does not depend on the EndlessNet control plane, database, credentials, or internal Go packages.

This repository owns the STUN source, tests, release artifacts, container image, service configuration examples, and deployment workflow. The public history in this repository is authoritative. Endpoint selection and client-side Binding behavior are owned by their respective consumers.

Boundaries

The service provides unauthenticated STUN Binding over UDP, per-source-IP token-bucket limiting, structured JSON logs, Prometheus metrics, and HTTP health/readiness endpoints. It does not provide TURN, relay user traffic, authorization, billing, coordinator access, PostgreSQL access, DNS discovery, Anycast, or Kubernetes deployment.

Protocol support is documented in docs/supported-protocol.md. The stable network contract is a standard STUN Binding request and response; repository releases do not change public DNS names or UDP ports.

Documentation

Configuration

Flags override environment variables. All configuration is validated before listeners start.

Environment variable Flag Default
ENDLESSNET_STUN_ADDRS --addr required, comma-separated
ENDLESSNET_STUN_METRICS_ADDR --metrics-addr 127.0.0.1:9090
ENDLESSNET_STUN_RATE_LIMIT_PER_SECOND --rate-limit-per-second 20
ENDLESSNET_STUN_RATE_LIMIT_BURST --rate-limit-burst 40
ENDLESSNET_STUN_LOG_LEVEL --log-level info

Use the safe example in configs/stun.example.env; no secrets are required. Validate a host configuration without opening sockets:

set -a
. /etc/endlessnet-stun/stun.env
set +a
/opt/endlessnet-stun/current/endlessnet-stun --check-config

Local development

go run ./cmd/endlessnet-stun \
  --addr 127.0.0.1:3478 \
  --metrics-addr 127.0.0.1:9090

Run the complete quality gate:

./scripts/verify.sh

It runs module verification, unit and process-level integration tests, race tests, go vet, formatting checks, and builds the service and smoke-test binaries. A real local Binding request can be checked with:

./scripts/smoke-test.sh \
  --stun-addr 127.0.0.1:3478

Container

docker build -t endlessnet-stun:dev .
docker run --read-only --cap-drop ALL --network host \
  -e ENDLESSNET_STUN_ADDRS=0.0.0.0:3478 \
  -e ENDLESSNET_STUN_METRICS_ADDR=127.0.0.1:9090 \
  endlessnet-stun:dev

The image runs as a non-root user. deploy/docker/docker-compose.example.yml pins an exact example version; operational deployments must never use latest.

Local health and observability

  • GET http://127.0.0.1:9090/healthz reports process health.
  • GET http://127.0.0.1:9090/readyz returns success only while at least one UDP listener is active.
  • GET http://127.0.0.1:9090/metrics returns Prometheus text format for the host-local Vector agent.

The HTTP listener is required to use a loopback address. Health, readiness, and metrics are not part of the public network contract; only STUN on UDP port 3478 is exposed externally.

Metrics include stun_requests_total, stun_responses_total, stun_invalid_requests_total, stun_rate_limited_total, stun_errors_total, stun_active_listeners, stun_request_duration_seconds, and stun_build_info. Labels are limited to listener, result, and address family; source IP is never a label. Successful client addresses and packet bodies are not logged. Rejected request logs redact the remote address.

Release process

Tags matching vMAJOR.MINOR.PATCH run the release workflow. A tag is accepted only when its commit is reachable from origin/main and GitHub associates that commit with a merged pull request whose base is main. The workflow repeats the quality gate, builds Linux AMD64 and ARM64 server and smoke-test binaries, creates SHA256 checksums, publishes a GitHub Release, and pushes immutable GHCR tags for the exact version, major/minor line, and major line. Deployment always consumes the exact vMAJOR.MINOR.PATCH artifact and verifies its checksum.

Update CHANGELOG.md on a feature branch, merge it through a pull request and CI into main, and only then create a signed or protected version tag. Direct-push and unmerged commits are rejected by both release and production deployment provenance checks. The release job never bypasses the production environment.

systemd deployment

Bootstrap a Linux host once with sudo ./scripts/install.sh, review /etc/endlessnet-stun/stun.env, and deploy an exact release through .github/workflows/deploy-production.yml. Runtime layout:

/opt/endlessnet-stun/
├── releases/v1.0.6/endlessnet-stun
├── releases/v1.0.7/endlessnet-stun
└── current -> /opt/endlessnet-stun/releases/v1.0.7

The workflow accepts an exact version, a comma-separated target host/group, matching public STUN endpoints, and the rolling strategy. Manual dispatch is accepted only from main, and the exact release commit must have merged-PR provenance. Targets update sequentially. Each host atomically sets ENDLESSNET_STUN_METRICS_ADDR=127.0.0.1:9090, performs checksum verification, configuration preflight, an atomic current symlink switch, restart of only endlessnet-stun.service, and local readiness. The runner then performs a real public UDP Binding smoke test; it never accesses the host-local HTTP endpoints. The remote operations are implemented by scripts/configure-metrics-bind.sh and scripts/install-release.sh; provenance, exact-version, checksum, configuration isolation, service isolation, readiness, and rollback behavior are covered by Linux deployment integration tests.

Configure the GitHub production environment with DEPLOY_SSH_PRIVATE_KEY and DEPLOY_KNOWN_HOSTS secrets plus DEPLOY_USER. Enable required reviewers when the repository's GitHub plan supports environment protection; merged-PR provenance remains mandatory in the workflow itself. Set STUN_AUTO_DEPLOY_AFTER_RELEASE=true plus STUN_TARGETS and STUN_ENDPOINTS variables only when every successful release should deploy to production. The same workflow remains manually dispatchable from main.

Rollback

Before switching, deployment records the prior immutable release. Failure to start, failed readiness, process exit, or failed public Binding smoke test restores the prior symlink and restarts only the STUN unit. scripts/rollback.sh provides the same operation explicitly and repeats readiness plus the real external smoke test. Previous artifacts are never rebuilt.

Troubleshooting

  • Configuration failure: run endlessnet-stun --check-config with the environment file loaded.
  • UDP timeout: verify DNS, host firewall, security group, and 3478/udp; TCP reachability does not prove STUN reachability.
  • Readiness failure: inspect systemctl status endlessnet-stun and confirm at least one configured UDP address can bind.
  • Rate limiting: inspect stun_rate_limited_total and adjust both rate and burst deliberately.
  • Deployment failure: inspect the workflow step for the reported target and rollback version; rollout stops before later targets.

EndlessNet clients continue to obtain endpoints such as stun1.endlessnet.ru:3478 from signed network maps or control-plane configuration. The client has no dependency on this repository's Go packages or release version.

Directories

Path Synopsis
cmd
endlessnet-stun command
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL