Motion - Secure Webcam Feeds

HowTo: Secure your WebCam feeds using Apache, Basic Auth and SSL on Debian

This is a draft document detailing how to use Apache to lock down your webcam feeds using Basic Auth and the SSL module. It's not even nearly finished.

Although this document is designed so that anyone can understand it a few things are assumed:
  • You have a LAN rather than a single machine connected to the internet
  • You have a router between you and the internet (be it smoothwall, an ADSL modem/router, Windows Internet connection sharing)
  • A very basic understanding of TCP/IP

The webcam facility in motion is very useful, you can keep an eye on your house from pretty much anywhere in the world, but you do run the risk of someone finding the URL or IP address of you computer and spying on you!

This can easily be stopped by running the apache open source web server and using the mjprox module.

Here's how it's done using the built-in Apache basic auth modules, and for good measure I've also detailed setting up SSL. Hell, why not, it's easy to get working and it won't do any harm! Make use of it!

This guide is intended to be easy to follow for everyone wether they are a seasoned linux user or, like me, a novice. If you're keen - stick at it! You'll find it's not as scary as you think it is, and after a little while it actually starts making sense.

First install apache, obviously. If you use one of the more popular linux distributions (e.g Debian, Redhat, SuSE) you will probably find that there is a nice bundled package that's easy to install.

In Debian, as root, type:

apt-get install apache-ssl

Once the package has installed you will be asked a few questions about yourself and your server in order to create an SSL certificate. In the real world you would need to answer all these questions accurately, but since this is for personal use you don't really need to worry about it too much. Here's what I would use:

  • Country Code - GB
  • State or Provice - Just put a single full stop in here (that's how you leave a field blank)
  • Locality Name - .
  • Organization Name - Motion Camera Server
  • Organizational Unit - .
  • server name - WebCam
  • Email Address - Whatever you like!

The computer will have a bit of a think, ask you to save the changes and then you're done! Easy eh? Don't belive me? In your web browser go to https://<ip address of your server> and have a look. While you're there why not examine your newly minted certificate. Have you noticed something about it (other than the fact that loads of information is missing). Hint: Have a look at the expiry date. You'll notice that it is set to expire a month from when you created it. "What use is that?" I hear you cry. Well, not very much. We're going to have to create ourselves a different certificate. Don't worry, it's easy!

(Shamelessly lifted from this page)

Create a Certificate Authority - This seems to be broken at the moment. I think firefox doesnt like them any more

*For some reason the following doesn't work anymore, instead refer to this page *


cd /etc/ssl

openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 7000

First you will be asked for a PEM pass phrase. Make this a decent strength password, i.e. put a few numbers in there for good measure. Remember what it is!!!! When you've confirmed your password you'll notice that things start looking familiar. We're being asked the same information as we have just entered up there, except instead of Server Name you are asked for your name.

Now we create an SSL key for apache and sign it with our Certificate Authority (CA). We create the keys:

openssl req -new -config ./openssl.cnf -nodes -out ./apache-req.pem -keyout ./apache-key.pem

Again, you'll notice you're being asked for the same old information. You will also be asked to set a challenge password, remember what you put in here!

Now we sign them (the following is all one line). You'll notice we're giving them the OK for 365 days, change this if you want:

openssl x509 -req -in apache-req.pem -out apache-cert.pem -signkey apache-key.pem -CA cacert.pem -CAkey private/cakey.pem -CAcreateserial -days 365

So, that's all our keys created and stamped, now we just need to move them so that apache can get at them. We do this:

cp apache-cert.pem /etc/apache-ssl/apache.pem

cp apache-key.pem /etc/apache-ssl/apache-key.pem

All we have to do now is tell apache to make use of the new keys. To do this we need to edit the apache config file, which in out default environment is located in /etc/apache-ssl/httpd.conf So load that in to your text editor and look for SSLCertificateFile and SSLCertificateKeyFile

They need to read more like this:

SSLCertificateFile /etc/apache-ssl/apache.pem

SSLCertificateKeyFile /etc/apache-ssl/apache-key.pem

And there we go. A new SSL Certificate which is valid for a more reasonable ammount of time. All you need to do is restart apache for the new keys to be used:

/etc/init.d/apache-ssl restart

OK, so now we have encrypted our HTTP session we should really think about locking it down so that only the people we want to be able to access can. To do this we will use the BasicAuth built in to Apache. Basically it looks in a text file for a username and a hashed password, and if the username and the password match it lets you in.

In Debian the BasicAuth comes as standard, it probably comes as standard anyway, but I don't know for certain.

The way I have my system set up is detailed below. I expect that this can be done a much better way, but this works for me! Please feel free to edit this page and let us all know the proper way of doing things! To be honest I can't even remember why I did it this way, but I'm sure there was a reason, but I haven't got a clue what it was. smile

I want to be able to view the web page containing my camera streams in two ways.

  • Locally That is on the home LAN. When I'm at home I don't want to have to authenticate against my server. There's no need, I'm at home.

  • Remotely That is anywhere that isn't at home. Be it from an Internet cafe or at work, I don't want just anybody to be able to view my cameras or motion movies/images. So here I will use BasicAuth to force me to authenticate before I can get at the goodies inside.

So to do this I have create two virtual servers on two different IP addresses. One virtual server requires a log-in and the other doesn't. To allow your linux machine to talk on two different IP addresses you either need two network cards, or you can create a virtual network card.

Virtual Network Interface

Open up your /etc/network/interfaces file and you'll see something like this:

auto eth0
iface eth0 inet static

auto eth0 means that your network interface is bought up automatically at bootup

iface eth0 inet static indicates you have a static IP address rather than an automatically assigned DHCP address

And the rest of that stuff describes you IP address, router address and a load of other stuff that you don't really need to know about.

If you have a DHCP assigned address you might like to think about moving over to a static one. This will allow you to configure your network so that your router forwards all traffic on port 443 (the secure HTTP port) to the a static address. If this address keeps changing then you won't be able to communicate with your web server from the outside world.

To create a virtual network card create another entry below the one above like this:

auto eth0:0
iface eth0:0 inet static

You'll notice the only changes are the name of the interface, the virtual interface is :0 (you can have loads of virtual interfaces if you want) and the IP address is different. Everything else stays the same, as it's on the same network.

Once you have edited and saved the file, bring the interface up by typing:

ifup eth0:0

You should now be able to ping that IP address from anywhere on your network.

Now you have two network interfaces you can set up a web server on each one.

We will assume that your web pages are in /var/www/secure. That's where I put mine. For testing, create a simple HTML file called index.html and put it in the directory specified here. Something simple like:

    <h1><c>Hello world!</c></h1>

Edit your /etc/apache-ssl/httpd.conf file.

Go down to the bottom of the page and we'll insert some config to create the virtual servers

<IfModule mod_ssl.c>
   Listen 443
   AddType application/x-x509-ca-cert .crt
   AddType application/x-pkcs7-crl    .crl
   SSLMutex file:/var/run/mod_ssl_mutex
   SSLSessionCache         none
   SSLRandomSeed startup file:/dev/urandom 512
   SSLRandomSeed connect file:/dev/urandom 512

      DocumentRoot /var/www/secure
      ServerName webcam
      ScriptAlias /cgi-bin/ /var/www/secure/cgi-bin/
      SSLEngine on
      SSLCertificateFile    /etc/apache/ssl.crt/server.crt
      SSLCertificateKeyFile /etc/apache/ssl.key/server.key
      SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

      DocumentRoot /var/www/secure
      ServerName shitcam
      ScriptAlias /cgi-bin/ /var/www/secure/cgi-bin/   
      SSLEngine on
      SSLCertificateFile    /etc/apache/ssl.crt/server.crt
      SSLCertificateKeyFile /etc/apache/ssl.key/server.key
      SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
      <Directory />
             Options Indexes Includes FollowSymLinks MultiViews +ExecCGI
             AllowOverride AuthConfig
             Order allow,deny
             Allow from all
             AuthType basic
             AuthName "Your Server Name"
             AuthUserFile .htpassword
             Require valid-user


Let's break it down:

You'll see the whole lot is enclosed in IfModule, in this case the mod_ssl module, so both the virtual servers go through encryption (that's all the SSL stuff we've just set up). The stuff between the IfModule and the first VirtualServer is some sort of black magic to do with the SSL layer. I don't know what it means, so I've left it well alone. Now we come on to the interesting bit, the virtual servers.

The first virtual server is:
  • Running on IP address on port 443 (When the url starts http*s*: your browser automatically goes to port 443)
  • Serving the files in /var/www/secure
  • The servername is webcam
  • The CGI files are in /var/www/secure/cgi-bin/
  • SSL is on
  • The SSL certificate files are where we just put them (or in this case somwhere else!)
  • Something to handle Internet Explorer being a bit dodgy

The second virtual server is the one that requires authentication before it will let you in. It's basic setup is eactly the same as the first virtual server, except it listens on a different IP address, the IP address of your virtual network card. You will notice there is also some additional information contained within Directory tags. This is the stuff that switches on the authentication. The lines worthy of note are:

  • AuthType basic - Specifies that BasicAuth is the one to use. BasicAuth holds the users in a text file
  • AuthUserFile - This is the file which apache will look in for the list of users that can access the server. In debian this file is by default in /etc/apache You can put this file somewhere else if you want
  • Require valid-user - A valid-user is one where the username and password entered match those in the AuthUserFile. Basically this is saying "You must enter a valid username and password to be able to access the files".

And that's pretty much it! You now have two web servers running, one requires a username and password and the other one doesn't but both servers look at the same files. Save your httpd.conf file and then restart your apache server like this:

/etc/init.d/apache-ssl restart

Any errors that occur will be put in a log file in /var/log/apache-ssl/error.log. If this all looks good then go ahead and test your new servers. Point your web browser to https://real.ip.address and at https://virtual.ip.address. If everything is working you will get straight in on the real IP address and you will be asked to enter a username and password for the virtual IP address. As you will probably notice you are not able to log on to the virtual IP address server, and that's because we haven't created any users yet. So let's do that now.

Creating users

Apache comes with a tool called htpasswd which will do all the hard work for you.

If this is the first time you used this tool you will need to create the password file in which the passwords will be stored. You can get htpasswd to do this for you. So, if this is the first time you are running it type:

htpasswd -cm /etc/apache-ssl/.htpassword

You will be asked to enter the password, and again to confirm. Once you done this type:

cat /etc/apache-ssl/.htpassword

and you'll see your username followed by a load of letters and numbers. Those letters and numbers are your password in an MD5 hash. The -cm you put after the htpasswd told it to Create a new file and use MD5 hashes. So, once you've added your first user, you won't need the c any more (since the file has already been created).

To add further users type:

htpasswd -m /etc/apache-ssl/.htpassword

Once you've added yourself to the file try and use it to authenticate to your webserver. With a bit of luck it will let you in.

And that's that! You now have a web server running that you can access in saftey from anywhere.

Now, to see your camera(s) in the browser window you need to use the mjprox (MjpegProxyGrab) CGI program. See the MjpegProxyGrab for full details on how this works.
Topic revision: r13 - 20 Apr 2005, WillCooke
Copyright © 1999-2022 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Please do not email Kenneth for support questions (read why). Use the Support Requests page or join the Mailing List.
This website only use harmless session cookies. See Cookie Policy for details. By using this website you accept the use of these cookies.