Secure access to home IP cameras over the web with SSL

Linux
Networking
Author

Vinh Nguyen

Published

March 18, 2016

IP cameras are cheap these days. I have a few Foscam FI8910W cameras at home as part of my home security system. A friend recently gave me a Foscam C1 to be used as a baby monitor. I try to avoid using the manufacturer's mobile device apps for viewing the video feeds because 1) I don't want my private information (video, IP address, credentials, etc) exchanged or leaked to the manufacturer and 2) I don't want to have to use multiple apps if I buy multiple cameras from different manufacturers. I currently use tinyCam Monitor PRO on my Android device to view the video feed both on the home network and while I'm away. It works very well, is customizable, and supports many different manufacturers.

I took precautions when setting up the cameras on my home network since I know these cameras could be easily hacked with a default setup:

Regarding the use of SSL, newer cameras like the Foscam C1 should support it by default, so making it world-accessible is as easy as setting up a port forward on the router to the IP camera port 443 (or whatever the https port is). However, for older cameras like the Foscam FI8901W that don't support SSL, one could set up an encrypted reverse proxy using a web server like nginx. Luckily, nginx is available on my router running Tomato Firmware so I don't have to use a separate Linux server. Here's how I set this up on my router running Tomato:

    server {
       listen 1234; # doesn't have to be port 443 - could be any port (say 8080) if you 
                   # connect via https://192.168.0.101:8080 .  But on port 443
                   # you can just use https://192.168.0.101
       ssl on;
       ssl_certificate  /tmp/etc/cert.pem;
       ssl_certificate_key  /tmp/etc/key.pem;
       # certificate and private key where you just placed them

       ssl_session_timeout  5m;    
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
       ssl_prefer_server_ciphers on;
       ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
       # reasonable SSL configuration, disable some known weak ciphers.

       location / {
         proxy_pass http://192.168.1.100:88;
         proxy_redirect http://192.168.1.100:88/ $scheme://$host:$server_port/;
     # If your webcam (or other proxied application) ever gives URLs in the HTTP headers
     # (e.g., in a 302 or 304 HTTP redirect),
     # the proxy_redirect line changes the URL in the HTTP header field
     # from http://192.168.0.123:456/some/path to https://192.168.0.1:8080/some/path
       }
    }
iptables -t filter -A INPUT -p tcp --dport 1234 -j ACCEPT