Difference between revisions of "Zms-inetd"

From ZoneMinder Wiki
Jump to navigationJump to search
 
(Undo revision 7578 by Jassure (talk) Same Spam)
 
(33 intermediate revisions by 8 users not shown)
Line 5: Line 5:
* '''Requirements''': bash, inetd
* '''Requirements''': bash, inetd
* '''License''': GNU General Public License, Version 2
* '''License''': GNU General Public License, Version 2


== Motivation ==
== Motivation ==
Line 10: Line 11:
I'm using Zoneminder with [http://nginx.net/ Nginx Httpd], which doesnt support simple CGI (just FastCGI). So I needed a leightweight solution to make ZMS work without any extra software. This script depends only on inetd and bash.
I'm using Zoneminder with [http://nginx.net/ Nginx Httpd], which doesnt support simple CGI (just FastCGI). So I needed a leightweight solution to make ZMS work without any extra software. This script depends only on inetd and bash.


== Installation and Configuration ==


=== Installation ===
=== Installation ===


Just copy and paste the zms-inetd-script from below (Section "Script") into a text file and save it, for example, as ''/usr/local/bin/zms-inetd''. Don't forget to make it executable (chmod 755 /usr/local/bin/zms-inetd).
Just copy and paste the zms-inetd-script from below (Section "Script") into a text file and save it, for example, as <code>/usr/local/bin/zms-inetd</code>. Don't forget to make it executable (<code>chmod 755 /usr/local/bin/zms-inetd</code>).


=== /etc/services ===
=== /etc/services ===
Line 33: Line 33:


The last step is to adjust the web path (URL) to ZMS. This is done through the ZM-Webinterface > Options > Paths > Web path to zms streaming server (ZM_PATH_ZMS).  According to the configuration above this would be:
The last step is to adjust the web path (URL) to ZMS. This is done through the ZM-Webinterface > Options > Paths > Web path to zms streaming server (ZM_PATH_ZMS).  According to the configuration above this would be:
  http://<server>:85/<anypath>
  <nowiki>http://<server>:85/<anypath></nowiki>
It doesn't matter which path you specifiy as zms-inetd will always proxy to the ZMS cgi-binary for security reasons.
It doesn't matter which path you specifiy as zms-inetd will always proxy to the ZMS cgi-binary for security reasons.


Line 40: Line 40:
=== Make it transparent ===
=== Make it transparent ===


In combination with Nginx its propably useful not to point ZM directly to the zms-inetd port, but masq it with a reverse proxy configuration in Nginx.  That should avoid some problems if you want to reverse proxy the whole ZM installation (eg: from intranet to the internet).
In combination with Nginx its propably useful not to point ZM directly to the zms-inetd port, but mask it with a reverse proxy configuration in Nginx.  That should avoid some problems if you want to reverse proxy the whole ZM installation (eg: from intranet to the internet).


Example:
Example:
   location /zm/zms-inetd {
   location /zm/zms-inetd {
     proxy_pass  http://127.0.0.1:85;
     proxy_pass  <nowiki>http://127.0.0.1:85;</nowiki>
  }
  }


Of course you have to adjust the cgi-bin path (ZM_PATH_ZMS), for example, to /zm/zms-inetd.
Of course you have to adjust the cgi-bin path (ZM_PATH_ZMS) appropriate (eg: <code>/zm/zms-inetd</code>).


=== Other use cases for zms-inetd ===
=== Other use cases for zms-inetd ===


Another scenario where zms-inetd perhaps could also be used is a leightweight or embedded system, just running ZMS. For example the [http://busybox.net/ busybox] multibinary offers an inetd and a shell. Due the fact that zms-inetd is not heavily integrated with bash it should not be to hard to adapt it to ash (default shell in busybox).
Another scenario where zms-inetd perhaps could also be used is a leightweight or embedded system, just running ZMS. For example the [http://busybox.net/ busybox] multibinary offers an inetd and a shell. Due the fact that zms-inetd is not heavily integrated with bash it should not be too hard to adapt it to ash (default shell in busybox).


== Script ==
== Script ==
<source lang="shell">
<pre><nowiki>#!/bin/bash
#!/bin/bash  
#
#
# Inetd-wrapper for ZMS (Zoneminder Streaming Server)
# Inetd-wrapper for ZMS (Zoneminder Streaming Server)
#
#
# Version:      2007-09-27
# Author:      Kurt Zankl <kz@xon.uni.cc>
# Author:      Kurt Zankl <kz@xon.uni.cc>
# Inspiration:  http://www.debian-administration.org/articles/371
# Inspiration:  http://www.debian-administration.org/articles/371
# Requirements: bash, inetd
# Requirements: bash, inetd
# License:      GNU General Public License, Version 2
# License:      GNU General Public License, Version 2
#
#
# /etc/services:
# /etc/services:
#  zms-inetd      85/tcp  # Zoneminder ZMS inetd-wrapper
#  zms-inetd      85/tcp  # Zoneminder ZMS inetd-wrapper
#
#
# /etc/inetd.conf:
# /etc/inetd.conf:
#  zms-inetd      stream tcp nowait    www-data  /usr/local/bin/zms-inetd  zms-inetd
#  zms-inetd      stream tcp nowait    www-data  /usr/local/bin/zms-inetd  zms-inetd
#
#
# ZM Options / Paths / Web path to zms streaming server:
# ZM Options / Paths / Web path to zms streaming server:
#  ZM_PATH_ZMS = http://<server>:85/<anypath>
#  ZM_PATH_ZMS = http://<server>:85/<anypath>
#
#
 
# configuration
# configuration
ZMCONF="/usr/local/etc/zm.conf"
ZMCONF="/usr/local/etc/zm.conf"
CGIBIN="zms"
CGIBIN="zms"
 
# error handler
# error handler
function errormsg {
function errormsg {
  echo "HTTP/1.1 200 OK"
  echo "HTTP/1.0 500 Internal Server Error"
  echo "Content-Type: text/html"
  echo "Content-Type: text/html"
  echo
  echo
  echo "<h1>ERROR</h1>"
  echo "<title>ERROR</title><h1>ERROR</h1>"
  echo -e "<pre>$1</pre>"
  echo -e "<pre>$1</""pre>"
  echo
  exit 1
  exit 1
}
}
 
# get request
# read ZM configuration
read REQUEST
[ -r $ZMCONF ] || errormsg "Error reading Zoneminder configuration \"$ZMCONF\"";
# skip headers
. $ZMCONF
HEADER="nothing"; while [ "$HEADER" != $'\r' -a -n "$HEADER" ]; do read HEADER; done
ZMS="$ZM_PATH_CGI/$CGIBIN"
 
[ -x $ZMS ] || errormsg "Error finding ZMS executable \"$ZMS\"";
# read ZM configuration
[ -r $ZMCONF ] || errormsg "Error reading Zoneminder configuration \"$ZMCONF\""
# get request
. $ZMCONF
read REQUEST
ZMS="$ZM_PATH_CGI/$CGIBIN"
# skip headers
[ -x $ZMS ] || errormsg "Error finding ZMS executable \"$ZMS\""
HEADER="nothing"; while [ "$HEADER" != $'\r' -a -n "$HEADER" ]; do read HEADER; done
 
# check request
# check request
[ -z "$REQUEST" ] && errormsg "Request is empty"
[ -z "$REQUEST" ] && errormsg "Request is empty"
 
# split request
# split request
URL="${REQUEST#GET }"
URL="${REQUEST#GET }"
URL="${URL% HTTP/*}"
URL="${URL% HTTP/*}"
QUERY="${URL#*\?}"
QUERY="${URL#*\?}"
URL="${URL%%\?*}"
URL="${URL%%\?*}"
 
# check query
# check query
[ "$QUERY" == "$URL" ] && errormsg "Invalid query"
[ "$QUERY" == "$URL" ] && errormsg "Invalid query"
 
# execute ZMS
# execute ZMS
export QUERY_STRING="$QUERY"
# (STDERR output is discarded as this confuses MPEG streaming clients)
echo "HTTP/1.1 200 OK"
export QUERY_STRING="$QUERY"
"$ZMS"
echo "HTTP/1.0 200 OK"
echo
"$ZMS" 2>/dev/null
exit 0
echo
</source>
exit 0</nowiki></pre>

Latest revision as of 11:47, 4 April 2016

zms-inetd is an inetd-wrapper for the ZMS (Zoneminder Streaming Server), so ZMS can work "standalone".


Motivation

I'm using Zoneminder with Nginx Httpd, which doesnt support simple CGI (just FastCGI). So I needed a leightweight solution to make ZMS work without any extra software. This script depends only on inetd and bash.


Installation

Just copy and paste the zms-inetd-script from below (Section "Script") into a text file and save it, for example, as /usr/local/bin/zms-inetd. Don't forget to make it executable (chmod 755 /usr/local/bin/zms-inetd).

/etc/services

As for every inetd-service you have to define a port number in /etc/services:

zms-inetd       85/tcp   # Zoneminder ZMS inetd-wrapper

/etc/inetd.conf

Of course also an entry in the inetd configuration is needed. Please adapt this to your needs (user [= www], path):

zms-inetd       stream tcp nowait    www   /usr/local/bin/zms-inetd  zms-inetd

Path to zm.conf

Set the ZMCONF variable in the shell-script appropriate.

Zoneminder-Configuration

The last step is to adjust the web path (URL) to ZMS. This is done through the ZM-Webinterface > Options > Paths > Web path to zms streaming server (ZM_PATH_ZMS). According to the configuration above this would be:

http://<server>:85/<anypath>

It doesn't matter which path you specifiy as zms-inetd will always proxy to the ZMS cgi-binary for security reasons.

Further thoughts

Make it transparent

In combination with Nginx its propably useful not to point ZM directly to the zms-inetd port, but mask it with a reverse proxy configuration in Nginx. That should avoid some problems if you want to reverse proxy the whole ZM installation (eg: from intranet to the internet).

Example:

 location /zm/zms-inetd {
   proxy_pass  http://127.0.0.1:85;
}

Of course you have to adjust the cgi-bin path (ZM_PATH_ZMS) appropriate (eg: /zm/zms-inetd).

Other use cases for zms-inetd

Another scenario where zms-inetd perhaps could also be used is a leightweight or embedded system, just running ZMS. For example the busybox multibinary offers an inetd and a shell. Due the fact that zms-inetd is not heavily integrated with bash it should not be too hard to adapt it to ash (default shell in busybox).

Script

#!/bin/bash
#
# Inetd-wrapper for ZMS (Zoneminder Streaming Server)
#
# Version:      2007-09-27
# Author:       Kurt Zankl <kz@xon.uni.cc>
# Inspiration:  http://www.debian-administration.org/articles/371
# Requirements: bash, inetd
# License:      GNU General Public License, Version 2
#
# /etc/services:
#   zms-inetd       85/tcp   # Zoneminder ZMS inetd-wrapper
#
# /etc/inetd.conf:
#   zms-inetd       stream tcp nowait    www-data   /usr/local/bin/zms-inetd  zms-inetd
#
# ZM Options / Paths / Web path to zms streaming server:
#   ZM_PATH_ZMS = http://<server>:85/<anypath>
#

# configuration
ZMCONF="/usr/local/etc/zm.conf"
CGIBIN="zms"

# error handler
function errormsg {
  echo "HTTP/1.0 500 Internal Server Error"
  echo "Content-Type: text/html"
  echo
  echo "<title>ERROR</title><h1>ERROR</h1>"
  echo -e "<pre>$1</""pre>"
  exit 1
}

# get request
read REQUEST
# skip headers
HEADER="nothing"; while [ "$HEADER" != $'\r' -a -n "$HEADER" ]; do read HEADER; done

# read ZM configuration
[ -r $ZMCONF ] || errormsg "Error reading Zoneminder configuration \"$ZMCONF\""
. $ZMCONF
ZMS="$ZM_PATH_CGI/$CGIBIN"
[ -x $ZMS ] || errormsg "Error finding ZMS executable \"$ZMS\""

# check request
[ -z "$REQUEST" ] && errormsg "Request is empty"

# split request
URL="${REQUEST#GET }"
URL="${URL% HTTP/*}"
QUERY="${URL#*\?}"
URL="${URL%%\?*}"

# check query
[ "$QUERY" == "$URL" ] && errormsg "Invalid query"

# execute ZMS
# (STDERR output is discarded as this confuses MPEG streaming clients)
export QUERY_STRING="$QUERY"
echo "HTTP/1.0 200 OK"
"$ZMS" 2>/dev/null
echo
exit 0