Multi-Tenant/IP Hosting for Wowza Streaming Engine

For most users, running Wowza Media Server/Wowza Streaming Engine (which I’ll refer to as just “Wowza”) are perfectly content running it out of the box as is on a dedicated server. Where it gets a little more interesting is when you have to co-exist with other server applications that want some of the same ports (I’m lookin’ at YOU, web servers!).

By default, Wowza binds itself to all available IP addresses on ports 1935 (RTMP, but will also take HTTP requests on that port), 8086 (for some basic management functions), 8083 and 8084 (for JMX), and with WSE4, 8087 (REST) and 8088 (WSE Manager). It won’t bind itself to port 80 specifically because of the common problem of co-existing with web servers. If you have Wowza enabled for IPv6, it will also bind to all available IPv6 addresses on the same ports.

This technique is also good for reducing surface area, where you can have remote management such as SSH or RDP listening on one address, and someone scanning your streaming server IP won’t find any open management ports to attempt to exploit.

Use Case: Web server on one IP address, Wowza on another

This is probably the simplest thing to do, where your ISP or colocation provider gives you the option of more than one IP address. You can also use multiple physical interfaces, if available. If you want to send web traffic out one gigabit port, and streaming traffic out another, Wowza doesn’t really care about the hardware side, so assign your addresses to hardware interfaces in the operating system.

To lock Wowza down to a particular IP address, there are three places you need to make configuration changes:

conf/Server.xml

In the Server.xml file, you’re defining the bind address for JMX and REST API management.

<RESTInterface> 
 <Enable>true</Enable>
 <IPAddress>*</IPAddress>
 <Port>8087</Port>
 [...]
</RESTInterface>

Simply change the IPAddress parameter to the address you want to bind it to. There’s also no reason that I know of why you can’t set this one strictly to localhost/127.0.0.1 so that your REST API isn’t exposed to the world.

Do the same in the CommandInterface section:

<CommandInterface>
 <HostPort>
  <ProcessorCount>${com.wowza.wms.TuningAuto}</ProcessorCount>
  <IpAddress>*</IpAddress>
  <Port>8083</Port>
 </HostPort>
</CommandInterface>

Then under JMXRemoteConfiguration (if enabled), change the IpAddress and RMIServerHostName:

<JMXRemoteConfiguration>
 <Enable>false</Enable>
 <IpAddress>localhost</IpAddress> <!-- set to localhost or internal ip address if behind NAT -->
 <RMIServerHostName>localhost</RMIServerHostName> <!-- set to external ip address or domain name if behind NAT -->
 <RMIConnectionPort>8084</RMIConnectionPort>
 <RMIRegistryPort>8085</RMIRegistryPort>
 [...]
</JMXRemoteConfiguration>

Likewise this one can be left on localhost so as not to expose JMX to the world.

conf/VHost.xml

Next stop is the VHost.xml configuration file which specifies where Wowza listens for actual streaming traffic.

Each <HostPort> section will have an <IpAddress> block that defaults to *:

<HostPort>
 <Name>Default Streaming</Name>
 <Type>Streaming</Type>
 <ProcessorCount>${com.wowza.wms.TuningAuto}</ProcessorCount>
 <IpAddress>69.4.233.200</IpAddress>
 <!-- Separate multiple ports with commas -->
 <!-- 80: HTTP, RTMPT -->
 <!-- 554: RTSP -->
 <Port>1935</Port>
 [...]
</HostPort>

Do this for all HostPort sections.

Finally, you’ll need to tell the manager to listen on the IP as well.

manager/bin/startmgr.{bat|sh}

In the batch file (Windows) or the shell script (Linux/OSX), look for the line that begins with CMD and add the following parameter to the end:

--httpListenAddress=1.2.3.4

If you’ve changed the REST API address from its default of *, you’ll get an error on the login screen:

In this case, you’ll need to tell the manager where to look for the server by clicking on the [+] Server link:

Screen Shot 2014-04-16 at 11.51.37 AM

(Tip: you can also use this to manage multiple Wowza Streaming Engine instances from a single installed manager)

Use Case: Wowza on Multiple IP addresses (but not all)

There are some situations where you’d want Wowza to listen on multiple addresses, but not all available addresses. An example of this would be where the base IP and management port of the machine are on a 100Mbps interface, and you’ve added a 4-port gigabit NIC to the system for streaming traffic. Another use case would be IPv6.

One limitation of the Wowza software is that while you can have a comma-separated list of ports in the configuration files to bind multiple ports, you don’t have that luxury for IP addresses. Practically speaking, this means all your stuff in Server.xml and the manager startup are restricted to either a single IP or all of them (unfortunately, this also means that as of right now, you cannot tell the manager to listen on a specific IPv4 address AND a specific IPv6 address).

In VHost.xml, adding an additional IP is a matter of creating an additional HostPort section with the new IP (v4 or v6). With Wowza V3 and below, this can make tuning a little interesting, just make sure you don’t give Wowza more processor cores than you actually have available, or the system performance will suffer. Another caveat to remember here is that if you make a change in the HTTPProviders on one IP’s HostPort section, don’t forget to do it for all the other IPs, or you’ll tear your hair out wondering why it works only part of the time.

As of 4.0.3, the manager doesn’t deal with this kind of configuration very well, so you will likely still need to manually edit configuration files from time to time.

Use Case: Separating management from streaming

This is more or less a hybrid of the previous approaches. If you have your system configured for a management IP, you can configure your Server.xml and manager, along with the port 8086 stuff in VHost.xml to listen on the management address, and then all the streaming stuff on ports 80, 554, 1935 can listen on the streaming address(es).

Use Case: IPv6

Wowza can be configured to listen on IPv6 by changing the startup parameters.

Version 3

in bin/setenv.{sh|bat}, change the JAVA_OPTS line from

-Djava.net.preferIPv4Stack=true

to

-Djava.net.preferIPv4Stack=false

Version 4

in conf/Tune.xml, similar process:

<VMOptions>
 <VMOption>-server</VMOption>
 <VMOption>-Djava.net.preferIPv4Stack=true</VMOption>
 <!-- <VMOption>-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="${com.wowza.wms.AppHome}/logs"</VMOption> -->
 <!-- <VMOption>-Duser.language=en -Duser.country=US -Dfile.encoding=Cp1252</VMOption> -->
 <!-- <VMOption>-verbose:gc -Xloggc:"${com.wowza.wms.AppHome}/logs/gc_${com.wowza.wms.StartupDateTime}.log" -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime</VMOption> -->
</VMOptions>

Use Case: Multi-tenant Virtual Hosts

This is essentially the same as above, except each defined VHost has its own configuration files, stored in a location determined by the entry in conf/VHosts.xml. Naturally, anything defined in conf/Server.xml doesn’t apply to VHosts.

In my ideal world, you’d be able to define one or more addresses allocated to each VHost in VHosts.xml, and then the VHost.xml for each of those VHosts could use “*” and be restricted to only those addresses, but that’s not currently an option. Instead, You need to set up the IP address for each one in the VHost.xml as described earlier. Same caveat applies for tuning.

Testing:

Once you’ve configured your IP addresses, you should see something like this in your access log:

2014-04-16	10:42:36	CDT	comment	server	INFO	200	-	RESTServer: Bind attempt ([3.4.5.6]:8087)	-	-	-	1.912	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-
2014-04-16	10:42:36	CDT	comment	server	INFO	200	-	RESTServer: Bind successful ([3.4.5.6]:8087)	-	-	-	2.209	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-
2014-04-16	10:42:45	CDT	comment	vhost	INFO	200	_defaultVHost_	Bind attempt (3.4.5.6:1935:16)	-	-	-	11.073	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-
2014-04-16	10:42:45	CDT	comment	vhost	INFO	200	_defaultVHost_	Bind successful (3.4.5.6:1935)	-	-	-	11.078	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-
2014-04-16	10:42:45	CDT	comment	vhost	INFO	200	_defaultVHost_	Bind attempt (3.4.5.6:8086:4)	-	-	-	11.081	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-
2014-04-16	10:42:45	CDT	comment	vhost	INFO	200	_defaultVHost_	Bind successful (3.4.5.6:8086)	-	-	-	11.084	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-	-

If you don’t see a successful bind, it will tell you what caused the failure.

One Comment On “Multi-Tenant/IP Hosting for Wowza Streaming Engine”

  1. Pingback: Multi-tenant Virtual Hosting with Wowza on EC2 – streamNerd

Leave a Reply

Your email address will not be published. Required fields are marked *