Установка и настройка zoneminder на ubuntu linux. делаем систему видеонаблюдения

Zoneminder Database

Enable and convert MySQL to innodb_file_per_table for Zoneminder

Note: You may wish to convert MyISAM tables to InnoDB tables before you proceed. Upgrading Zoneminder to 1.26 or newer should do this for you.

innodb_file_per_table is by default ON Mysql 5.6.6 and onwards. There is plenty of stuff on Google about pros & cons of innodb_file_per_table.
This post details how to enable innodb_file_per_table on an existing database. Because innodb_file_per_table affects new tables only, created after innodb_file_per_table is enabled, we need to recreate old databases to force innodb_file_per_table on old tables and reclaim some disk space.

Become root

sudo su

Backup First
Create a dir to take backups:

cd ~

Note: I found it helpful to create a file which contained the MySQL user and password. Otherwise you will have to enter the user and password for every operation.

nano .my.cnf

Enter this content

user=root
password=mysqlpass

Ctrl+o Enter to save

CTRL+x to exit

Make backup directory

mkdir backup
cd backup

Copy MySQL data files (raw)
(If all goes well, we will not need this)

Stop Zoneminder

service zoneminder stop

If you have other services that use MySQL you will want to stop them and possibly Apache.

service mysql stop && cp -ra /var/lib/mysql mysqldata && service mysql start

Take mysqldump
As soon as above line completes, take a mysqldump of all databases

mysqldump --routines --events --flush-privileges --all-databases > all-db.sql

Drop Databases
Create a sql file to drop all databases EXCEPT mysql database

mysql -e "SELECT DISTINCT CONCAT ('DROP DATABASE ',TABLE_SCHEMA,' ;') FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA <> 'mysql' AND TABLE_SCHEMA <> 'information_schema';" | tail -n+2 > drop.sql

Verify if drop.sql has correct database names and then execute drop.sql queries.

mysql < drop.sql

Verify all InnoDB tables gone

SELECT table_name, table_schema, engine FROM information_schema.tables WHERE engine = 'InnoDB';

Remove InnoDB files
Stop mysql server first

service mysql stop

Then

rm /var/lib/mysql/ibdata1 && rm /var/lib/mysql/ib_logfile0 && rm /var/lib/mysql/ib_logfile1

At this point most likely you will have only /var/lib/mysql/mysql directory only.

Enable innodb_file_per_table

Open my.cnf file

nano /etc/mysql/my.cnf

Add following line after

innodb_file_per_table

Ctrl+o Enter to save

CTRL+x to exit

Time to import from mysqldump
Start mysql server now

service mysql start

Run mysql import

mysql < all-db.sql

Force mysql_upgrade (to generate performance_schema)

mysql_upgrade --force

That’s All!

Restart Zoneminder (and any other services you have stopped)

service zoneminder start

Check for proper operation and that all your events are present.

When you are satisfied that all is worling well remove the backup directory and password filr=e

cd ~
rm -r backup
rm .my.cnf

You are finished!

Adding Permissions to allow Database Upgrade

Versions of Zoneminder up to and including 1.28.1 in Ubuntu would automatically add the zm database to MySQL. Beginning about August
2015 the development version from the iconnor-master PPA omitted this step becoming like the Debian install process. Manually adding the
database to MySQL will be necessary.

To install the zm database (after doing apt-get install zoneminder)

Create Zoneminder database in MySQL (Note: this also creates the default Zoneminder user and permissions in MySQL)

This next step creates a file which contained the MySQL user and password. Otherwise you will have to enter the user and password on the
command line which is not secure!

Go to the root directory

cd ~

Create a hidden password file

nano .my.cnf

Enter this content (but use your MySQL root password!)

user=root
password=(mysqlpass)

Ctrl+o Enter to save

CTRL+x to exit

Create database permissions

mysql -e "grant select,insert,update,delete,create,alter,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';"

Remove password file

rm .my.cnf

Continue with the Zoneminder installation

Hardening Webserver

Hide Apache Version and Operating System

sudo vi /etc/apache2/conf-enabled/security.conf
ServerTokens Prod
ServerSignature Off
sudo systemctl restart apache2

Disable Directory Listing and FollowSymLinks

sudo vi /etc/apache2/apache2.conf
<Directory /var/www/>
        Options -Indexes -FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>
sudo systemctl restart apache2

Secure Apache using mod_security and mod_evasive Modules

Mod_security

Acts as a firewall for web servers and applications, providing protection against brute force attacks. Install it and then restart Apache.

sudo apt-get install libapache2-mod-security2 -y
sudo systemctl restart apache2

Disable TRACE HTTP Requestit Request Size

By default, Trace HTTP Request is enabled allowing for Cross Site Tracing. This enables a hacker to easily steal cookie information. Disabling Trace HTTP Request makes the mod_proxy and core server return “405 — Method Not Allowed” error message to clients.

sudo vi /etc/apache2/conf-enabled/security.conf
TraceEnable Off
sudo systemctl restart apache2

Easy Way: Debian Jessie¶

Step 1: Setup Sudo

By default Debian does not come with sudo. Log in as root or use su command.
N.B. The instructions below are for setting up sudo for your current account, you can
do this as root if you prefer.

apt-get update
apt-get install sudo
usermod -a -G sudo <username>
exit

Logout or try to reload user groups

Step 2: Run sudo and update

Now run session using sudo and ensure system is updated.

sudo -i
apt-get upgrade

Step 3: Install Apache and MySQL

These are not dependencies for the package as they could
be installed elsewhere.

apt-get install apache2 mysql-server

Step 4: Edit sources.list to add jessie-backports

nano etcaptsources.list

Add the following to the bottom of the file

# Backports repository
deb http//archive.debian.orgdebian jessie-backports main contrib non-free

CTRL+o and <Enter> to save
CTRL+x to exit

Run the following

echo 'Acquire::Check-Valid-Until no;' > etcaptapt.conf.d99no-check-valid-until

Step 5: Install ZoneMinder

apt-get update
apt-get install zoneminder

Step 6: Read the Readme

The rest of the install process is covered in the README.Debian, so feel free to have
a read.

zcat usrsharedoczoneminderREADME.Debian.gz

Step 7: Setup Database

Install the zm database and setup the user account. Refer to Hints in Ubuntu install
should you choose to change default database user and password.

cat usrsharezoneminderdbzm_create.sql | sudo mysql --defaults-file=/etcmysqldebian.cnf
echo 'grant lock tables,alter,create,select,insert,update,delete,index on zm.* to 'zmuser'@localhost identified by "zmpass";'    | sudo mysql --defaults-file=/etcmysqldebian.cnf mysql

Step 8: zm.conf Permissions

Adjust permissions to the zm.conf file to allow web account to access it.

chgrp -c www-data etczmzm.conf

Step 9: Setup ZoneMinder service

Step 10: Configure Apache

The following commands will setup the default /zm virtual directory and configure
required apache modules.

a2enconf zoneminder
a2enmod cgi
a2enmod rewrite

Step 11: Edit Timezone in PHP

nano etcphp5apache2php.ini

Search for (Ctrl + w then type Date and press Enter) and change
date.timezone for your time zone. Don’t forget to remove the ; from in front
of date.timezone

Date
; Defines the default timezone used by the date functions
; http//php.netdate.timezone
date.timezone = AmericaNew_York

CTRL+o then to save

CTRL+x to exit

Step 12: Please check the configuration

Zoneminder 1.32.x
  1. Check path of ZM_PATH in ‘/etc/zm/conf.d/zmcustom.conf’ is ZM_PATH_ZMS=/zm/cgi-bin/nph-zms
    ::

    cat /etc/zm/conf.d/zmcustom.conf

  2. Check config of /etc/apache2/conf-enabled/zoneminder.conf has the same ScriptAlias /zm/cgi-bin that is configured
    in ZM_PATH. The part /nph-zms has to be left out of the ScriptAlias

Step 13: Start ZoneMinder

Reload Apache to enable your changes and then start ZoneMinder.

systemctl reload apache2
systemctl start zoneminder

Step 14: Making sure ZoneMinder works

  1. Open up a browser and go to — should bring up ZoneMinder Console

  2. (Optional API Check)Open up a tab in the same browser and go to

Congratulations Your installation is complete

Configuration Apis¶

The APIs allow you to access all the configuration parameters of ZM that you typically set inside the web console.
This returns the full list of configuration parameters:

curl -XGET http//serverzmapiconfigs.json

Each configuration parameter has an Id, Name, Value and other fields. Chances are you are likely only going to focus on these 3.

The edit function of the Configs API is a little quirky at the moment. Its format deviates from the usual edit flow of other APIs. This will be fixed, eventually. For now, to change the “Value” of ZM_X10_HOUSE_CODE from A to B:

curl -XPUT http//serverzmapiconfigseditZM_X10_HOUSE_CODE.json  -d "Config=B"

To validate changes have been made:

NFS-Shares in ZoneMinder einbinden

sudo service zoneminder stop

NFS Client installieren und konfigurieren

sudo apt-get install nfs-client nfs-common
sudo modprobe nfs
sudo su -
echo NFS | tee -a /etc/modules
exit
sudo cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

NFS
sudo cp /etc/idmapd.conf /etc/idmapd.conf_orig
sudo vi /etc/idmapd.conf

Verbosity = 0
Pipefs-Directory = /run/rpc_pipefs
# set your own domain here, if it differs from FQDN minus hostname
Domain = localdomain



Nobody-User = nobody
Nobody-Group = nogroup

ZoneMinder event storage

sudo vi /etc/systemd/system/var-cache-zoneminder-events.mount
# systemd NFS mount for ZoneMinder event storage


Description=NFS mount for ZoneMinder event storage
After=network.target
Before=zoneminder


What=192.168.1.5:/volume1/ZoneMinder
Where=/var/cache/zoneminder/events
Type=nfs


WantedBy=multi-user.target
sudo systemctl enable var-cache-zoneminder-events.mount
sudo systemctl start var-cache-zoneminder-events.mount
sudo systemctl status var-cache-zoneminder-events.mount

ZoneMinder cache storage

sudo vi /etc/systemd/system/var-cache-zoneminder-cache.mount
# systemd NFS mount for ZoneMinder cache storage


Description=NFS mount for ZoneMinder cache storage
After=network.target
Before=zoneminder


What=192.168.1.5:/volume1/ZoneMinder
Where=/var/cache/zoneminder/cache
Type=nfs


WantedBy=multi-user.target
sudo systemctl enable var-cache-zoneminder-cache.mount
sudo systemctl start var-cache-zoneminder-cache.mount
sudo systemctl status var-cache-zoneminder-cache.mount

ZoneMinder images storage

sudo vi /etc/systemd/system/var-cache-zoneminder-images.mount
# systemd NFS mount for ZoneMinder images storage


Description=NFS mount for ZoneMinder images storage
After=network.target
Before=zoneminder


What=192.168.1.5:/volume1/ZoneMinder
Where=/var/cache/zoneminder/images
Type=nfs


WantedBy=multi-user.target
sudo systemctl enable var-cache-zoneminder-images.mount
sudo systemctl start var-cache-zoneminder-images.mount
sudo systemctl status var-cache-zoneminder-images.mount

ZoneMinder temp storage

sudo vi /etc/systemd/system/var-cache-zoneminder-temp.mount
# systemd NFS mount for ZoneMinder temp storage


Description=NFS mount for ZoneMinder temp storage
After=network.target
Before=zoneminder


What=192.168.1.5:/volume1/ZoneMinder
Where=/var/cache/zoneminder/temp
Type=nfs


WantedBy=multi-user.target
sudo systemctl enable var-cache-zoneminder-temp.mount
sudo systemctl start var-cache-zoneminder-temp.mount
sudo systemctl status var-cache-zoneminder-temp.mount
sudo init 6

Misc Tab¶

Event Prefix
By default events are named ‘Event-<event id>’, however you are free to rename them individually as you wish. This option lets you modify the event prefix, the ‘Event-‘ part, to be a value of your choice so that events are named differently as they are generated. This allows you to name events according to which monitor generated them.
Section Length
This specifies the length (in seconds) of any fixed length events produced when the monitor function is ‘Record’ or ‘Mocord’. Otherwise it is ignored. This should not be so long that events are difficult to navigate nor so short that too many events are generated. A length of between 300 and 900 seconds I recommended.
Frame Skip
This setting also applies only to the ‘Record’ or ‘Mocord’ functions and specifies how many frames should be skipped in the recorded events. The default setting of zero results in every captured frame being saved. Using a value of one would mean that one frame is skipped between each saved, two means that two frames are skipped between each saved frame etc. An alternate way of thinking is that one in every ‘Frame Skip + 1’ frames is saved. The point of this is to ensure that saved events do not take up too much space unnecessarily whilst still allowing the camera to capture at a fairly high frame rate. The alternate approach is to limit the capture frame rate which will obviously affect the rate at which frames are saved.
FPS Report Interval
How often the current performance in terms of Frames Per Second is output to the system log. Not used in any functional way so set it to maybe 1000 for now. If you watch /var/log/messages (normally) you will see this value being emitted at the frequency you specify both for video capture and processing.
Default Scale
If your monitor has been defined with a particularly large or small image size then you can choose a default scale here with which to view the monitor so it is easier or more visible from the web interface.
Web Colour
Some elements of ZoneMinder now use colours to identify monitors on certain views. You can select which colour is used for each monitor here. Any specification that is valid for HTML colours is valid here, e.g. ‘red’ or ‘#ff0000’. A small swatch next to the input box displays the colour you have chosen.
Embed EXIF data into image:

Embeds EXIF data into each jpeg frame

Todo

what about mp4s?

Zoneminder Multi Server on Ubuntu

10MAY18 — Tested this procedure with Ubuntu Bionic 18.04 with Zoneminder 1.30.4, Mariadb, Apache2 and PHP 7.2 installed per the WIKI instructions with the shell script.

For this procedure my servers were:

Name — u2 IP address 192.168.50.2 This is the storage and database server

Name — u3 IP address 192.168.50.3 This is the remote zoneminder server

It is possible to use a separate database server and a seperate storage server. Your storage server does need to have a Linux file system on it as Zoneminder uses symbolic links and a Windows (NTFS, FAT32) does not know about symbolic links. You can also use Samba to mount the storage drive but this is written to use NFS.

I use Putty from a Windows PC to connect to the servers as I can copy the commands from this web page and paste them into Putty. This is the easy way for me!

Database and Storage Server

Stop the Zoneminder service

service zoneminder stop

Edit the my.conf. Change bind-address to: bind-address = 0.0.0.0

nano /etc/mysql/my.cnf

Ctrl+o Enter to save

CTRL+x to exit

Restart MySQL

systemctl restart mysql

Grant remote user access (Note: for additional remote servers add them using their IP address)

mysql -uroot -p -e "grant all on zm.* to 'zmuser'@192.168.50.2 identified by 'zmpass';"
mysql -uroot -p -e "grant all on zm.* to 'zmuser'@192.168.50.3 identified by 'zmpass';"

Install the NFS server

apt install nfs-kernel-server

Add the export directory

nano /etc/exports

Add to the end of the file (Note: for additional remote servers add additional lines using their IP address)

/var/cache/zoneminder/events 192.168.50.3(rw,sync,no_subtree_check)

Ctrl+o Enter to save

CTRL+x to exit

Restart the NFS server

systemctl restart nfs-kernel-server

Edit the Zoneminder config file

nano /etc/zm/zm.conf

Change these two lines

ZM_DB_HOST=192.168.50.2

ZM_SERVER_HOST=u2

Ctrl+o Enter to save

CTRL+x to exit

Start Zoneminder service

service zoneminder start

Local Zoneminder Server(s)

If you have more than one remote server repeat this procedure on each one adjusting the host name for each.

Stop Zoneminder

service zoneminder stop

Edit the Zoneminder config file

nano /etc/zm/zm.conf

Change these two lines

ZM_DB_HOST=192.168.50.2

ZM_SERVER_HOST=u3

Ctrl+o Enter to save

CTRL+x to exit

Install NFS client

apt install nfs-client
modprobe nfs
echo NFS | tee -a /etc/modules

Create a systemd file for the mount

nano /etc/systemd/system/var-cache-zoneminder-events.mount

Copy and paste everything between the lines into the systemd file

# systemd mount unit for ZoneMinder event storage


Description=systemd mount unit for ZoneMinder event storage
After=network.target
Before=zoneminder
 

What=192.168.50.2:/var/cache/zoneminder/events
Where=/var/cache/zoneminder/events
Type=nfs
 

WantedBy=multi-user.target

Ctrl+o Enter to save

CTRL+x to exit

Save and start the mount

systemctl enable var-cache-zoneminder-events.mount
systemctl start var-cache-zoneminder-events.mount

Start the Zoneminder service

service zoneminder start

In a web browser open Zoneminder on one of the servers. (Note: you may want to check all your servers to insure Zoneminder is started on each. You may have to reboot each server to get Zoneminder to start)

Click on Options — Servers — Add New Server

In the Name block add a name of one of your servers. In my example the first server name is u2.

In the Hostname block enter the IP address of the first server. In my example it is 192.168.50.2

Click Save

Add the rest of your servers in the same way. Close the Options window when your servers have been added.

Storage and Server APIs¶

ZoneMinder introduced many new options that allowed you to configure multiserver/multistorage configurations. While a part of this was available in previous versions, a lot of rework was done as part of ZM 1.31 and 1.32. As part of that work, a lot of new and useful APIs were added. Some of these are part of ZM 1.32 and others will be part of ZM 1.32.3 (of course, if you build from master, you can access them right away, or wait till a stable release is out.

This returns storage data for my single server install. If you are using multi-storage, you’ll see many such “Storage” entries, one for each storage defined:

curl http//serverzmapistorage.json

Returns:

{
    "storage" 
        {
            "Storage" {
                "Id" "0",
                "Path" "\/var\/cache\/zoneminder\/events",
                "Name" "Default",
                "Type" "local",
                "Url" null,
                "DiskSpace" "364705447651",
                "Scheme" "Medium",
                "ServerId" null,
                "DoDelete" true
            }
         }
       
}

“DiskSpace” is the disk used in bytes. While this doesn’t return disk space data as rich as , it is much more efficient.

Similarly,

curl http//serverzmapiservers.json

Returns:

{
      "servers" 
          {
              "Server" {
                  "Id" "1",
                  "Name" "server1",
                  "Hostname" "server1.mydomain.com",
                  "State_Id" null,
                  "Status" "Running",
                  "CpuLoad" "0.9",
                  "TotalMem" "6186237952",
                  "FreeMem" "156102656",
                  "TotalSwap" "536866816",
                  "FreeSwap" "525697024",
                  "zmstats" false,
                  "zmaudit" false,
                  "zmtrigger" false
              }
          }
      
  }

Streaming Interface¶

Developers working on their application often ask if there is an “API” to receive live streams, or recorded event streams.
It is possible to stream both live and recorded streams. This isn’t strictly an “API” per-se (that is, it is not integrated
into the Cake PHP based API layer discussed here) and also why we’ve used the term “Interface” instead of an “API”.

Live Streams

What you need to know is that if you want to display “live streams”, ZoneMinder sends you streaming JPEG images (MJPEG)
which can easily be rendered in a browser using an tag.

For example:

<img src="https://yourserver/zm/cgi-bin/nph-zms?scale=50&width=640p&height=480px&mode=jpeg&maxfps=5&buffer=1000&&monitor=1&auth=b54a589e09f330498f4ae2203&connkey=36139" />

will display a live feed from monitor id 1, scaled down by 50% in quality and resized to 640x480px.

  • This assumes is your CGI_BIN path. Change it to what is correct in your system
  • The “auth” token you see above is required if you use ZoneMinder authentication. To understand how to get the auth token, please read the “Login, Logout & API security” section below.
  • The “connkey” parameter is essentially a random number which uniquely identifies a stream. If you don’t specify a connkey, ZM will generate its own. It is recommended to generate a connkey because you can then use it to “control” the stream (pause/resume etc.)
  • Instead of dealing with the “auth” token, you can also use where “username” and “password” are your ZoneMinder username and password respectively. Note that this is not recommended because you are transmitting them in a URL and even if you use HTTPS, they may show up in web server logs.

PTZ on live streams

PTZ commands are pretty cryptic in ZoneMinder. This is not meant to be an exhaustive guide, but just something to whet your appetite:

Lets assume you have a monitor, with ID=6. Let’s further assume you want to pan it left.

You’d need to send a:
command to with the following data payload in the command (NOT in the URL)

Obviously, if you are using authentication, you need to be logged in for this to work.

Like I said, at this stage, this is only meant to get you started. Explore the ZoneMinder code and use “Inspect source” as you use PTZ commands in the ZoneMinder source code.
control_functions.php is a great place to start.

Pre-recorded (past event) streams

Similar to live playback, if you have chosen to store events in JPEG mode, you can play it back using:

<img src="https://yourserver/zm/cgi-bin/nph-zms?mode=jpeg&frame=1&replay=none&source=event&event=293820&connkey=77493&auth=b54a58f5f4ae2203" />
  • This assumes is your CGI_BIN path. Change it to what is correct in your system
  • This will playback event 293820, starting from frame 1 as an MJPEG stream
  • Like before, you can add more parameters like etc.
  • auth and connkey have the same meaning as before, and yes, you can replace auth by as before and the same security concerns cited above apply.

If instead, you have chosen to use the MP4 (Video) storage mode for events, you can directly play back the saved video file:

<video src="https://yourserver/zm/index.php?view=view_video&eid=294690&auth=33f3d558af84cf08" type="video/mp4"></video>

This will play back the video recording for event 294690

Storage and Server APIs¶

ZoneMinder introduced many new options that allowed you to configure multiserver/multistorage configurations. While a part of this was available in previous versions, a lot of rework was done as part of ZM 1.31 and 1.32. As part of that work, a lot of new and useful APIs were added. Some of these are part of ZM 1.32 and others will be part of ZM 1.32.3 (of course, if you build from master, you can access them right away, or wait till a stable release is out.

This returns storage data for my single server install. If you are using multi-storage, you’ll see many such “Storage” entries, one for each storage defined:

curl http//serverzmapistorage.json

Returns:

{
    "storage" 
        {
            "Storage" {
                "Id" "0",
                "Path" "\/var\/cache\/zoneminder\/events",
                "Name" "Default",
                "Type" "local",
                "Url" null,
                "DiskSpace" "364705447651",
                "Scheme" "Medium",
                "ServerId" null,
                "DoDelete" true
            }
         }
       
}

“DiskSpace” is the disk used in bytes. While this doesn’t return disk space data as rich as , it is much more efficient.

Similarly,

curl http//serverzmapiservers.json

Returns:

{
      "servers" 
          {
              "Server" {
                  "Id" "1",
                  "Name" "server1",
                  "Hostname" "server1.mydomain.com",
                  "State_Id" null,
                  "Status" "Running",
                  "CpuLoad" "0.9",
                  "TotalMem" "6186237952",
                  "FreeMem" "156102656",
                  "TotalSwap" "536866816",
                  "FreeSwap" "525697024",
                  "zmstats" false,
                  "zmaudit" false,
                  "zmtrigger" false
              }
          }
      
  }

MySQL installieren

sudo apt-get install mysql-server
sudo mysql
mysql> SHOW databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
mysql> exit

Standardmäßig hat MySQL nur den Benutzer root. Mit diesem Benutzer kann man sich an der Datenbank anmelden, wenn man als root auf dem Linux Betriebssystem den Befehl mysql ausführt. Eine Passworteingabe ist nicht nötig.

Es ist empfehlenswert einen weiteren Benutzer anzulegen, der sich per Passwort verbinden kann. So kann beispielsweise über ein PHP Skript etc. auf die Datenbank zugegriffen werden. Der Benutzer kann folgendermaßen angelegt werden:

sudo mysql -e "CREATE USER 'mysqluser'@'localhost' IDENTIFIED BY 'mysqlpassword';"
sudo mysql -e "GRANT ALL PRIVILEGES ON * . * TO 'mysqluser'@'localhost' WITH GRANT OPTION;"
sudo mysql -e "FLUSH PRIVILEGES;"
mysql -u mysqluser -p
exit
Datenbank Adminbenutzer: mysqluser
Kennwort: mysqlpassword

Understanding key security¶

  • Version 1.0 uses an MD5 hash to generate the credentials. The hash is computed over your secret key (if available), username, password and some time parameters (along with remote IP if enabled). This is not a secure/recommended hashing mechanism. If your auth hash is compromised, an attacker will be able to use your hash till it expires. To avoid this, you could disable the user in ZoneMinder. Furthermore, enabling remote IP () requires that you issue future requests from the same IP that generated the tokens. While this may be considered an additional layer for security, this can cause issues with mobile devices.
  • Version 2.0 uses a different approach. The hash is a simple base64 encoded form of “claims”, but signed with your secret key. Consider for example, the following access key:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJab25lTWluZGVyIiwiaWF0IjoxNTU3OTQwNzUyLCJleHAiOjE1NTc5NDQzNTIsInVzZXIiOiJhZG1pbiIsInR5cGUiOiJhY2Nlc3MifQ.-5VOcpw3cFHiSTN5zfGDSrrPyVya1M8_2Anh5u6eNlI

If you were to use any JWT token verifier it can easily decode that token and will show:

{
"iss" "ZoneMinder",
"iat" 1557940752,
"exp" 1557944352,
"user" "admin",
"type" "access"
}
Invalid Signature

Don’t be surprised. JWT tokens, by default, are not meant to be encrypted. It is just an assertion of a claim. It states that the issuer of this token was ZoneMinder,
It was issued at (iat) Wednesday, 2019-05-15 17:19:12 UTC and will expire on (exp) Wednesday, 2019-05-15 18:19:12 UTC. This token claims to be owned by an admin and is an access token. If your token were to be stolen, this information is available to the person who stole it. Note that there are no sensitive details like passwords in this claim.

However, that person will not have your secret key as part of this token and therefore, will NOT be able to create a new JWT token to get, say, a refresh token. They will however, be able to use your access token to access resources just like the auth hash above, till the access token expires (2 hrs). To revoke this token, you don’t need to disable the user. Go to and tap on “Revoke All Access Tokens”. This will invalidate the token immediately (this option will invalidate all tokens for all users, and new ones will need to be generated).

Over time, we will provide you with more fine grained access to these options.

Summarizing good practices:

  • Use HTTPS, not HTTP
  • If possible, use free services like LetsEncrypt instead of self-signed certificates (sometimes this is not possible)
  • Keep your tokens as private as possible, and use them as recommended above
  • If you believe your tokens are compromised, revoke them, but also check if your attacker has compromised more than you think (example, they may also have your username/password or access to your system via other exploits, in which case they can regenerate as many tokens/credentials as they want).
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *