Franklin Heath Ltd

Master Your Information Assets

  • Categories

  • Meta

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/ 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/ >> ~/.ssh/authorized_keys
cat > ~/server
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/ 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 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,

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):

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 pi@192.168.*.*


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 🙂

Tux keeping an eye on the fish

Tux keeping an eye on the fish

6 Responses to “Raspberry Pi Fishcam – The Secure Version”

  1. JBeale said

    Is there some way to allow ssh in from the outside, but also hide the fact that you have any open ports from automated scanners looking for targets?

    • Craig H said

      It’s a good question, and I did think about it, but I think the simple answer is no, not with the standard ssh daemon and Linux network stack. If it listens on a TCP port, as it has to, then a port scan will be able to detect the low level TCP handshaking happening on that port before the daemon has the chance to apply any access control. You might consider using a different port number than 22, so it’s less obvious that it’s an ssh port, but most hackers would try telnet on that port and immediately discover it was ssh anyway (RFC4253 requires the daemon to respond with a human-readable identification string starting with “SSH-“).

      If you were really worried about this, one approach might be to have some sort of polling mechanism so that sshd was only started when you needed it. The question would be what to use to initiate the start up; maybe have a file on a web file-sharing service and get the Pi to check the contents periodically, or something like that?

  2. Gordon J said

    In the past I’ve used a technique which worked well. I set up a user on the server that, when you login via ssh runs a script, that copies in an authorized_keys file for a different user, kicks you out, waits 1 minutes and deletes the keys. This gives you a one minute window to login as the other user. And to access you have to have keys in place for the initial user.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: