Archive for June 2018

This is a followup to nginx RTMP Streaming With Simple Authentication.

Last time we covered a very basic setup with a hardcoded passkey. Multiple people have contacted me so far requesting an explanation on how to move towards a slightly more sophisticated authentication setup. Usually involving a php script to authenticate against. Maybe you want to use an existing mySQL or mariaDB database to set up users and channels? Fear not, this is not that complicated to start out with.

Server side configuration

Starting from the old example, we set up a basic rtmp section:

rtmp {
  server {
    listen 1935;
	ping 30s;
	notify_method get;
	application stream {
	  live on;
	  record off;

The on_publish command can point to any web address that you like. It could be supplied via the nginx server as well or you could use an apache2 instance for that. You can also use a completely different server if you wish. For now, we assume that there is a php script rtmp_auth.php which sits in the webroot of your webserver.

The above line will do the following:

  • as soon as someone tries to publish a stream to your domain, the nginx rtmp module will issue a HTTP POST request to the on_publish url.
  • nginx will supply the script with the get variable “name” and fill it with whatever comes directly after your initial stream url
  • it will also pass on any further GET style variables via the standard ?var1=value1&var2=value2 syntax.
  • it will wait for a HTTP return code which either tells it that everything is fine and streaming should commence (201) or that something went wront and it should drop the connection (404)

Suppose someone uses the following url to connect to your rtmp server:


nginx will then call your rtmp_auth.php script like this:

Inside of your php script you then have access to the $_POST array which holds your values and you can do whatever you want with them. In the following example we will use a php array $valid_users to hold a list of allowed users and passwords. Of course, you could instead connect to a database and query for the username and password. The interesting part is all in the if-statement which follows after that.

$username = $_POST["name"]; # in our current example, this will be 'john'
$password = $_POST["psk"]; # in our current example, this will be 'supersecret'

$valid_users = array("john" => "supersecret",
                     "winnie" => "thepooh",
					 "batman" => "nananananananana");

if ($valid_users[$username] == $password) {
  http_response_code(201); # return 201 "Created"
} else {
  http_response_code(404); # return 404 "Not Found"

With this code, if the credentials check out, we return a 201 status code which tells nginx that whoever tries to connect is allowed to stream. If they do not, we issue a 404 and tell the client to get lost.

Client side configuration

Let us suppose your streaming client uses open broadcaster studio (OBS), which is a free and open source streaming utility which works with pretty much all major streaming sites and can also be configured to a custom site.

In OBS, you set the stream type to Custom Streaming Server and as the url you would use rtmp:// As the stream key you would set john?psk=supersecret or any other username / password combination. If you want to supply more information you can supply more GET style variables via appending &var1=value1&var2=value2 and so on. Anything you write before the ? in the stream key field will end up in the variable $_POST["name"] inside your php script.

Sadly, SSL support for RTMP and also for the internal on_publishrequest is still somewhat lacking. So keep in mind that all of this stuff is plaintext authentication. You might not want to use a username / password combo directly but rather a streaming hash that you can allocate via a database and which has to be requested by the user beforehand. At least this way, if someone captures the data, they do not know the login credentials of your users.

You could for example generate a 64 character hash, put it into an SQL table and assign it to a user of your site. Then the user just enters this hash in OBS into the stream key field. Your php script will then be called and the variable $_POST["name"] will hold this hash. After that you can connect to your database, check out whether the hash exists or not and maybe even set up some notification on your website that user john is now streaming. Just be sure to finish with a 201 or 404 code in order to let nginx-rtmp know what it should do about the connection attempt.

In the end you can make things as complex as you want. You can use the same method for other nginx-rtmp directives such as: on_play, on_done, on_update and many more. Check them out at the nginx-rtmp wiki page.

Update: A kind reader has informed me that newer versions of the nginx rtmp plugin no longer use a GET but a POST request to call the URL you specify in the on_publish, on_play, etc directives. I have updated the code to reflect the changes.

FileZilla, the formerly easy-to-recommend FTP/SFTP client for private and enterprise use has fallen from grace and included adware in their installers. With security professionals already recommending uninstalling FileZilla, its author Tim Kosse is trying hard to reframe the issue, claiming that ad-supported installers are necessary and have been around for a long time.

This does not change the fact, however, that some of the “offers” available via the ad-laden installer are downloading unsigned executables to your pc. Including some really shady ones that download seperate data files which later get concatenated into an executable. The best guess is that this would be an attempt at avoiding detection by malware blockers.

This is a terrible move by FileZilla and I too suggest uninstalling it if you still use it. A good alternative for Windows users is WinSCP. Free, open source, what is not to like?

Trump Beaten by Facts (Again)

Fri, Jun 22, 2018

Trump tweeted that crime in Germany is “way up” and that this is due to all the refugees taken in by my country. While I would quickly run out of hard drive space if I were to comment on every single time that dimwit claims something despite the evidence pointing in the completely other direction, this one - of course - is a bit personal.

Luckily, we Germans love our statistics and cold hard facts. For anyone interested you can check out the official crime statistics of the Federal Statistical Office of Germany. As these only go up to 2016, here are the latest numbers for 2017, you can find these on page 10 in the PDF file, section 3.1. The total number of criminal offenses registered in 2017 is 5,761,984. This is the lowest number since 1992 and a good 10% less than in 2016.

This was way too easy… But then again, if you are Trump you already are your worst enemy anyway. The rest of the world can just sit back, relax, and enjoy some popcorn while the US fade from the world stage.

So the United States decided to quit the United Nations human rights body. They cited bias vs Israel and the presence of countries in the council that are not exactly well known for their adherence to human rights, like Iran.

Now, dear friends from the U.S., who again separates children from their families in order to scare immigrants to stay away? Not to mention you are still running Guantanamo Bay and appointed Gina Haspel as the new director of the CIA. A person who ran a blacksite in Thailand which was used to torture prisoners. She then ordered the destruction of 92 video tapes documenting interrogation sessions. Of course even your own president likes the use of waterboarding. Easier to point the finger at someone else, right?

More Intel CPU Flaws Surface

Thu, Jun 14, 2018

While the latest CPU iteration of Intel still is affected by Meltdown, another vulnerability was discovered in their CPUs. It is also based on speculative execution and apparently allows floating point registers to be leaked from another process. Dubbed Lazy FP state restore this bug of course affects all systems based on Intel processors which are vulnerable. Linux and the latest flavours of BSD are already fixed or immune anyway. Windows Server 2008 however is still vulnerable.

The snake oil vendor who has fallen from grace in western main stream politics Kaspersky has temporarily halted its cooperation with Europol. This came after a vote in the plenary session of the European Parliament which put forward a motion which advises EU states to exclude and ban programs and equipment that have been confirmed as malicious. (Apparently for most politicians this does not fall under common sense)

The problem is that this motion explicitly mentions Kaspersky, so they have been rather peeved in the process.

The big question is: Will the EU now ban Windows 10, Alexa, Cortana, Siri, and several other malicious pieces of tech? ^^

F-Secure Not So Secure

Wed, Jun 6, 2018

Another snake oil vulnerability was unveiled recently. F-Secure allows for arbitrary code execution by means of a specially crafted RAR archive. Since it scans files without asking, there is not much an affected user can do about that if such a file ends up in the claws of his F-Secure Installation.