Raspberry Pi Fishcam – The Secure Version
Posted by Craig H on 16 August 2013
Having proved the concept using netcat, we need to add access control and make it accessible via a discoverable external address. The design is essentially the same, running the video capture command on the Pi and routing the output stream over IP to a remote client, but we use ssh (Secure SHell) as the transport to add authentication and encryption.
The first thing to do before exposing your Pi to the outside world is: change the default password! With Raspbian, the default admin user name and password is “pi” and “raspberry”. You should change the password to something that’s not based on a name or word that could be found in a cracking dictionary; best would be a randomly generated password that you write down and keep with you, or you can use initial letters of words in a sentence you can remember but others can’t guess. For extra security you could change the name of the admin account too.
Remote Access User Account
To make sure that any problems with our setup won’t allow bad guys into our home network, we use a dedicated account without super-user privileges for the remote camera access. We also disable normal user name and password access for this account, as remote access will use an RSA private key for authentication. Finally, we change the account’s shell so login goes directly to the camera software script; even if someone were able to steal the private key they would still only be able to look at our fish 🙂
Run this command on the Pi to create the account:sudo adduser --system --ingroup video --disabled-password --shell /home/fishcam/server fishcam
Then turn on ssh using the configuration menu:sudo raspi-config
Finally, note down the IP address of your Pi:hostname -I
RSA Key Pair
You will need to run the video streaming client on a device that has ssh installed. We use Mac OS Terminal (which has ssh installed by default) or cygwin on Windows (install the openssh package). The default key size and algorithm is 2048-bit RSA, which will be plenty; we use no passphrase, so we will be able to just click on a script to watch the video stream:
Run this command on the client to create the key pair:ssh-keygen -f ~/.ssh/fishcam -N ""
Then copy the public key to the Pi:scp ~/.ssh/fishcam.pub pi@<IP address you noted earlier>:/tmp
Video Command Setup
We need to move the public key into the right place so ssh uses it for authentication, and create the script to be run when the fishcam user logs in:
Run these commands on the Pi:sudo su -s /bin/bash fishcam umask 077 mkdir ~/.ssh cat /tmp/fishcam.pub >> ~/.ssh/authorized_keys cat > ~/server #!/bin/sh exec raspivid -n -w 640 -h 360 -b 500000 -t 600000 -o -
Then press Ctrl-D to end the file, and run:chmod +x ~/server
Then press Ctrl-D to end the bash command session.
You can now test this out, within your home network, by installing VLC and running the following script on your client device. The path to the VLC binary will be something like /Applications/VLC.app/Contents/MacOS/vlc on MacOS, or /cygdrive/c/Program Files/VideoLAN/VLC/vlc.exe on cygwin:
RPI="<IP address you noted earlier>" VLC="<path to the VLC binary>" ssh -i ~/.ssh/fishcam fishcam@"$RPI" dummy | "$VLC" fd/h264://0
Enabling Access from Outside Your Home
Typical home networks, using ADSL or cable broadband connections, have a router which controls the network traffic between all the devices in your home and the outside world. When your device connects to the router, it is given an IP address which is not visible from the outside (usually on the 192.168.xxx.xxx private network). When you connect to outside addresses, such as Google, the router uses Network Address Translation to map from the public IP address of the router to the private IP address of your device. This deals with sessions initiated from the inside out, but not any from the outside in; for that we need to use port forwarding. A further complication is that the public IP address of your router may change each time your broadband starts up; to get around that we need to use Dynamic DNS (DDNS).
The details of configuring the port forwarding depend on your particular router. You need to set up two things; Firstly, an address reservation so when your Pi boots up, the router always gives it the same private IP address, and secondly, the port number to be mapped (which is 22 for ssh). You should be able to find these settings in your router’s admin menus; for NETGEAR routers, address reservations are entered under Advanced / Lan Setup and the port number is entered under Security / Port Forwarding.
To use DDNS, you need to set up an account with a DDNS provider, and install a DDNS client on your Pi. We went with No-IP, as they offer a free service for personal use. You choose a user name, a password, and a domain name to use under one of the top level domains they manage (for example, myfishcam.no-ip.org).
Install the open source ddclient on the Pi:sudo apt-get install ddclient
The installation script prompts you for various settings, but doesn’t include everything needed to work with No-IP over a secure session; after installation you will need to change a few configuration settings:
Edit /etc/ddclient.conf (bold shows the changes):daemon=600 use=web, web=ip1.dynupdate.no-ip.com protocol=dyndns2 ssl=yes server=dynupdate.no-ip.com login=<your user name> password='<your password>' <your full domain name>
The DDNS client will automatically start each time you boot your Pi, and will periodically update the No-IP server with the current public IP address of your router.
You should now be able to connect to your camera from anywhere in the world, in the same way as our test run above, except using the full domain name instead of the private IP address:
RPI="<your full domain name>" VLC="<path to the VLC binary>" ssh -i ~/.ssh/fishcam fishcam@"$RPI" dummy | "$VLC" fd/h264://0
To access it from other devices than the one you created the RSA key pair on, you can simply copy the private key file (~/.ssh/fishcam) to the other device; do make sure it’s not publicly readable though, as ssh would then refuse to use it.
To fix read permissions on the private key:chmod 600 ~/.ssh/fishcam
Extra Security Measures
Because we are using ssh port forwarding, that also enables logins to your Pi’s admin account from the outside world, using the admin user name and password. That’s handy if you want to tinker with things remotely, like changing the video bit rate to suit the bandwidth of your broadband upload speed, but it could be considered an unnecessary security risk (you did change the default password before starting on this, like we said above, didn’t you?)
For maximum security, you can configure your Pi to limit ssh connections from the outside world to just the fishcam account, but still allow you to use ssh for admin within your home network. If you’ve changed the admin account name, or you use a different private network IP address range, this will need to be modified appropriately:
Add the following line to the end of the file /etc/ssh/sshd_config on your Pi:AllowUsers fishcam email@example.com.*.*
I’m reasonably confident that it will take more effort to break this security than anyone could feasibly want to put in to it. I am tempted to publish the domain name and challenge people to hack into it (it would be great to learn if more security improvements could be made) but I’m not going to; that’s not because I don’t trust the security of the Pi, it’s because I don’t trust the security of the other devices connected to our home network, that aren’t open source, and that we didn’t configure ourselves! If anyone can spot any flaws in the above configurations do please let us know and we’ll update the article and credit you profusely 🙂