Home Security: record CCTV cameras with ZoneMinder as DVR


Vinh Nguyen


March 24, 2016


I started working on this project and documenting it in late October 2014. I've only recently had the time to finish writing it all up.

I was interested in a home surveillance security system for a several reasons:

  1. a friend's house and car were burglarized three times in the last few years, and
  2. another friend was sued by his neighbor, claiming his dogs were excessively loud during the day.

A surveillance camera system would have helped in identifying the culprits in the first case. In the second case, my friend was able to bring video footage from his home CCTV surveillance system that he bought from Costco to court to disprove his neighbor's claim: that to the contrary, the dogs were not barking during the stated time.

In implementing my own CCTV surveillance security system on my premise, I had several options:

  1. purchase a system from a home monitoring security company and make monthly payments for their monitoring service,
  2. purchase a CCTV surveillance system that Costco, Sam's Club, and many online retailers sell, or
  3. build my own DIY system.

I decided on the DIY route because

  1. it saves me money in the long run (ie, no recurring fees),
  2. I have the freedom to configure it the way I want it,
  3. I am able to reuse the hardware and service if I ever decide to move, and
  4. the stars were aligned regarding the critical components:
    • the cost of an energy efficient server with a small footprint is relatively inexpensive
    • a fully mature open source software exists on Linux for monitoring and recording
    • commodity wireless cameras are relatively inexpensive (namely, Foscam FI8910W)
    • mobile phone apps exist for easy remote viewing (Android: tinyCam Monitor and ZmView)

Note: be mindful of the laws regulating surveillance and privacy in your local jurisdiction (for me, it's California).

The main ingredient to my home surveillance system is ZoneMinder, a Linux CCTV recording platform that doesn't require much processing power to run. More information about it's use could be found here and here.

Regarding cameras, I opted for wireless IP cameras over wired analogue cameras because wiring can make installations time-consuming and is something I'm just not very good at (this was the primary reason why I decided not to install a surveillance system from Costco when I first moved into my current house). In particular, I chose the Foscam FI8910W for inside the house and Foscam FI8904W for outside the house based on a friend's recommendation.

With the server's hardware, I wanted to maximize computing power while constraining power consumption (< 30W), cost ($200), and footprint (mini-ITX). It took a couple of days of research, but I found the Zotac ZBOX CI320 nano to be more than sufficient. Based on my testing, it consumes about 9W of power when recording one camera. This isn't too surprising as system is based on a quad-core Intel Celeron processor. I normally refrain from Celerons but this is plenty of juice for the server's only job: recording videos using ZoneMinder. I slapped on 8GB of ram and a 500GB hard drive 2.5" hard drive. Ideally, I would have liked to install a 4TB drive if I had a 3.5" slot or a maybe 2TB drive in the 2.5" slot. However, the drive was given to me for free and it more than suffices for making a few week's worth of video footages readily available. Update: this hard drive died after running for 1.5 years; I upgraded to a WD Red Mobile 2.5" 1TB server-grade hard drive.

Installing ZoneMinder

When configuring the server, first go into the BIOS (hold DEL during boot) and change the UEFI settings to Windows 7 (Windows 8 by default). Otherwise, the device will not boot without a monitor plugged in, and this will render the device useless as a headless server.

I originally planned to run CentOS 6.5 on the Zotac for stability, but was unable to install it because of some kernel issue when trying to install from the LiveCD. I therefore went with Ubuntu Server 14.04 (LTS), which I'm even more familiar with. During installation, I installed LAMP and OpenSSH as well in order to run ZoneMinder and manage the server remotely. Installation was relatively straightforward if you install from the repo (as of 3/24/2016, I used version 1.29.0) :

sudo apt-get update && sudo apt-get upgrade
sudo a2enmod cgi
sudo service apache2 restart
sudo apt-get install python-software-properties
sudo add-apt-repository ppa:iconnor/zoneminder
sudo apt-get update
sudo apt-get install zoneminder php5-gd libvlc-dev libvlccore-dev vlc
mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
mysql -uroot -p -e "grant all on zm.* to 'zmuser'@localhost identified by 'zmpass';"
mysqladmin -uroot -p reload
sudo chmod 740 /etc/zm/zm.conf
sudo chown root:www-data /etc/zm/zm.conf
sudo adduser www-data video

Add the sleep line in /etc/init.d/zoneminder:

start() {
      sleep 15
      echo -n "Starting $prog: "

Finish configuring with the following:

sudo a2enmod cgi
sudo a2enconf zoneminder
sudo a2enmod rewrite
sudo service zoneminder start

Edit date.time_zone in /etc/php5/apache2/php.ini:

; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = America/Los_Angeles

Restart the computer.

Configure SSL by doing:

sudo make-ssl-cert generate-default-snakeoil --force-overwrite
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo service apache2 restart

The encrypted url https://server.ip/zm should now work; the unencrypted url is http://server.ip/zm.

Configuring ZoneMinder

  • Go to http://server.ip/zm in the web browser
  • Go to Options > Paths and set PATH_ZMS to /zm/cgi-bin/nph-zms (Caution: make sure you enter only /zm/cgi-bin/nph-zms with no space at the end or your video will not work!)
  • Go to Options > Users: change the default admin username and password and add a new user for viewing only (no admin rights)
  • Go to Options > System: check OPT_USE_AUTH for to require user login and OPT_CONTROL to enable control on cameras
  • Go to Filters, select PurgeWhenFull from the Use Filter dropdown. Set Disk Percent to 90 so events (recorded videos) are deleted when the disk reaches 90%. Click Save.
    • The length of saved videos will thus depend on the hard drive's capacity and number of cameras.
  • On the main page, go to Running > Restart > Apply

Adding Cameras to ZoneMinder

I have a few Foscam FI8910W cameras, so I followed these instructions.

  • Check if /usr/share/perl5/ZoneMinder/Control/FI8918W.pm exists on the server; if not, download from https://github.com/ZoneMinder/ZoneMinder/blob/master/scripts/ZoneMinder/lib/ZoneMinder/Control/FI8918W.pm
  • Click Add New Monitor
    • In the General tab, give the camera a Name, set Source Type to Remote, and set Function to Mocord (Record and Motion Detection)
    • In the Source tab,
      • Enter in the camera's IP address in Remote Host Name
      • In the Remote Path field, enter /videostream.cgi?user=visitor_user&pwd=visitor_pw, where visitor_user and visitor_pw is the camera's login with at least visitor status
      • Enter 640 and 480 for width and height, and select Perserve Aspect Ratio
    • In the Control tab,
      • Set Controllable
      • Select Foscam FI8918W for Control Type
      • Set Control Address to the camera's IP address
      • Set Control Device to operator_user:operator_pw where operator_user and operator_pw are the camera's login info with at least operator status (this format is camera firmware specific)

Now, on the main ZoneMinder page, we could view the stream by clicking on each of the camera. From there, we could also view old recorded events.

On the ZoneMinder server, the recorded events (videos) are saved at /var/cache/zoneminder/events (many jpeg files since we are using the jpeg protocol of the Foscam camera).

Remote viewing

In order to view ZoneMinder outside the home network, set port forwarding on the local router. For example, one could use the ZmView app on an Android device to view the cameras remotely at https://server.ip:port/zm.

For remote viewing, it might be better to view directly from the cameras (so long as they are set up securely). Viewing the videos from ZoneMinder will increase the CPU load. Remember, the primary purpose of ZoneMinder is to record the video footage in case they are needed in a month.