DEV Community

Liu Lantao
Liu Lantao

Posted on • Updated on

RTMP/RTMPS relay with stunnel

On May 1st, 2019, Facebook Live will deprecate RTMP from Live API and GoLive page, and enforce using RTMPS.


I'm relaying the stream through 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 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 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Enable tunnel in /etc/default/stunnel4

ENABLE=1
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

* Please note you need to enable verifyChain = yes to prevent MITM attacks

systemctl restart stunnel4 && systemctl status stunnel4
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>;
Enter fullscreen mode Exit fullscreen mode

All done!


Lax - Freelancer, System engineer, Tech-Writer
You can find me on Twitter @liulantao or GitHub @Lax.

Top comments (17)

Collapse
 
ancienttom profile image
Thomas J. Strike Jr. • Edited

This doesn't work for me. It neither works from a ffmpeg command line string or from your direction with nginx. You use rtmps in ffmpeg which causes librtmp to stall out in my ffmpeg build. I've read that librtmp uses openssl to encode with and it is not enabled on my ffmpeg build. It appears with all the Googling I've done that OpenSSL is not a library that librtmp uses but rather a running service. I can't find anywhere that explains enough to get ffmpeg working with rtmps and OpenSSL.

Why do you need to use stunnel and nginx in the first place if you can stream to Facebook using an rtmps encoded stream from within ffmpeg. Shouldn't ffmpeg be able to stream directly to Facebook if librtmp was working properly?

I came here in desperation for a work around to get a rtmps stream working to Facebook in the light that I cannot get a ssl/tls connection going with ffmpeg. If you have any knowledge on how to make ffmpeg output a rtmps stream or how the librtmp library works and how to get it to do what it is supposed to when using a rtmps call, I would really appreciate the help.

You know how you know that you've exhausted all searching for information that you need? It's when you keep Googling using different key phrases and each time, all the links on Google come up purple.

Collapse
 
podfish profile image
Steven ɥsᴉɟpod Ketelsen 🎙️🐟🥚

Are you building ffmpeg from source or using a package manager? what distribution/OS?

Collapse
 
ancienttom profile image
Thomas J. Strike Jr. • Edited

Working with a Debian OS fork. I got it sorted out about a week ago with the fine fellows on the ffmpeg Freenode IRC channel. It turns out that I was fighting a bug in ffmpeg that when it came to encryption wasn't doing it right and was propagated to every source they had. That's why when I tried using it with nginx on my Centos server and my Ubuntu desk top, I ended up with the same failure to connect to Facebook. I am now using a version of ffmpeg that I compiled myself from the latest updates on github (with the encryption fixed). I compiled it using the internally supplied rtmp handler and added in gnutls. It now works like a champ.

I haven't taken the use of stunnel in this application seriously. It was just an act of desperation of trying the stunnel work around to get something working. The right tool for the right job would be ffmpeg.

Thread Thread
 
podfish profile image
Steven ɥsᴉɟpod Ketelsen 🎙️🐟🥚

I'm using ubuntu server and didn't have any issues whatsoever. the ffmpeg bug must have been introduced later.

For me it's convenient to embed the ffmpeg command in the rtmp section of the nginx config because i'm streaming from a network device and using nginx to push to multiple ingestors (fb live, periscope, yt) and will eventually be presenting a variable rate HTTP Live Stream and an icecast mp3 stream on my site.

Thread Thread
 
ancienttom profile image
Thomas J. Strike Jr.

Yes, from what I understand is that the bug is fairly recent and now living in all the OS repositories. If you are not pushing rtmps, encrypted, then you would not notice it.

Collapse
 
martinharran profile image
MartinHarran

A nice work around, well done! It works fine for me and I can connect to Facebook ok but the live stream does not start automatically, I have to go into live producer where I can see the stream connected; however, I have to manually click the Go Live button to start the streaming on my timeline. Is there any way to start it automatically?

Collapse
 
cahlback profile image
Christoffer

I'm getting this error:

Neither nodename nor servname known (EAI_NONAME)

This is my fb.conf

[fb-live]
client = yes
accept = 127.0.0.1:19350
connect = live-api-s.facebook.com:443/rtmp/
verifyChain = no

Currently my stunnel.conf looks like this:

;setuid = stunnel4
;setgid = stunnel4
pid=/tmp/stunnel.pid
output = /usr/local/var/log/stunnel4/stunnel.log
include = /usr/local/etc/stunnel/conf.d

;foreground = yes

If I activate setuid and setgid, I also get this error:

/usr/local/etc/stunnel/stunnel.conf:1: "setuid = stunnel4": Illegal UID

Collapse
 
bbrout profile image
bbrout

I had this working beautifully but had to alter ownership of the pid. I had my virtual machine run into some major problems with a bad install which would not uninstall. Backups would have helped. I am now trying to reinstall stunnel so I can route through Facebook and through other outlets at the same time from OBS.

I saved the previous configuration files and followed your steps but cannot get stunnel to start. I keep getting the same errors as follows:

● stunnel4.service - LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons)
Loaded: loaded (/etc/init.d/stunnel4; generated)
Active: failed (Result: exit-code) since Tue 2020-09-29 03:14:00 UTC; 11s ago
Docs: man:systemd-sysv-generator(8)
Process: 1078 ExecStart=/etc/init.d/stunnel4 start (code=exited, status=1/FAILURE)

Sep 29 03:14:00 virtualstreamer stunnel4[1102]: [ ] Compression disabled
Sep 29 03:14:00 virtualstreamer stunnel4[1102]: [ ] No PRNG seeding was required
Sep 29 03:14:00 virtualstreamer stunnel4[1102]: [ ] Initializing service [fb-live]
Sep 29 03:14:00 virtualstreamer stunnel4[1102]: [!] Service [fb-live]: Either "CAfile" or "CApath" has to be configured
Sep 29 03:14:00 virtualstreamer stunnel4[1102]: [ ] Deallocating section defaults
Sep 29 03:14:00 virtualstreamer stunnel4[1078]: failed
Sep 29 03:14:00 virtualstreamer stunnel4[1078]: You should check that you have specified the pid= in you configuration file
Sep 29 03:14:00 virtualstreamer systemd[1]: stunnel4.service: Control process exited, code=exited, status=1/FAILURE
Sep 29 03:14:00 virtualstreamer systemd[1]: stunnel4.service: Failed with result 'exit-code'.
Sep 29 03:14:00 virtualstreamer systemd[1]: Failed to start LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons).

I have tried my own daemon for a pid and tried your out-of-the-box pid=/tmp/stunnel.pid and both fail. Can you help please? This used to work great.

-Bruce

Collapse
 
attiqfsd profile image
Attiq Haroon

Hello Lax,

I followed this tutorial and did not face any error message. My OBS is streaming to the RTMP server fine, but there is nothing showing up on the facebook page. Can you help me what could have gone wrong? I am using Vultr Debian 8 VPS as a RTMP server.

Collapse
 
ahmedesoliman profile image
Ahmed Soliman

Stunnel4 requires Java JDK - Which java works best with stunnel4?

Collapse
 
zon3full profile image
Zon3Full

great effort bro woks really well , just have to start the three commands everytime i reboot and please can i multi config it for facebook and Instagram also ?

Collapse
 
reavessm profile image
Stephen Reaves

After changing the verifyChain to yes, did you have to mess with the CAfile and/or checkHost? If so, what did you do?

Collapse
 
piyushg44294785 profile image
Streak Gaming • Edited

i need to edit stunnel conf file in windows can u please modify the code for windows
???

Collapse
 
podfish profile image
Steven ɥsᴉɟpod Ketelsen 🎙️🐟🥚

This worked like a charm for me!

Collapse
 
afanjul profile image
Alex

Nice work dude!!!

Collapse
 
cahlback profile image
Christoffer

Anybody who have gotten this to work on a mac?
I got RMPT running to both Youtube and Twitch smoothly, but Facebook doesn't detect anything even though I got Stunnel running.

Collapse
 
cahlback profile image
Christoffer • Edited

Solved my own problem!
Some of the stuff are a bit embarrassing, but I'll put it up here, maybe someone else gets any help from it.

Running on Mac OS Catalina

In my Fb.conf-file I had this info:

client = yes
accept = 127.0.0.1:19350
connect = live-api-s.facebook.com:443/rtmp/
verifyChain = no
Enter fullscreen mode Exit fullscreen mode

It needs to be:

client = yes
accept = 127.0.0.1:19350
connect = live-api-s.facebook.com:443
verifyChain = no
Enter fullscreen mode Exit fullscreen mode

Note the difference in the links:
live-api-s.facebook.com:443/rtmp/
live-api-s.facebook.com:443

If you use live-api-s.facebook.com:443/rtmp/
the result will be
live-api-s.facebook.com:443/rtmp/rtmp/your-stream-key
My error was that i copied the link directly from facebook and forgot to remove the last parts. Some of you will think I am a noob, and you are completely correct, haha! ;) However, I am a proud noob, after I got this thing working! :)

On my mac, I also ran into issues with stunnel.conf, more specifically setuid and setgid. It never worked when I started up Stunnel, so I put # before them to deactivate those lines. I honestly have no real idea what these commands do, more than they have to do with User Id and Group Id, but it works. Maybe this is a difference between MacOS and Linux.

 #setuid = stunnel
 #setgid = stunnel
pid=/tmp/stunnel.pid
output = /usr/local/var/log/stunnel4/stunnel.log
include = /usr/local/etc/man sstunnel/conf.d
Enter fullscreen mode Exit fullscreen mode

Also, I never used the command ENABLE. Never found it on my mac, and it never asked for it either. Happy Days!

The last issue I stumbled upon was that when I finally had gotten everything up and running on my computer, with no errors in the Stunnel.log-file and so on, Facebook still did not receive anything. After a while, I found out that it actually did receive a video link, but Facebooks Stream Health tab showed Auth Token Validation Failure or something like that. I have no idea what made the actual difference, but I just clicked "turn off static stream key" and it worked. Now it looks like it is on again, but it works now, so I have no idea what really was the issue here. But sometimes clicking around some will do the work.

Maybe someone will get some help out of this! I have noticed that there is extremely little info on doing this on a mac.
Cheers!