In this post we will show you how to set up a standard USB webcam with a Raspberry Pi (RPI) and the AppMyProduct service for easy access and high security: There are already many good guides out there that demonstrate how to setup a webcam with the RPI – but they all leave the reader with a combination of firewall hassle and very poor security: You will have to setup port forwarding in the WAN router to access the RPI and there is no encryption or access control. So a lot of hassle and risk of strangers peeking through your webcam.
With a few additional, simple steps as compared to these existing guides, you can eliminate the firewall hassle, add strong encryption and a robust access control mechanism – Nabto’s AppMyProduct to the rescue!
RPI + Logitech C270
Once you are done, you will be able to securely access your RPI Webcam from anywhere through the AppMyProduct Video App – without any firewall fiddling or messing with DynDNS and self-signed certificates. As you will see below, the apps are freely available from the app stores – and the source code is available so you can tweak yourself. It is a hybrid app, so you can make many interesting changes and additions by just knowing basic HTML.
What you need
- A Raspberry Pi board with a Raspbian image installed. We have tested with 2nd and 3rd generation boards, 1st generation will most likely also work like a charm.
- A camera connected to the PI, this guide assumes a USB webcam but you can use anything that works with the Motion software package, including Raspberry Pi camera modules.
- An iOS or Android device.
- An AppMyProduct account – create one for free on www.appmyproduct.com, no credit card necessary and you can add several devices completely free of charge for development, testing, home and educational use.
Step 1: Log on to the RPI
Log on to your RPI, either directly if you have it connected to a display with keyboard or through ssh from a computer on your network:
$ ssh email@example.com
Last login: Sat Sep 9 09:14:12 2017 from mclappe2.home
The default password for the pi user is raspberry.
Step 2: Install software
The following must be installed:
- Motion – webcam software
- CMake, Git and Ninja – to build the Nabto remote access software
Log on to the RPI as described above and perform the following steps:
$ sudo apt-get update
Fetched 9,707 kB in 22s (439 kB/s)
Reading package lists... Done
$ sudo apt-get install motion
$ sudo apt-get install git cmake ninja-build
Unpacking ninja-build (1.3.4-1.2) ...
Processing triggers for man-db (2.7.5-1~bpo8+1) ...
Setting up ninja-build (1.3.4-1.2) ...
If you already have a running webcam and just want to setup remote access, only lines 1 and 7 are necessary.
Step 3: Configure the webcam software
In this step we must edit two configuration files on the RPI. If you have a favorite editor and know your way around, just do the following:
- set “daemon on” and “stream_localhost on” in /etc/motion/motion.conf
- set “start_motion_daemon=yes” in /etc/default/motion
For a bit more detail:
Log on to the RPI as described above and start the nano editor in the console to enable the webcam software to run as a background service:
pi@rpi:~ $ sudo nano /etc/motion/motion.conf
Change “daemon off” to “daemon on” (the line with the cursor above).
Next, as an extra security measure, you can disable insecure remote access to the camera. You can do this by setting “stream_localhost on” in the same file (when we install the secure remote access software in a moment, it will access the camera from localhost):
The tricky part is to exit this nano editor … press “control-x” (to exit), press “y” (to save) and press enter (to use the default suggested filename).
Next, we must start the webcam software when the RPI boots:
pi@rpi:~ $ sudo nano /etc/default/motion
Set “start_motion_daemon=yes” and exit as described above (control-x, “y”, enter).
Finally, start the webcam service:
pi@rpi:~ $ sudo service motion start
Step 4: Build the remote access software
Perform the following steps on the RPI (ie, log on to the device or continue in the shell from above).
First, retrieve the remote access source code from the github repo https://github.com/nabto/unabto.git:
$ mkdir git
$ cd git
$ git clone https://github.com/nabto/unabto.git
Cloning into 'unabto'...
remote: Counting objects: 5745, done.
remote: Total 5745 (delta 0), reused 0 (delta 0), pack-reused 5745
Receiving objects: 100% (5745/5745), 2.63 MiB | 1.55 MiB/s, done.
Resolving deltas: 100% (3388/3388), done.
Next, run cmake to prepare the build of the uNabto tunnel service. The key step in line 4 below is quite long, so scroll a bit to see it all or look below where we have zoomed in on it:
$ cd unabto/apps/tunnel
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release -DUNABTO_CRYPTO_MODULE=openssl_armv4 -DUNABTO_RANDOM_MODULE=openssl_armv4 -GNinja ..
-- The C compiler identification is GNU 4.9.2
-- The ASM compiler identification is GNU
-- Found assembler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc
-- Generating done
-- Build files have been written to: /home/pi/git/unabto/apps/tunnel/build
The cmake invocation in step 4 looks as follows:
cmake -DCMAKE_BUILD_TYPE=Release \
-DUNABTO_RANDOM_MODULE=openssl_armv4 -GNinja ..
Just FYI – the Ninja tool used is an alternative to standard make tool; it builds much faster on the RPI than make, likely because Ninja has optimized filesystem access on the quite slow RPI.
Now you can build the tunnel:
pi@rpi:.../build $ ninja
[77/77] Linking C executable unabto_tunnel
Check you can execute the unabto_tunnel binary (./unabto_tunnel) and copy the resulting binary into /usr/bin:
pi@rpi:.../build $ sudo cp unabto_tunnel /usr/bin
Step 5: Create an AppMyProduct device
For this step, you need an AppMyProduct account – go to https://www.appmyproduct.com and sign up if you haven’t done so already.
Next, create a product – you don’t have to tick the “Free product” checkbox, you get a few regular licenses for free with your account (in this way you don’t have to see ads for the first devices you use).
Next, generate a license by clicking the “Generate license” button and enter 1 as quantity:
You now have everything you need to run the tunnel on the device – the device id and the key revealed when clicking “Show License Key” are used in the next step:
Step 6: Configure the tunnel
Log on to the RPI or continue your session above. Edit the file ./git/unabto/apps/tunnel/scripts/unabto_tunnel.conf:
pi@rpi:~ $ cd git/unabto/apps/tunnel/scripts
pi@rpi:.../scripts $ nano unabto_tunnel.conf
Replace the device id and key fields with what you retrieved from the AppMyProduct portal in step 5:
The port number 8081 matches the default configuration of the Motion webcam service, change this if you use a different port number.
Install the startup script and config file from the scripts directory:
$ sudo cp unabto_tunnel.conf /etc
$ sudo cp unabto_tunnel_initd /etc/init.d/unabto_tunnel
$ sudo chmod +x /etc/init.d/unabto_tunnel
$ sudo update-rc.d unabto_tunnel defaults
$ sudo /etc/init.d/unabto_tunnel start
Now everything should be working like a charm! Before actually firing up the app and enjoying remote access to your webcam, let’s check everything looks ok:
$ ps auwwx | grep unabto_tunnel | grep -v grep
pi 16300 0.1 0.2 18428 1932 ? 21:00 0:00 /usr/bin/unabto_tunnel /usr/bin/unabto_tunnel -d vtquiht9.xmnqf.appmyproduct.com -s -k
If nothing is seen as output of the ps command, go back to step 4 and make sure you can execute the binary after building it – and that you copied it into /usr/bin. If this does not help, write a comment below with your error message.
Also check the webcam service is running fine:
pi@rpi:.../scripts $ ps auwwx | grep motion | grep -v grep
motion 15762 1.4 1.1 53716 10020 ? Sl 20:31 1:13 /usr/bin/motion
If nothing is seen here, make sure everything was installed correctly in step 2. Also, check Motion’s FAQ.
Step 7: Access the webcam
Visit Apple’s App Store or Google Play to download the AppMyProduct Video app. Start the app on the same network as the RPI to discover the device by tapping “Add new” and pair on the subsequent screens:
Discover new device
After pairing, you can see the actual webcam feed from anywhere – your communication with the camera is encrypted and only paired clients are allowed access. You can change settings for the device to control remote access:
The Video Feed
On the security settings page, you should disable “Open for pairing” when you don’t want to allow further clients access to the camera. In the Access Control List you can see all the paired clients, ie who has access. You can delete the individual users with access by tapping the element.
Note that the “player” is extremely simple – it can only be used to show the default MJPG stream from the webcam. In a later blog post in this series we will add support for more advanced players for better video quality and also for adding sound.
You can download the source code for the player app from the ionic-starter-nabto-video github repo – it is a hybrid app you can edit by knowing just basic HTML. We will get back to this in a later post, demonstrating how to add new features to the webcam app.
Further Reading on Security
Some of you have asked for a bit of elaboration on how access control works in more detail and how we make sure only the intended users can access the device. It is a bit out of the scope to go into detail with in this post – but the AppMyProduct Video app and the tunnel software installed on the RPI use the Nabto platform under the hood for communication.
The platform provides a few different ways to control access, in this project we use the “Paired Public Key Authentication” approach outlined in section 8.2 of TEN036 “Security in Nabto Solutions”. Basically this ensures that only clients that possess the private key of an RSA keypair where the public key has been installed on the RPI is allowed to access the camera. In addition to the introduction above, you can read more about it in the Fingerprint ACL module documentation in the uNabto SDK.
For a more general introduction to security in the Nabto platform, the remaining sections of TEN036 “Security in Nabto Solutions are a good read – and also, we have a short introduction in this blog post.