Restreaming with nginx-rtmp on a VPS: The Multiplatform Setup Guide
nginx-rtmp is the backbone of professional private streaming setups. It receives your stream, optionally transcodes it, and forwards it to as many destinations as configured. Here is the complete working setup.
Installation on Ubuntu 22.04
sudo apt update
sudo apt install nginx libnginx-mod-rtmp
# Verify RTMP module is loaded:
nginx -V 2>&1 | grep rtmp
Complete nginx.conf Configuration
worker_processes auto;
events {
worker_connections 1024;
}
# Standard web server block (for stats page)
http {
server {
listen 8080;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /var/www/html;
}
}
}
rtmp {
server {
listen 1935;
chunk_size 4096;
timeout 30;
application live {
live on;
record off;
# Require authentication (prevents unauthorized streaming to your relay)
on_publish http://localhost:8080/auth;
# Forwarders
push rtmp://live.twitch.tv/live/YOUR_TWITCH_KEY;
push rtmp://a.rtmp.youtube.com/live2/YOUR_YOUTUBE_KEY;
push rtmp://live.kick.com/app/YOUR_KICK_KEY;
}
}
}
Firewall Configuration
# Allow RTMP port through UFW
sudo ufw allow 1935/tcp
sudo ufw allow 8080/tcp # Stats page (optional - restrict to your IP)
sudo ufw reload
Securing Your Relay
Without authentication, anyone who discovers your VPS IP can stream to it:
# In nginx.conf, application block:
on_publish http://127.0.0.1:8080/auth;
With a simple authenticating HTTP endpoint (local Flask/Node.js app):
# auth_server.py
from flask import Flask, request
app = Flask(__name__)
ALLOWED_KEYS = {'my_secret_stream_key_123'}
@app.route('/auth', methods=['POST'])
def auth():
key = request.form.get('name', '')
if key in ALLOWED_KEYS:
return '', 200
return '', 403
if __name__ == '__main__':
app.run(port=8080)
In OBS, your stream key becomes my_secret_stream_key_123 — nginx validates it before forwarding.