Page 1 of 1

[Guide] Access Axis cam configuration through ZM's web console (using Apache as a reverse proxy)

Posted: Wed Sep 07, 2016 3:58 pm
by coracis
I have a setup where my ZM server can be reached through a public network. All cameras are attached via a private network ( For configuring the IP-Cameras from the public network I would usually setup an SSH forward (ssh -L8000: for example). But how to have my users (camera admins) access the configuration interfaces without SSH? What I am looking for is an additional button in the web console which will display the configuration interface of a chosen cam.

This is possible by means of Apache's built-in reverse proxy abilities. This will make Apache look up the URI of the IP-Cameras and then relay the web-pages to us.

I am running a Zoneminder (zmrepo) 1.30 setup on CentOS 7 with Apache 2.4 which is connected to some Axis IP-Cameras that all have a configuration interface running on their port 80.

We will have to do two steps:
1. Setup the reverse proxy
2. Integrate links into ZM interface

1. Setup the reverse proxy

Make sure that mod_proxy is loaded

Code: Select all

# httpd -M | grep proxy_module
 proxy_module (shared)
We need a request URI. Let's make it /k111. This shall relay to our first camera This means that Apache will display the configuration interface at host/k111 as if we would browse from the ZM server. Configure your httpd accordingly:

Code: Select all

<Location "/k1">
Make sure you cross-check with the documentation.

Reload Apache (systemctl reload httpd) and you should have a working reverse proxy.

That was it! Uhm, not really (at least not for Axis cameras) since the URIs in the served documents need to be rewritten. Otherwise links may redirect the client to an address not beginning with /k111 and our reverse proxy connection will break. There is an Apache module which can rewrite the URIs for us: mod_proxy_html to the rescue.

Make sure you have the module installed and is detected by Apache:

Code: Select all

yum install mod_proxy_html
httpd -M | grep proxy_html
Configuration of this module is a bit more thorough. For me it came down to the following:

Code: Select all

LogLevel warn proxy_html:trace5
#AddType text/html .shtml
#AddOutputFilter INCLUDES .shtml

<Location "/k111">

# allgemeine Optionen für mod_proxy_html
ProxyHTMLEnable On
ProxyHTMLExtended On
ProxyHTMLLinks link href
ProxyHTMLLinks frame src
ProxyHTMLLinks img src
ProxyHTMLLinks script src
ProxyHTMLLinks a href
ProxyHTMLLinks td background
ProxyHTMLEvents onclick
# work-around; comment out next line if CSS is not working
ProxyHTMLURLMap /css/win_ns.css /css/common.css h
# Replace addresses in HTML tags
ProxyHTMLURLMap ^/ /k111/ cRn
# a more strict mapping for replacing in Javascript/CSS
ProxyHTMLURLMap (/.*\.(shtml|css|txt|gif)) /k111$1 R
The first paragraph reflects changes to the httpd.conf itself. LogLevel is raised for the appropriate module. This value can be reset once your server goes productive. The other two lines were commented out to avoid warnings in the log.

In the second paragraph ProxyHTMLEnable and ProxyHTMLURLMap should be self-explanatory. The ProxyHTMLLinks directive is a filter to declare which attributes of an HTML tag may be changed. I have got this ruleset by trail&error, reading Apache's error log and using Firefox' network anlyser (Button F12).

Since you need to do this for every camera, you wind up with a lot of configuration lines. To ease on this issue you may consider including common lines from another file, using mod_macro or wait for Apache 2.4.8 which will sport a mightier LocationMatch.

2. Integrate links into ZM interface

This needs some editing of PHP-Code. I added a line after line 331 in web/skins/classic/views/console.php with a link. Just use PHP and ask it for $monitor['Host'], something like

Code: Select all

<a href="<?php str_replace('192.168.1.', '', $monitor['Host']) ?>" target="_blank">KK</a>
but watch out that you do not mess up the HTML of the generated table!

Of course you can also create an own helper function and put it into web/skins/classic/includes/functions.php

Now when I visit host/k111/operator/basic.shtml and supply the authentication credentials of the camera I can browse the configuration interface of the camera as if I were connected directly. A few links are not showing up, mainly because a ProxyHTMLLinks line is missing. I may add them consequently to my post once I find them.