Tuesday, October 29, 2013

Your Barn Door is Off Its Hinges

I was a bit hasty when I said the next step in building the garage door security camera was constructing a web interface. As any good DevOps guy should know, getting the administrative portions of the host in stable shape is really the next step. I needed to deal with disk space issues, data retention, security and properly setting timezones.

The majority of my tweakings are being recorded within GitHub's GarageSecurity admin folder until I refactor that away. This folder includes config files and modifications that reflect the steps that I took to lock things down, including:
  1. Set the timezone to be local instead of UTC
  2. Build and enforce firewall rules
  3. Ensure that Motion's HTTP Configuration endpoints are disabled
  4. Hide the webcam's MJPEG stream behind an Apache2 proxy
  5. Allow Samba/Apache2 to list the recordings on the LAN
  6. Use an NFS mount instead of local storage for recordings (instead of using a 64 GB compact flash card, use a 2 TB NAS drive
  7. Create a crontab entry to compress & archive yesterday's recordings
  8. Allow userlevel (not root) access to Raspberry Pi's GPIO pins

The timezone issue is more a matter of personal taste. I would rather the time on the server reflect local time, since I will be looking at file timestamps quite frequently. Others may fall in love with UTC. Or Swatch Internet time. Whatever floats your boat. I did notice that tzselect does not appear to persist across reboots; instead I had to use dpkg-reconfigure tzdata.

The primary goal was to secure access to the webcam feed and disallow unauthorized access. Since this is an Ubuntu distribution, I used the Uncomplicated Firewall to only permit traffic across HTTP and SSH ports. This would close the default webcam and control ports that could be exposed by Motion, as well as other running services. The control endpoints were not needed for my purposes, and I'd rather not assume the risk of arbitrary file access. I still wanted to have access to the MJPEG feed coming from Motion... however I wanted the ability to lock it down. In order to provide more granular security controls I proxed the 8081 webcam port from Motion behind Apache2's mod_proxy, where I could define whatever controls I liked within the Apache VirtualHost. Likewise I allowed authenticated users to view the list of recordings using Apache's directory index module so that archived images and recordings could be easily accessed.

Once Motion was appropriately locked down, I moved on to dealing with file storage and archival. Instead of writing to the local SD card, I decided to make an NFS4 mount to a NAS server on the LAN. The amount of file I/O could easily be delt with over 802.11n, and the SAN could also assume the duties of archiving/compressing the files on a daily basis. This keeps the number of files on the mount much lower, allows for greater storage and doesn't wear out the SD card nearly as much. One catch was that the mount was occurring over a wireless interface, so an attempt to mount the filesystem too early would cause the boot process to lock up. I worked around this by using the mount options soft,bg,timeo=14,intr to decrease the operation timeout and allow for retries in the background. By the time the boot processes is complete, a retry operation should be able to successfully mount the drive.

The final security point is one that will be of much greater use once the web interface is written. The RPi.GPIO libraries write to /dev/mem, which means they need root access to work. Rather than grant scripts root access to /dev/mem (which is horrible practice), I enlisted the help of Gordon Henderson's WiringPi project. There are two parts to this implementation: one is the GPIO utility that helps create userspace devices for GPIO control, and the other is the Python library that can access these devices. I created an entry in rc.local that creates a device for GPIO17 in output mode that is accessible by www-data, which in turn can be accessed within a Python script running as the www-data user.

The security is definitely not exhaustive, but it's a solid start to get things rolling. From here I should be able to deploy a web application that exists as the sole entry point for the garage security system, and access controls can be entirely managed through Apache. A rogue user should hopefully be contained within the scope of the www-data user.

No comments:

Post a Comment