WebRTC Outpost
Configuration repository for a Coturn relay that supports a Stoat deployment on GCP. The stack provisions a relay-main Ubuntu 24.04 instance, hardens the host with nftables, fail2ban, and unattended-upgrades, then deploys Coturn plus a Coraza-enabled Caddy service with Podman Compose. Caddy handles ACME certificate issuance, HTTPS health checks, and deny-by-default web responses on the TURN hostname. Coturn handles STUN and TURN traffic directly on 3478 and 5349, reusing the certificate that Caddy stores in the shared data volume.
Repository Layout
tofu/: OpenTofu infrastructure for the static IP, VM, and GCP firewall rule.ansible/: Host preparation and hardening for Ubuntu 24.04.compose/: Runtime configuration for Coturn and Caddy.docker/: Custom images for Coturn and Caddy..github/workflows/: CI workflows for building images and deploying the stack.
Required GitHub Secrets
R2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEYCLOUDFLARE_ACCOUNT_IDGCP_SA_KEYSSH_PRIVATE_KEYTURN_SHARED_SECRET
Recommended GitHub Variables
GCP_PROJECTGCP_REGIONGCP_ZONETURN_REALMCADDY_EMAIL
Notes
- The OpenTofu S3 backend is configured at deploy time so the Cloudflare R2 endpoint does not need to be committed to the repository.
- The Google provider reads service account credentials from the standard
GOOGLE_APPLICATION_CREDENTIALSshell environment variable. Set it to the JSON key file path for localtofuruns. - The custom Coturn image waits for the Caddy-managed certificate for
TURN_REALMto appear in the sharedcaddy_datavolume before starting the TLS listener on5349. - Caddy on the relay host only answers
/healthand returns403for other HTTPS requests. TURN and STUN traffic does not pass through Caddy; Coturn receives it directly through host networking. - The Ansible playbook lowers
net.ipv4.ip_unprivileged_port_startto80so a rootless Podman-managed Caddy container can bind to80and443.
DNS Setup
- Create a DNS
Arecord so the hostname used byTURN_REALMresolves to the OpenTofu-provisionedrelay_ip. - If you use Cloudflare, keep that record set to DNS-only. The orange-cloud proxy does not support TURN or STUN over UDP.
- Optional SRV records can advertise the default ports:
_stun._udpon3478,_turn._udpon3478, and_turns._tcpon5349for the same hostname.
Local OpenTofu Usage
Export the Google credentials path and required OpenTofu variables before running tofu locally:
export GOOGLE_APPLICATION_CREDENTIALS="secret-path"
export TF_VAR_gcp_project="your-gcp-project"
export TF_VAR_gcp_region="us-west1"
export TF_VAR_gcp_zone="us-west1-b"
cd tofu
tofu init
tofu apply
network_name defaults to default, instance_name defaults to relay-main, and admin_ssh_public_key is optional unless you want SSH access provisioned on the VM.