5. Security
This page explains what the relay protects, against whom, and what it leaves to you. To lock down a running relay, see Restrict Who Can Publish and Watch.
5.1 Reporting Security Issues
Email jacob.josh.sanford@gmail.com rather than opening a public issue. The same policy is in SECURITY.md at the repository root.
5.2 Threat Model
The relay is built to run on a home or studio network, next to the machine that runs your streaming software. It assumes:
- You are trusted. Whoever edits
env/relay.envanddocker-compose.yml, or can rundockeron the host, controls the relay and can read its stream keys. - Other machines on the network are not. They should not be able to send a stream through the relay to your Twitch or YouTube channel.
- Settings can be mistyped. A bad value should stop the relay at startup rather than produce a broken or unsafe nginx configuration.
It does not try to hide your stream from viewers on the network, or to protect stream keys from anyone with access to the host.
5.3 What Is Protected
- Publishing. Only addresses in
PUBLISH_IP_RANGE, plus127.0.0.1, can send a stream to the relay. Others are refused withaccess forbidden by rulein the log. The default,172.16.0.0/12,192.168.0.0/16, admits the Docker networks and typical home networks. - Configuration. Every variable you set is checked against a whitelist or pattern before it is written into the nginx configuration, so a value cannot inject a shell command or an nginx directive. If a value fails, the container stops before nginx starts and the log names the variable. For each check, see the Input Validation Reference.
5.4 What Is Not Protected
- Playback is open. The relay has publish rules only, and no play rules. Anyone who can reach port 1935 can play
rtmp://<RELAY_HOST>/relay/<STREAM_NAME>, and the transcoded Twitch stream at/twitch/<STREAM_NAME>. This was checked against a running container: withPUBLISH_IP_RANGE=10.99.0.0/24, a host outside that range was refused as a publisher but could playrelay/<STREAM_NAME>. - The port is published on every host interface.
docker-compose.ymlmaps1935:1935. Docker writes its own iptables rules for published ports, so host firewall tools such asufwmay not block them. To close both gaps, see Limit Who Can Watch. 127.0.0.1can always publish, whateverPUBLISH_IP_RANGEis set to.- The
twitchapplication accepts publishes directly. Any address inPUBLISH_IP_RANGEcan publish to/twitch/<STREAM_NAME>and send a stream to Twitch without going through the transcoder.
5.5 Where Stream Keys Live
env/relay.env, in plain text..gitignoreexcludes it, so git does not commit it; the tracked template isenv/relay.env.example, which holds no keys. See Change Relay Settings.- The container environment. Anyone who can run
docker inspecton the container can read them. The relay has no support for Docker secrets or*_FILEvariables. - The generated nginx config inside the container, in plain text.
- The container log, when
NGINX_ERROR_LOG_LEVELisinfoor more verbose: nginx logs the full push URL, including the key, when it starts relaying. Return toerror(the default) after troubleshooting, and remove keys before sharing logs.
If a key may have leaked, reset it in the service's dashboard.
5.6 Running the Container
- Archive path. The path must be writable by the nginx user. If it is not, the container stops at startup with
ERROR: ARCHIVE_PATH is not writable by the nginx user.Archive writes every stream published torelayat its source bitrate, so a 6000 kbps stream uses about 2.7 GB per hour: watch disk space. - Read-only filesystem. A read-only root filesystem breaks startup: the startup scripts rewrite files under
NGINX_CONFD_DIR(/etc/nginx/http.d) in place withsed -iandmv. - Resource limits. Twitch non-partner mode re-encodes for as long as you stream. Setting a CPU limit on the container keeps it from starving the host. See CPU Considerations.
- Updates. To pick up relay and base image fixes, run
git pull, then rebuild withdocker compose build --pulland restart withdocker compose up -d.
5.7 See Also
- Restrict Who Can Publish and Watch - Lock down publishing and playback
- Input Validation Reference - Every validation function and the variables it checks
- IP Authentication - Publish refused with "access forbidden by rule"
- Architecture - How configuration is processed