How to Make a £59 Fully Featured Raspberry Pi Home Security Camera – Newbie Guide

This tutorial will explain how to create your own CCTV IP Webcam using a Raspberry Pi Zero Wireless £9 computer!

It uses the excellent RPi Web Cam Interface open source software, which offers a near real-time live video stream via a web interface for the Raspberry Pi camera module, as well as motion detection video recording.

It can be used for a wide variety of applications including surveillance, dvr recording and time lapse photography. It is highly configurable and can be extended with the use of macro scripts. It can be opened on any browser (smartphones included) and contains the following features:

  • View, stop and restart a live-preview with low latency and high framerate. Full sensor area available.
  • Control camera settings like brightness, contrast, … live
  • Record full-hd videos and save them on the sd-card packed into mp4 container while the live-preview continues
  • Do timed or continuous video recording with splitting into fixed length segments
  • Take single or multiple (timelapse) full-res pictures and save them on the sd-card (live-preview holds on for a short moment)
  • Preview, download and delete the saved videos and pictures, zip-download for multiple files
  • Trigger captures by motion detection using internal or external detection processes.
  • Trigger captures by many scheduling-possibilities
  • Circular buffer to capture actions leading up to motion detection
  • Control Pan-Tilt or Pi-Light
  • Shutdown/Reboot your Pi from the web interface
  • Show annotations (eg timestamp) on live-preview and taken images/videos
  • Supports selection from 2 cameras when used with a compute module

The software is fully functional with a Pi Zero Wireless, offering a small footprint that operates over wifi and only requires a power source.

The example here uses a 160 degree fisheye camera module that gives a much better field of view than the standard official camera (and is fully compatible). If you don’t need a better viewing angle, the official Pi Zero case fully integrates the official camera into a very neat little package!

You can also buy a 160 degree fisheye IR (infrared) camera that comes with IR LED lights which are powered and attached to the camera board. There are also many more camera options at Modmypi, such as a 222 degree fisheye, and an IR on/off camera.

SHOPPING LIST

Total: £59.54

INSTALLING THE SOFTWARE

Write an Image onto the SD Card
We will be using the lite version of Raspberry Pi’s official operating system as the base for our security camera.

  1. Download RASPBIAN JESSIE LITE from
    https://www.raspberrypi.org/downloads/raspbian/

    Screen Shot 2017-07-01 at 17.17.55 v2

  2. Download Etcher which we will use to burn the image to an SD card (this supports Windows, OSX, and Linux, and is really easy to use):
    https://etcher.io

    Screen Shot 2017-07-01 at 17.18.41

  3. Insert your microSDXC card into your computer
  4. Run Etcher and press the Select Image button
    Screen Shot 2017-07-01 at 17.19.42

  5. Find your previously saved 2017-06-21-raspbian-jessie-lite.zip file from step 1 (or whichever version is the latest)
    Screen Shot 2017-07-01 at 17.21.26

  6. Your SD card may already be automatically detected, but if not press the Change link to select the card.
  7. Press the Flash button
    Screen Shot 2017-07-01 at 17.29.06

  8. Once finished, Etcher will automatically unmount the SD card. However, remove and plug the card back in so that we can copy some files to the SD card.
  9. Given that the Pi Zero W has limited ports, performing an initial configuration such as connecting to wifi or enabling SSH would require a keyboard and monitor. This can be avoided by putting two text files in the top-level directory of the SD card, one to enable SSH and the other to set up wifi by including details within the text file.
    1. The inserted SD card should be labelled boot and contain files called bootcode.bin, config.txt, etc.
    2. Create a new text file in the same location as the previously mentioned files called “ssh”. Note that it’s not called ssh.txt, and obviously don’t include the quotes (“”). This text file can be empty as it’s just the file name which enables ssh.
    3. Create another new text file called “wpa_supplicant.conf”. This file does need some information contained within, so open the file with a text editor such as notepad. Paste in the following lines of text and update the ssid and psk lines with your local wifi details.
      ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
      update_config=1
      country=GB
      network={
      	ssid="enter_your_wifi_name_here"
      	psk="enter_your_wifi_password_here"
      	key_mgmt=WPA-PSK
      }
    4. Your SD card should now have the above two mentioned files as seen below. Once you’ve finished, properly eject the SD card from your computer.
      Screen Shot 2017-07-01 at 18.25.25
  10. Put your SD card into the Pi Zero and then assemble the ribbon cable, case, and camera. Don’t power the Pi on just yet though…

    Determine the IP address

  11. When the Pi powers up, it will obtain an IP address automatically from your router. You will want to know what this IP is, but unless you plug in your Pi to a monitor (which is an option via the HDMI port), you need to determine the IP another way. This is where a very useful local network scanning utility called Fing comes in. Fing is an iOS or Android app that will show you all devices on your network and their IP address.
    1. Download Fing from the Appstore (or find more details from their website https://www.fing.io/)
    2. Run Fing and let it scan your network. If you already have any Raspberry Pi devices, make a note of their IP so you can discount them when you turn the Pi on.
    3. Turn on your Raspberry Pi Zero and give it 3 or so mins to boot.
    4. Scan your network using Fing again, and all being well you should hopefully see a new Raspberry Pi entry with it’s IP address! The hostname will be called “raspberrypi”
    5. If a new IP doesn’t appear, double check your wifi settings by inserting the SD card back into your computer and looking at or editing wpa_supplicant.conf. If that method still doesn’t work, plug the Pi into your monitor or TV via the HDMI port (you may need a mini to normal HDMI converter).
  12. If you’re using Windows, you will need a way to SSH to your Pi for remote access to install the software. Download Putty (putty-64bit-0.69-installer.msi) from https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html and install. If you’re using macOS, just open Terminal (press cmd+space and type in Terminal to find it).
    1. For Putty instructions, please follow this guide:
      https://www.raspberrypi.org/documentation/remote-access/ssh/windows.md
    2. For macOS, at the terminal simply type (replacing 192.168.0.2 with your Pi’s IP address).
      ssh pi@192.168.0.2
    3. The default password is raspberry
  13. You should now be at your Pi’s command prompt:
    pi@raspberrypi:~ $

    Update the Pi and Enable the Camera

  14. Let’s update the software by running the following lines one at a time:
    sudo apt-get update
    sudo apt-get upgrade
  15. Let’s change the password:
    passwd
  16. It’s a good idea to give the Pi a static IP address. This excellent tutorial covers how to do this:
    http://raspberrypituts.com/raspberry-pi-static-ip-address-simple-tutorial/
  17. We now need to enable the camera and set the timezone. This can be done by running:
    sudo raspi-config
    1. Select Interfacing Options from the menu
      Screen Shot 2017-07-02 at 17.42.49

    2. Select Camera and then Yes and then Ok
    3. Back at the main menu, select Localisation Options and then Change Timezone
    4. As an example for the UK, select the following:
      Europe -> London
  18. Now close the window by selecting Finish, and press Yes to reboot
  19. SSH back into the Pi using Putty or terminal.

    Install RPi Web Cam Interface

  20. If you aren’t there already, cd into your home directory
    cd ~
  21. Install git (because this isn’t included with Jessie Lite by default)
    sudo apt-get install git vim
  22. Run the following (either a line at a time or all at once is ok)
    git clone https://github.com/silvanmelchior/RPi_Cam_Web_Interface.git
    cd RPi_Cam_Web_Interface
    chmod u+x *.sh
    ./install.sh
  23. You should now be presented with the Configuration Options screen. To navigate this page, pressing tab will jump between the options window and the Ok/Cancel buttons. When in the options window, use the arrow keys to move up and down.
    Screen Shot 2017-07-02 at 18.36.53
    Cam subfolder – best leave this at the default html. You would only need to change this if you were hosting multiple sites on the same Pi
    Autostart – Leave it at Yes so that the software starts automatically after a reboot
    Server – Leave this at Apache. There are other options, but for ease of use Apache is the best choice.
    Webport – If you are thinking of accessing the camera from outside your home, it is best this port is changed to something between 1024 and 65535. Make a note of the number if it’s something other than 80.
    User – Set a username. You could leave this empty if you’re only ever going to access the camera from within your network, but it’s advised to set a user and pass for extra security.
    Password – Set a password
    jpglink – Leave this set to no, it’s for backwards compatibility

  24. Press Ok when you have set your desired options
  25. Press Yes to Start Now.

    Accessing the Web Interface

  26. All being well, you should now be able to enter your Pi’s IP address into a web browser. e.g
    http://192.168.1.5/html/

    If you used a different port, enter this as follows:

    http://192.168.1.5:2244/html/
  27. Hopefully you can now see a live stream from your camera
    Screen Shot 2017-07-02 at 19.01.25

  28. Let’s change a few key options at this point. Notice how the camera is upside down? This can be rotated in 90 degree intervals from the “Rotation, default 0:” option within Camera Settings. In this case we will choose Rotate_180:
    Screen Shot 2017-07-02 at 19.04.01

  29. The default resolution is 1080p, but you loose a lot of the sensor with this, so within Camera Settings -> Resolution, from the Load Preset drop-down menu, choose Max View 972p 4:3
    Screen Shot 2017-07-02 at 19.07.04

  30. If the annotation text along the top of the video feed (showing date/time) blends too much into a white background, change Camera Settings -> Annotation -> Background (drop-down menu) to On.
    Screen Shot 2017-07-02 at 19.12.23

    Enabling Motion Detection

  31. Change Motion Detect Mode (within Camera Settings) to Internal
    Screen Shot 2017-07-03 at 16.54.51

  32. Adjust the parameters such as Noise Level, Threshold, etc within motion Settings. Full details on what these do can be found here:
    http://elinux.org/RPi-Cam-Web-Interface#Motion_Detection

That is it! Feel free to explore the Wiki http://elinux.org/RPi-Cam-Web-Interface, and if you have any questions there’s an active support forum here: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=63276

Advanced Guides

If you would like to see what else is possible with these cameras, please have a look at some of my other guides:

Telegram – Send Messages, Photos, Animated Gifs from your Raspberry Pi and RPi Web Cam

This tutorial has been created to work with RPi Web Cam Interface (for more details see: https://elinux.org/RPi-Cam-Web-Interface)

Telegram (an IM platform similar to WhatsApp) has the ability to send messages and pictures from your RPi Web Cam to your phone or desktop whenever motion is detected for instant notification. Plus it’s FREE! 🙂
 
To find out more visit: https://telegram.org
 
We will be using a Telegram Bot which is specifically designed to work with software, meaning that a message can be sent using bash scripts: https://telegram.org/blog/bot-revolution
 
Start by installing the Telegram app on your phone or desktop (this process will create your account – https://telegram.org), and then sign up for a Telegram bot using Botfather with the instructions here: https://core.telegram.org/bots#6-botfather.
 
Make a note of your API Token and bot username (the one that must end in bot)
 
We now need to obtain your bot’s chatid. To do this, enter the bot username in the Telegram search field (either in Contacts or Chats), then select the bot to initiate a chat with it, and then send a message. This process will establish a conversation (or chat) between you and the bot, identified as a chatid.
 
To find the chatid, enter the following URL in a browser (your API token goes after and right next to /bot):

https://api.telegram.org/botReplaceThisWithTheBotFatherToken/getUpdates

 
e.g, if your API is “123456789:jekcjrnekjrhteuncheiucnf”:

https://api.telegram.org/bot123456789:jekcjrnekjrhteuncheiucnf/getUpdates

 
You need the “id” number from the output it produces:

"message":{"message_id":2872,"from":{"id":987654321,

 
In the example above, this would be “987654321”
 
If you only see {“ok”:true,”result”:[]}, it means you haven’t yet sent your bot a message from your account.
 
Ok, so now that you have your API token and chatid, we can use the Pi to send you a message. Let’s send a test message to start with by entering the following from the Pi command line (substituting with your API and chatid where relevant):

curl -s -X POST https://api.telegram.org/bot123456789:jekcjrnekjrhteuncheiucnf/sendMessage -d text="A message from your bot" -d chat_id=987654321

 
Now we need to wrap this up in a script to send you notifications when motion is detected.

Create a new config file to store variables for Telegram

sudo nano /var/www/html/macros/configfile.cfg

Enter the following text into that file, replacing where necessary

#!/bin/bash
 
#Replace text within and including the arrow brackets <> with your own details
 
#Camera details
cameraName="<Mycam>"  
 
#Telegram details
tokenurl="https://api.telegram.org/bot<your API key>"
chatid="<your chat id>"
 
#Folder paths
webfolder="/var/www/html"
nomsg="/home/pi/nomsgfile.lck"
logfile="${webfolder}/scheduleLog.txt"
curlout="${webfolder}/curlout.txt"  #Keeps a log of the curl output for troubleshooting
 
 
#Logging function
logging () {
  #logging yes true "This is my error message"
  #$1 yes/no - send telegram msg
  #$2 true/false - disable audible notification or pop-up msg on receiving device
 
  ext="$1"
  notification="$2"
  msg="$3"
 
  NOW="`date +"-%Y/%m/%d %H:%M:%S-"`"
  echo "$msg"
  echo "${NOW} ${msg}" >> $logfile
  if [ $ext == "yes" ]; then
    curl -s \
      -X POST \
      ${tokenurl}/sendMessage \
      -d text="$msg" \
      -d disable_notification=${notification} \
      -d chat_id=${chatid} >> ${curlout} &
  fi
}

Create a new macro file that will be run whenever motion is detected

sudo nano /var/www/html/macros/motion_event.sh

Copy in the following text

#!/bin/bash
. /var/www/html/macros/configfile.cfg
 
#If you wish to disable notifications, create a file using "touch /home/pi/nomsgfile.lck"
if [ -f $nomsg ]; then
  logging no true "Message alerting has been disabled, exiting..."
exit
fi
 
#Copy the low res snapshot image from memory to a file
cp /dev/shm/mjpeg/cam.jpg ${webfolder}/cam_new.jpg
 
#On motion detection start (parameter is 1 for on, 0 for off)
fileparams=$1
if [ $fileparams -eq 1 ]
then
  #Send both a single text message and a photo because sometimes the photo message times out if the Telegram servers are busy
  
  logging yes false "Motion detected from ${cameraName}"
 
  curl -s -X POST \
    ${tokenurl}/sendPhoto \
    -F chat_id=${chatid} \
    -F photo="@${webfolder}/cam_new.jpg" \
    -F caption="Motion detected on ${cameraName}" >> ${curlout} &
 
fi

We now just need to make the motion_event.sh file executable and change the ownership:

sudo chmod +x /var/www/html/macros/motion_event.sh
sudo chown www-data:www-data /var/www/html/macros/motion_event.sh
sudo chown www-data:www-data /var/www/html/macros/configfile.cfg

To trigger motion detection within RPi Web Cam you need to ensure that Motion detect mode is set to Internal (or Monitor). For more details on how to configure this please see: https://elinux.org/RPi-Cam-Web-Interface#Motion_Detection

Access Raspberry Pi Filesystem from Mac OSX using Netatalk AFP

This tutorial will explain how to browse your RPi Web Cam media folder from within Finder on MacOS.

    On your Raspberry Pi:

  1. Update packages and install netatalk
  2. sudo apt-get update
    sudo apt-get install netatalk
  3. Create a password for the www-data account
    sudo passwd www-data

    On your Mac:

  4. Open terminal and type the following
  5. open afp://<your-raspberrypi-ip>
  6. When the window pops up and asks for your username and password for the Raspberry Pi, enter www-data as the username, and the password you set above.
  7. You will now be able to browse the html folder and open video files from within media on your Mac.
  8. If the video file is opened in Preview, use the J K and L keys for the following:
    J = Press to reverse video. Press more than once to increase the speed.
    K = Play the video forward at normal speed.
    L = Fast forward the video. Press more than once to increase the speed.

 

Pushover Alerts for Motion Detection with RPi Web Cam Interface

UPDATE – Pushover has its limitations such as not being able to send photos and having to pay for the service. A better, free!, alternative is Telegram. For instructions, please see my tutorial here: https://quavoce.wordpress.com/2017/09/29/telegram-send-messages-photos-animated-gifs-from-your-raspberry-pi-and-rpi-web-cam/

This post describes how to use an online push notification service called Pushover to send you notifications on your mobile devices whenever an event occurs. In this example, we are using it with the excellent RPi Web Cam Interface (http://elinux.org/RPi-Cam-Web-Interface) to send you a message whenever motion is detected.

If you would like to create a secure HTTPS remote access to your cameras, be sure to check out my other post here:

  1. Signing and Setting up Pushover
    1. Sign up for an account here: https://pushover.net/login
    2. Make a note of your “user key” (copy it into a text editor for example)
    3. Select the Apps & Plugins link
    4. Click Create a new Application
    5. Give your app a name, and choose Script within the Type drop-down menu
    6. Tick the checkbox and press Create Application
    7. Make a note of your API/Token key.
  2. Install the Smartphone App or launch the desktop client
    1. Links to the apps are on the Pushover website under the Android, iOS, & Desktop link
  3. Create a script on the Pi
    1. At the command prompt, cd to the macros folder (substitute html for the folder you specified during setup)
    2. cd /var/www/html/macros/
    3. Create a start_vid.sh file using your favourite text editor (nano or vim for example – the latter of which needs to be installed using “sudo apt-get install vim” – nano is easier if you don’t know vim)
    4. sudo vim start_vid.sh
    5. Paste the following bash script into the file:
    6. time=`date +"%d-%m-%Y %T"`
      url="https://<MyDynamicURLorIP>/mycamera" #no trailing slash after html
      cameraName="myCam"
      
      filename=${1##*/}
      thumb=`echo $filename | awk -F "_" '{ print $2 }'`
      thumbname="v${thumb}.th.jpg"
      sendurl="${url}/media/${filename}.${thumbname}"
      streamurl="${url}/media/${filename}"
      livestream="${url}/min.php"
      
      curl -s \
        -F "token=yourAPITokenKey" \
        -F "user=yourUserKey" \
        -F "device=DeviceNames" \
        -F "message=Motion detected at $time. Live video Link: ${livestream} - Recorded video link (need to wait until recording has completed): ${streamurl}" \
        -F "title=Motion Detected from $cameraName" \
        -F "url=$sendurl" \
        -F "url_title=Click to open a still image showing detected motion" \
        https://api.pushover.net/1/messages.json > /dev/null 2>&1
    7. Save the file and the change the permissions so it can be executed
    8. sudo chmod +x start_vid.sh
      sudo chown www-data:www-data start_vid.sh
    9. Test it works
    10. sudo ./start_vid.sh /var/www/html/media/vi_0003_20160818_092213.mp4
    11. This should send a push message to your phone with a link to thumbnail for the above file (which obviously won’t work for you unless you already have a video with the exact date and time as above) 🙂

Full Reverse Proxy Instructions with Dynamic IP and HTTPS Encryption

June 2018 – Unfortunately these instructions no longer work on the latest version of Raspbian. I have found an updated set of instructions at the link below, so rather than reinventing the wheel, please follow these instructions instead:

Building a reverse proxy server with Nginx, Certbot, Raspbian Stretch Lite and Raspberry Pi 3

The Goal

  • Secure reverse proxy running on a Raspberry Pi at home (using the latest NGINX web-server), so that you don’t have to open multiple ports to the internet on your router.
  • Dynamic DNS URL for various web applications at home, e.g RPi Web Cam Interface – http://elinux.org/RPi-Cam-Web-Interface
  • Official HTTPS certification from letsencrypt.org for free
    • So that you don’t have to login with your password being sent in the clear!
    • Required because self-signed certs don’t work when trying to view recorded RPi Cam video on an iPhone/iPad
  • Push notifications sent to your phone when events occur such as motion detection
  • One Raspberry Pi for the proxy and separate Pis for multiple RPi Web Cam Interface cameras

To summarise how this will work once built, you will have a single external access point into your home network via the secure HTTPS port 443 using something like https://mydomain.com/mycamera/.

This method is called a Reverse Proxy and runs on a Raspberry Pi using the NGINX (Engine X) web server. This web server software is used on many official websites on the internet, and is therefore a secure barrier between the internet and your home network.

A file on the proxy Pi called /etc/nginx/services.conf is used to redirect custom URL sub-paths (such as “mycamera” in the example above) to another internal web server on whatever port you need, such as a Pi running the video surveillance dvr software RPi Web Cam Interface – http://elinux.org/RPi-Cam-Web-Interface

Pre-requisites

You will need to know how to do the following:

  • Write a Jessie image to an SD card
  • Configure a static IP (a link is included below)
  • Edit text files from the command line
  • Using an SSH client from your computer such as Putty to connect to the Pi
  • Know how to configure your router for port forwarding

Set up the Pi and Install NGINX:

  1. Create a new Jessie image on an SD card (use whichever method is required for your computer).
  2. Once booted into the GUI, goto Preferences -> Raspberry Pi Configuration
    1. Change Boot to CLI
    2. Untick Auto Login
    3. Give it a new Hostname (eg proxypi)
    4. Set your timezone
    5. Enable SSH
    6. Press OK and reboot
  3. Log into the Pi using default user/pass (pi/raspberry)
  4. Determine assigned IP by running “hostname -I”. (The proxypi really should be connected via ethernet rather than wifi, and DHCP should have assigned you an IP)
  5. SSH to the Pi using this IP address from your computer (use Putty on Windows)
  6. Change the default password
  7. passwd
  8. Set a static IP on the Pi using these instructions: https://www.modmypi.com/blog/how-to-give-your-raspberry-pi-a-static-ip-address-update
  9. Reboot and log back in using the Static IP
  10. Update the Pi
  11. sudo apt-get update
    sudo apt-get upgrade
    reboot
  12. Install the latest NGINX. Edit the sources.list and add the stretch branch of raspbian
    1. Edit the sources.list file
    2. sudo nano /etc/apt/sources.list
    3. Add the following to the last line:
    4. deb http://mirrordirector.raspbian.org/raspbian/ stretch main contrib non-free rpi
  13. Prevent all packages using stretch unless specified:
    1. Create a new file:
      sudo nano /etc/apt/preferences
    2. Add the following lines:
    3. Package: *
      Pin: release n=jessie
      Pin-Priority: 600
  14. Update:
    sudo apt-get update
  15. Install NGINX:
    sudo apt-get install -t stretch nginx

Set up a Dynamic DNS Hostname

I’m using and paying for Dyn’s Dynamic DNS server due to it’s reliability: http://dyn.com/remote-access/
There are plenty of free options out there though so follow their instructions to set up a hostname and updater client if you prefer.
The instructions below explain how to install a client on the proxypi for automatic IP updates to Dyn. This assumes you’ve already created your dynamic hostname within “My Services -> DynDNS Pro”. (ddclient):

  1. Install ddclient
    sudo apt-get install ddclient
  2. Answer the questions when prompted
    – Other DNS Provider
    – Dynamic DNS Server: members.dyndns.org
    – Protocol: dyndns2
    – Username/password
    – Network: web
    – URL name.
  3. Generate your conf file from the following link: https://account.dyn.com/tools/clientconfig.html
    1. Within the webpage, select your host and client (ddclient)
    2. Compare the generated conf file with what was configured during setup (/etc/ddclient.conf) and update accordingly
      daemon=600
      protocol=dyndns2
      use=web, web=checkip.dyndns.com, web-skip='IP Address'
      server=members.dyndns.org
      login=your_username
      password='your_password'
      your_hostname
    3. Test by running
      sudo ddclient -daemon=0 -verbose

 

Configuring HTTPS with https://letsencrypt.org/

  1. You should already have a webpage that you can browse to on your local network:
  2. http:///

    This should give you the welcome nginx welcome page.

  3. Configure your router to forward port 80 and 443 to your proxy raspberry Pi IP
  4. Add the Jessie backports to your sources.list by editing
  5. sudo nano /etc/apt/sources.list
  6. Then add the following line
  7. deb ftp://ftp.uk.debian.org/debian jessie-backports main
  8. Update:
    sudo apt-get update

    (ignore any GPG errors)

  9. Install Certbot
    sudo apt-get install certbot -t jessie-backports
  10. Run certbot
    sudo certbot certonly --webroot -w /var/www/html -d your_domainname

    It will ask you for your email address as part of the setup.

  11. You should see a Congratulations! message
  12. Now follow the next section “Configuring NGINX

 

Configuring NGINX Proxy:

  1. Create a new nginx configuration for reverse proxy by editing the following file:
    sudo nano /etc/nginx/sites-available/main
  2. Copy the text below into the “main”text file and edit the entries as required.
  3. access_log off;
    add_header Cache-Control public;
    server_tokens off;
    # HTTP 80
    server {
    	listen 80;
    	server_name _;
    	return 301 https://$request_uri?;
    }
    # HTTPS 443
    server  {
    	listen 443 ssl;
    	keepalive_timeout 70;
    	server_name ;
    	include /etc/nginx/ssl.conf;
    	include /etc/nginx/services.conf;
    }
  4. Create an ssl.conf file
  5. sudo nano /etc/nginx/ssl.conf
  6. Copy the following text into it
  7. ssl on;
    ssl_certificate /etc/letsencrypt/live//fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live//privkey.pem;
    
    ssl_session_cache shared:SSL:20m;
    ssl_session_timeout 180m;
    
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
    
    ssl_dhparam /etc/nginx/cert/dhparam.pem;
  8. Create the services.conf file.
  9. sudo nano /etc/nginx/services.conf
  10. Add as many entries as you need.
  11. location /picam {
    proxy_pass http://internal-rpi-cam-ip2/html;
    include /etc/nginx/proxy.conf;
    }
    location /picam2 {
    proxy_pass http://internal-rpi-cam-ip2/html;
    include /etc/nginx/proxy.conf;
    }
    location /couchpotato {
    proxy_pass http://internal-cp-ip:4001/couchpotato;
    include /etc/nginx/proxy.conf;
    }
    location /sonarr {
    proxy_pass http://internal-sonarr-ip:8989/sonarr;
    include /etc/nginx/proxy.conf;
    }
  12. Create a proxy.conf file:
  13. sudo nano /etc/nginx/proxy.conf
  14. Copy the following text into this file
  15. proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 10m;
    client_body_buffer_size 128k;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
    proxy_buffers 32 4k;
  16. Create a symbolic link to the main site
  17. sudo ln -s /etc/nginx/sites-available/main /etc/nginx/sites-enabled/main
  18. (Optional) Strengthen HTTPS key exchange by running the commands below (it takes around 5 mins to generate on a RPi 3 – go make dinner if on a Pi1 – Original Instructions found here: https://bjornjohansen.no/optimizing-https-nginx)
  19. sudo mkdir /etc/nginx/cert
    sudo openssl dhparam 2048 -out /etc/nginx/cert/dhparam.pem
  20. Test the config:
  21. sudo nginx -t
    nginx: [warn] conflicting server name "_" on 0.0.0.0:80, ignored
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  22. Redirect Port 443 on your router to the proxypi
  23. Restart the nginx service
  24. sudo service nginx restart
  25. Test your site security from here: https://www.ssllabs.com/ssltest/index.html
    You should get an A rating! (if step 6 was also followed)
  26. Test that certificate renewal will work
  27. sudo certbot renew --dry-run
  28. Set up a cronjob to automate cert renewal. Start by opening the crontab file
  29. sudo crontab -e
  30. Enter the following line at the bottom of the file
  31. * 1 * * 1 sudo /usr/bin/certbot renew

That’s it!!

If you have installed RPi Cam on another Pi and the internal URL/IP matches what you configured in /etc/nginx/services.conf, then you should be able to browse using this URL:

https://your-domainname/picam/

PLEASE NOTE – You must end the URL with a trailing forward slash “/”, otherwise the redirect won’t work properly

I built a new proxy pi as I wrote these instructions, so it should all work… I’ll be happy to answer any questions you have though.

Optional Extras for RPi Cam

Please see my other blog posts to add extra features to your setup:

RPi Cam Web Interface: Turn on and off motion detection usng IFTTT Do Buttons

EDIT – Updated March 2018 to include a more secure raspi_runner.sh script and updated IFTTT instructions.

Would you like the ability to turn on and off motion detection on your Rpi Cam Web Interface from your phone with just the press of an IFTTT Applet button (rather than logging into the camera’s website)?

An extra bonus on the iPhone is the ability to add a button to the home screen widget, so it’s really easy to control your camera. Plus it’s not limited to motion detection – anything the pipe commands can do (http://elinux.org/RPi-Cam-Web-Interface#Pipe), the Applet button can do too!

  1. Install Dropbox-Uploader
  2. cd ~
    git clone https://github.com/andreafabrizi/Dropbox-Uploader.git
    cd Dropbox-Uploader/
    chmod +x dropbox_uploader.sh
    ./dropbox_uploader.sh
    
  3. Follow the Dropbox-Uploader instructions:
  4. - Open the following URL in your Browser, and log in using your account: <a class="postlink" href="https://www.dropbox.com/developers/apps">https://www.dropbox.com/developers/apps</a>
    
    - Click on "Create App", then select "Dropbox API app"
    - Now go on with the configuration, choosing the app permissions and access restrictions to your DropBox folder
    - Enter the "App Name" that you prefer (e.g. MyPiUploader)
    
    - Now, click on the "Create App" button.
    
    - When your new App is successfully created, please click on the Generate button
    under the 'Generated access token' section, then copy and paste the new access token here:
    
    # Access token:
    
    
  5. Install Raspi-Runner
  6. 
    cd ~
    git clone https://github.com/enkydu/Raspi_Runner
    cd Raspi_Runner/
    chmod +x raspi_runner.sh
    ./raspi_runner.sh
    What is name of Dropbox folder, for Raspi Runner commands? (i.e. Raspi_Commands): scripts
    what is the full path to your Dropbox Uploader? (i.e. /home/pi/Dropbox_Uploader): /home/pi/Dropbox-Uploader
    
    

    Note – ensure the path has Dropbox-Uploader instead of the default Dropbox_Uploader

  7. We now need to modify raspi_runner.sh to be more secure. As things stand, any command posted into dropbox can be executed on the Pi which isn’t good, so the solution is to have pre-defined commands instead.
    Edit /home/pi/Raspi_Runner/raspi_runner.sh and replace text with the following code:
  8. #!/bin/bash
    
    # Check location of Raspi Runner
    script_path="$(readlink -f ${BASH_SOURCE[0]})"
    rr_home="$(dirname $script_path)"
    
    cd $rr_home
    
    rr_dboxstorage=scripts
    rr_storage=/home/pi/Raspi_Runner/scripts
    rr_dbuploader=/home/pi/Dropbox-Uploader
    
    # Download new scripts delivered by mail from Dropbox to Raspberry Pi folder /home/pi/Raspi_Runner/Raspi_Commands
    $rr_dbuploader/dropbox_uploader.sh -q download /$rr_dboxstorage
    
    # Check for new files on Raspberry Pi
    check=`ls $rr_storage | wc -l`
    
    if [[ $check -eq 0 ]];
            then exit 0
    fi
    
    files=`ls $rr_storage`
    OIFS="$IFS"
    IFS=$'\n'
    
    # Run all delivered scripts
    currTime=`date +"%d-%m-%Y %T"`
    for i in $files
    do
      command=`cat ${rr_storage}/$i`
      echo -e "$currTime - $command" >> $rr_home/cmdlog.txt
      case "$command" in
        motionon)
          echo 'md 1' > /var/www/html/FIFO
          ;;
        motionoff)
          echo 'md 0' > /var/www/html/FIFO
          ;;
      esac
    
    done
    
    # Remove all scripts, which were already executed from Dropbox
    for i in $files
    do
            $rr_dbuploader/dropbox_uploader.sh -q remove /$rr_dboxstorage/$i
    done
    
    # Remove all scripts, which were already executed from Raspberry Pi
    rm $rr_storage/*
    
  9. Test the new code by creating a text file in the scripts folder within your dropbox storage area (via the web or your computer if Dropbox is installed) with the following text inside that file (any filename will be ok):
  10. motionon
  11. Run the raspi_runner.sh command as shown below. The script will connect to Dropbox, download any files within the scripts folder, read the contents of that text file, and if there is a match (e.g. ‘motionon’) it will run the associated command defined within our script (in this case, turn on motion detection)
  12. /home/pi/Raspi_Runner/raspi_runner.sh
  13. Now set a schedule in cron so that raspi_runner executes every 2 minutes:
  14. crontab -e
  15. Paste the following line and save
  16. */2 * * * * /home/pi/Raspi_Runner/raspi_runner.sh > /dev/null 2>&1
  17. Create an IFTTT Applet (assumes you’ve created an IFTTT account and linked DropBox to it)
    1. Browse to the IFTTT website https://ifttt.com/discover
    2. Go to the My Applets page (link top of the site)
    3. Press the New Applet button
    4. Press the blue coloured +this within the large ‘If This Then That’ text
    5. Search for Button Widget and press the big red box
    6. Select the Button Press red box
    7. Now select +that
    8. Search for and select Dropbox
    9. Choose Create a text file
    10. Complete the action fields as follows
      1. File Name, e.g.
      2. anyfilename
      3. Content, e.g.
      4. motionon
      5. Dropbox folder path, e.g.
      6. scripts
    11. Click Create Action
    12. Give this action a name such as Turn on Motion
    13. Click Finish

    What’s nice about this method is that you can turn off motion detection in the middle of a recording, whereas the website button to turn motion off is greyed out until no more motion is detected.

    You can now use the iPhone app (and probably Android as well) to create a Widget for easy access to initiate the Applet.

    Advanced Extras
    If you have followed my guide “Full Reverse Proxy Instructions with Dynamic IP and HTTPS Encryption“, you could install Raspi Runner on the proxy pi and then issue commands to other cameras or Linux devices on your network using ssh.
    For example, after configuring SSH Public Key Authentication on your proxy, you can use the following command in raspi-runner.sh instead:

          cameraon)
          echo "md 1" | ssh picam 'cat > /var/www/html/FIFO'
          ;;