Secure App Access to Raspberry Pi Camera

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-logitechc270

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

  1. 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. raspberry-pi-3-hero-1-1571x1080
  2. 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.
  3. An iOS or Android device.
  4. 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 pi@192.168.1.207
pi@192.168.1.207's password:
...
Last login: Sat Sep 9 09:14:12 2017 from mclappe2.home
pi@rpi:~ $

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

The nano editor on the RPI. It is highly recommended to learn another editor like vi or emacs if you are going to edit a lot of files - but nano seems a popular choice in tutorials.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):

Screen Shot 2017-09-09 at 19.29.17.pngThe 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

Screen Shot 2017-09-09 at 19.22.02

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_CRYPTO_MODULE=openssl_armv4 \
  -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).

Screen Shot 2017-09-09 at 20.29.24

Next, generate a license by clicking the “Generate license” button and enter 1 as quantity:

Screen Shot 2017-09-09 at 20.36.18

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:

Screen Shot 2017-09-09 at 20.38.32

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:

Screen Shot 2017-09-09 at 22.01.07.png

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:

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:

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.

 

Security in Nabto P2P/IoT solutions

Security in IoT and especially in home security solutions has been subject for several recent articles and debate, for instance see http://thenewstack.io/snooping-webcam-reveals-security-dangers-internet-things/.

Since the article above covers the general security issues of P2P, the same concerns of course apply to Nabto based solutions – this post addresses these concerns and summarizes the security principles of our platform, some of it applies to P2P solutions in general.

Basically, to allow a peer-to-peer connection to be established to a device, such as a camera, the camera must communicate with a central service that knows about the camera’s network configuration. This is not any different than in e.g. IP telephony where the IP phone central knows about each IP phone’s network configuration and needs to communicate periodically with each IP phone to allow other peers to make calls to it:

When a Nabto enabled device (e.g. a P2P IP camera) is turned on, it will try to register itself with its associated central services. Our approach to this is to use DNS – each Nabto enabled device has an associated DNS hostname, for instance <some-id>.p2p.vendor.net. This DNS name resolves to the Nabto “phone central” services, we denote this the “Nabto basestation”:

nabto-devices-white

The registration with the basestation takes place using strong cryptography using HMAC/SHA256 and AES128 with a per device unique shared secret. This allows a secure, private channel to be setup between the basestation and the device; all subsequent remote communication with the device is then encrypted for confidentiality and integrity. This approach without the need for asymmetric cryptography on the device enables Nabto to work on even the most resource constrained devices, e.g. sub 1-dollar 8-bit MCUs.

The client that communicates with the device is authenticated through an RSA X509 certificate. When a client initiates a connection towards a device, a secure channel is first established between client and basestation using a regular RSA based TLS handshake. A session key is then established and exchanged between client and device, along with IP information to allow a P2P connection attempt.

Once a connection is established, the device owner controls who accesses the device, the traffic cannot be manipulated and an attacker cannot intercept the communication.

nabto-security

This is all good as long as you can trust the owner of the basestation and that what I said above is actually true about the device code. The Nabto platform allows vendors to host their own private basestation – and most of our biggest customers indeed do that today. This means that Nabto is completely out of the loop. And that the vendor can have their servers located in their desired geographical region – so no need for communication with seemingly random hosts in e.g. China. The vendor can hence have a trust relationship solely with their customers (the end-user), the end-user sees no peculiar traffic between their device and an unknown 3rd party.

Our device SDK is open source, you can download everything on Github so you can see exactly what the communication is about. Of course this is not a guarantee – the individual vendor could in principle change the source code. But if you inspect the communication  with e.g. Wireshark and correlate with the available source code, the task for understanding the individual vendor’s product for an analyst is indeed simpler.

With all the above being said – much of the current discussion about P2P security is about the owner of the device not being able to turn P2P access off: It is of course up to the vendor to control how to activate the Nabto P2P functionality – but we make it simple to do so, we have a single “master switch”; if not turned on, there is absolutely no P2P related communication taking place.

For more information on security in the Nabto platform, don’t hesitate to contact us on support@nabto.com or take a look in our security guide TEN036 Security in Nabto Solutions.