RTMP/RTMPS relay with stunnel
Published: 2019-04-04 07:01:46

---
title: RTMP/RTMPS relay with stunnel
published: true
description: How to push RTMPS via an RTMP over SSL tunnel
tags: 
---

On May 1st, 2019, Facebook Live will [deprecate RTMP](https://developers.facebook.com/docs/graph-api/changelog/breaking-changes/#live-api-4-24) from Live API and GoLive page, and enforce using RTMPS.

---

I'm relaying the stream through [nginx-rtmp-module](https://github.com/arut/nginx-rtmp-module) to different platforms such as FB Live, YouTube Live, and Twitch.
Unfortunately `nginx-rtmp-module` doesn't support replaying to an `rtmps://` address, and the feature is not supposed be added in a recent release.
There's an issue [nginx-rtmp-module#1397](https://github.com/arut/nginx-rtmp-module/issues/1397) discussing about this.


RTMPS, which is RTMP over a TLS/SSL connection.
We can use a tunnel software to establish an SSL connection with the server and pass RTMP streams over the connection.


[Stunnel](https://www.stunnel.org) is a proxy designed to add TLS encryption functionality to existing clients and servers without any changes in the programs' code.
Stunnel uses the OpenSSL library for cryptography, so it supports whatever cryptographic algorithms are compiled into the library.

We can install `stunnel` with the package manager on a modern OS.

---

My current setup without `stunnel`

```
{OBS/FFmpeg/...} -> rtmp://nginx-rtmp-server:1935 -> rtmp://live-api-s.facebook.com:80
```

With `stunnel`, the setup will be like the following:

```
{OBS/FFmpeg/...} -> rtmp://nginx-rtmp-server:1935 -> rtmp://stunnel:19350 -> rtmps://live-api-s.facebook.com:443
```
`stunnel` is running on port `:19350` because nginx is already listening on port `:1935`.

---

I'm installing `stunnel` on `Debian 9 - stretch` with `root` user. You need to switch `root` user or use `sudo` for every commands listed below.

```
# Install stunnel
apt install stunnel4
```

Here is a minimal configuration of stunnel.

```
# Stunnel basic config
cat <<EOF > /etc/stunnel/stunnel.conf 
setuid = stunnel4
setgid = stunnel4
pid=/tmp/stunnel.pid
output = /var/log/stunnel4/stunnel.log
include = /etc/stunnel/conf.d
EOF
```

Enable tunnel in `/etc/default/stunnel4`

```
ENABLE=1
```

Now add a tunnel for Facebook Live address

```
# RTMP -> RTMPS tunnel
cat <<EOF > /etc/stunnel/conf.d/fb.conf 
[fb-live]
client = yes
accept = 127.0.0.1:19350
connect = live-api-s.facebook.com:443
verifyChain = no
EOF
```
\* Please note you need to enable `verifyChain = yes` to prevent MITM attacks

```
systemctl restart stunnel4 && systemctl status stunnel4
```

---

We can run a `ffmpeg` command to test pushing stream, target to local stunnel port `:19350`

```
ffmpeg -re -i /path/to/video.flv -c:v libx264 -c:a aac -f flv rtmps://127.0.0.1:19350/rtmp/<facebook-live-stream-key>
```

Now the tunnel is ready to work!

Let's replace the URL to local stunnel port within nginx rtmp config.

```
# Change this line
push rtmp://live-api-s.facebook.com:80/rtmp/<facebook-live-stream-key>;
# to
push rtmp://127.0.0.1:19350/rtmp/<facebook-live-stream-key>;
```

All done!

---

Lax - Freelancer, System engineer, Tech-Writer
You can find me on Twitter [@liulantao](https://twitter.com/liulantao) or GitHub [@Lax](https://github.com/Lax).