Apache, HTTP, security, Ubuntu

Securing Foscam IP camera access over SSL with Apache reverse proxying

UPDATED: 5/7/14 Important security vulnerabilities for Foscam cameras

UPDATED: 9/27/13  (The solution below does not include audio support; for audio over stunnel please see this post over at warped.org)

Recently I was assisting a local business setup their Foscam IP cameras and make them remotely accessible for monitoring purposes from anywhere in the world. The particular models they had installed are the FI8910W line. These camera’s are pretty cool and for ~$100 retail they are a pretty good deal in my opinion. The cameras can be accessed via a browser over HTTP and also support a rudimentary HTTP/CGI API. However one of the biggest issues with these cameras security wise is the lack of SSL support. The embedded webserver on these things only supports HTTP and basic auth in the clear which, outside of your local network is not a good thing if your requirements is to be able to view/manage them remotely from over the internet.

One solution for this is to simply front all access to your cameras with a SSL secured reverse proxy. We did this using Apache’s mod_proxy. I’m not going to go into every detail of how to do this below, but the point is to give the reader a starting point. You can lookup the details on all these apache configuration specifics elsewhere on the web, there are tons of examples out there.

The example below would be for securing access to 2 (two) Foscam IP cameras on your local network, living on an example subnet 192.168.1.0. It assumes the local network is fronted by a router that supports port forwarding, which most consumer/business routers do. The end objective here is that when you access https://myproxy.host.com:10001 you will be accessing CAM1 and when you access https://myproxy.host.com:10002 you will be accessing CAM2.

Secondarily you can also set it up so that you could hit CAM1 at https://myproxy.host.com:10000/cam1/ and CAM2 at https://myproxy.host.com:10000/cam2/

  1. CAM1 IP = 192.168.1.100 listening on port 80
  2. CAM2 IP = 192.168.1.101 listening on port 80
  3. Reverse Proxy Server = 192.168.1.50 listening on ports 10000, 10001, 10002
  4. Router IP address: 192.168.1.1  configured with port forwarding as follows: Port 10000 -> 192.168.1.50:10000, 10001 -> 192.168.1.50:10001 and 10002 -> 192.168.1.50:10002

OVERVIEW

  • First off you need to setup a computer/server running Apache. The Apache webserver is available for almost every operating system known to man from linux to windows, to os-x. This server’s IP address is 192.168.1.50 and ensure that name based virtual host support is enabled as well as mod_ssl.
  • Next ensure that apache is listening on all the necessary ports (the 3 mentioned above). You will want to have Apache listen on a separate unique port for each IP Camera it is proxying access to, or at least one unique port if you are proxying the cameras of of a sub-path: For this example we are assigning port 10000 -> [CAM1 & CAM2 via sub-dir proxies], port 10001->CAM1 only and 10002->CAM2 only. Within your apache configuration you will want to ensure that you have statements like the following configured:
NameVirtualHost *:10000
NameVirtualHost *:10001
NameVirtualHost *:10002
Listen 10000
Listen 10001
Listen 10002
  • Now that Apache is configured to listen on the necessary ports, we need to configure the actual virtual hosts and the reverse proxying directives within each host, see the example below:
###############################
# Reverse proxy config for BOTH
# CAMs (1 & 2) via sub-paths
# @ 192.168.1.100
###############################
<VirtualHost 192.168.1.50:10000>
 ProxyRequests Off
 ProxyPreserveHost On
 ProxyVia On
 <Proxy *>
 Order deny,allow
 Allow from all
 </Proxy>

 # CAM1 (note trailing / is important)
 ProxyPass /cam1/ http://192.168.1.100:80/
 ProxyPassReverse /cam1/ http://192.168.1.100:80/

 # CAM2 (note trailing / is important)
 ProxyPass /cam2/ http://192.168.1.101:80/
 ProxyPassReverse /cam2/ http://192.168.1.101:80/

 CustomLog /path/to/apachelogs/access_cam1.log combined
 ErrorLog /path/to/apachelogs/error_cam1.log
 ServerName cam3

 SSLEngine On
 SSLCertificateFile /path/to/sslcert/mysslcert.crt
 SSLCertificateKeyFile /path/to/sslkey/sslkey.key

 <FilesMatch "\.(cgi|shtml|phtml|php)$">
 SSLOptions +StdEnvVars
 </FilesMatch>
 <Directory /usr/lib/cgi-bin>
 SSLOptions +StdEnvVars
 </Directory>

 BrowserMatch "MSIE [2-6]" \
 nokeepalive ssl-unclean-shutdown \
 downgrade-1.0 force-response-1.0
 # MSIE 7 and newer should be able to use keepalive
 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

###############################
# Reverse proxy config for CAM1
# @ 192.168.1.100
###############################
<VirtualHost 192.168.1.50:10001>
 ProxyRequests Off
 ProxyPreserveHost On
 ProxyVia On
 <Proxy *>
 Order deny,allow
 Allow from all
 </Proxy>
 ProxyPass / http://192.168.1.100:80/
 ProxyPassReverse / http://192.168.1.100:80/
 CustomLog /path/to/apachelogs/access_cam1.log combined
 ErrorLog /path/to/apachelogs/error_cam1.log
 ServerName cam3

 SSLEngine On
 SSLCertificateFile /path/to/sslcert/mysslcert.crt
 SSLCertificateKeyFile /path/to/sslkey/sslkey.key

 <FilesMatch "\.(cgi|shtml|phtml|php)$">
 SSLOptions +StdEnvVars
 </FilesMatch>
 <Directory /usr/lib/cgi-bin>
 SSLOptions +StdEnvVars
 </Directory>

 BrowserMatch "MSIE [2-6]" \
 nokeepalive ssl-unclean-shutdown \
 downgrade-1.0 force-response-1.0
 # MSIE 7 and newer should be able to use keepalive
 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

###############################
# Reverse proxy config for CAM2
# @ 192.168.1.101
###############################
<VirtualHost 192.168.1.50:10002>
 ProxyRequests Off
 ProxyPreserveHost On
 ProxyVia On
 <Proxy *>
 Order deny,allow
 Allow from all
 </Proxy>
 ProxyPass / http://192.168.1.101:80/
 ProxyPassReverse / http://192.168.1.101:80/
 CustomLog /path/to/apachelogs/access_cam2.log combined
 ErrorLog /path/to/apachelogs/error_cam2.log
 ServerName cam3

 SSLEngine On
 SSLCertificateFile /path/to/sslcert/mysslcert.crt
 SSLCertificateKeyFile /path/to/sslkey/sslkey.key

 <FilesMatch "\.(cgi|shtml|phtml|php)$">
 SSLOptions +StdEnvVars
 </FilesMatch>
 <Directory /usr/lib/cgi-bin>
 SSLOptions +StdEnvVars
 </Directory>

 BrowserMatch "MSIE [2-6]" \
 nokeepalive ssl-unclean-shutdown \
 downgrade-1.0 force-response-1.0
 # MSIE 7 and newer should be able to use keepalive
 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
  • Ok, so before you start up apache, you need to generate your own self-signed SSL certificate/key. See those lines above in the configuration for “SSLCertificateFile” and “SSLCertificateKeyFile”? You will need to generate your own SSL private key, certificate request, and then self sign it. The results of those openssl commands yield files that you point to on your local proxy server. You can read here for an example on how to generate the necessary files
  • Next ensure the router that sits in front of your proxy server @ 192.168.1.50 has port forwarding enabled and forwards traffic going to port 10000, 10001 and 10002 to your proxy server.
  • Start up apache, work out the kinks and you should be ready to go. If you are outside of your normal network you will need to find your router’s WAN public IP address and go to https://my.external.router.ip:10001 and https://my.external.router.ip:10002 and you will be accessing CAM1 and CAM2 respectively over SSL from anywhere in the world. OR secondarily you can also go to https://my.external.router.ip:10000/cam1/ and https://my.external.router.ip:10000/cam2/ to hit the cameras. Please note that traffic from your browser to your proxy server is encrypted with SSL, however the SSL encryption will terminate at the proxy server. Network traffic from your proxy server to CAM1 and CAM2 is unencrypted but only running over your local network. This article assumes you trust who is on your local network not to be sniffing packets.
  • You will also want to ensure that your proxy server has a firewall on it, permits IP forwarding, limits access to only the necessary ports and is configured securely. You can handle that on your own and that is outside of the scope of this article.
  • Hopefully this helps someone out there who wants to securely access their IP cameras over the internet. Note that what is described above should work with any IP camera on the market that only supports HTTP, however the general procedure described above was only tested to work with Foscam model FI8910W

SOFTWARE FOR VIEWING YOUR PROXIED CAMERAS

I’ve received many questions regarding which apps out there support talking to Foscam’s behind a SSL secured proxy and unfortunately the few I’ve used all fall short in one way or another. Proxying http/https based resources on a network (via ports, sub-paths or other methods) is a technology that has been around for a long time and from an client apps perspective it need not know it is even there. Secondarily, the Foscam camera APIs will work just fine regardless of how they are proxied (from the root url or off of a sub-path in the proxy). Regardless here are some apps I’ve used below with some notes

  • iOS: FoscamPro: Cool app, works great when you are on your internal network, but fails miserably if you try to use it from outside your network when your cameras are behind an SSL secured proxy as described above. Why? The FoscamPro application simply DOES NOT support SSL. (FoscamPro devs: PLEASE IMPLEMENT THIS!) The only way to use FoscamPro in the setup above is if you have a VPN server running behind your router; you then connect to your home VPN which lets you appear “internal” to your local network when you are outside of your network, and then access your cameras directly, bypassing the proxy. The VPN itself is what is encrypting all of your communications.
  • iOS: Live Cams Pro: Cool app, works very similar to FoscamPro but supports other manufacturers and more devices, generic url streams etc. They DO support SSL which works with the proxied setup described above. However they DO NOT support specifying a relative path off of the base IP that you are connecting to a Foscam camera with. This effectively eliminates your ability to proxy your cameras via sub-dirs (i.e. https://my.net/cam1/) which is CRITICAL if you have a lot of cams but your router limits the number of port forwards you can have! (Live Cams Pro devs: PLEASE IMPLEMENT THIS!)
  • Android: tinyCam Monitor PRO: Cool app, I must admit I am pretty sure this supports HTTPS as I was testing with this earlier this summer for the port-> cam based config. I have not tested with the sub-dir path setup. If someone can shoot me an update on this I’ll appreciate it. (I’ve switched to all iOS)
About these ads

45 thoughts on “Securing Foscam IP camera access over SSL with Apache reverse proxying

  1. Just got 2 8910’s figuring, who would make an IP cam without SSL? I’m running openSuse on one of my computers so this is a perfect solution. Thanks.

  2. This is great, thank you so much for posting this. One question though, do you know if any of the mobile apps for iOS or Android handle SSL logins and still work after setting this up?

    1. Well that is another matter; for Android I use TinyCam Monitor PRO (which DOES support connecting via SSL). For iOS (iPad) I use the FoscamPro app, this is a cool app, however it does NOT currently support connecting over SSL; I’ve requested this from the developer but have not heard much movement on it.

      That said, worst case scenario… if you are already going to the trouble of setting up a reverse proxy to access your cams, go ahead and setup a PPTP VPN server on that box as well and expose it to the outside. This will let you connect over a secure VPN to your local lan (which most phones, ios devices support), then access your cameras over http or https, doesn’t really matter at that point.

      1. Hrmm… I’ll have to look into some of the apps for iOS and see what does what. I also use FoscamPro, but they seem pretty slow to put out updates, although they seem to be worthwhile updates when they come out. We’ll see. I’ll leave another comment if I find something decent that handles SSL.

        VPN would be fine if it were only me using it… but I don’t think the wife will be too fond of the process. Then again, if I’m doing VPN, then reverse proxy isn’t even needed if I only use it from mobile devices. sigh… too much thinking so early… where’s that coffee?

  3. Thanks for the tips. I managed to set up reverse proxy following your instructions.

    However, I am having some problems and I hope you can point me in the right direction.

    I find the the connection has slowed down dramatically with Reverse Proxy/SSL compared to straight to camera. Is this expected? If I connected locally using SSL it is still very responsive but going from internet to proxy is very slow.

    Also audio options in tinyCam PRO are removed in SSL mode but REC still there. Are you seeing this as well?

    Thanks

    1. James, some slowness is to be expected due to encryption and additional hops. In my experience it was not that bad but there are so many factors at play. Your hardware, uplink, network etc. I didn’t loose any audio, but I was using that iPad app mentioned on the article. I was not viewing via the browser.

      1. I have the same app on ipad I will try that too. But on my Android phone using tinyCAM the audio is definitely gone. I added the same camera but non SSL and audio works fine.

        I’ve read nginx works faster and less load on the host PC. I will give that a try.

        Thanks.

  4. Hey James, were you able to fix the audio issue with tinyCAM on android? I too have same issue, don’t have any ios device to test it out. Can you please confirm?

    Thanks

    1. Still no audio when using SSL on Android. Also still have the massive delay when controlling the PTZ. I don’t think it’s the network speed as I’ve tried it with 4G and different WIFI hotspots. The image loads straight away but moving the cam around has a 5 sec delay.

      I tried nginx as well and it was the exact same…

      1. Hmm I have not had any major latency issues and my proxy is like a 6 year old server. Are your cameras hooked up via wifi or hard wired Ethernet?

      2. It’s connected via wifi. However when I am at home (LAN/WLAN) I dont notice the same delay. This is still going through the SSL.

    1. @EggmanTech: NOTE, another way to proxy cams is via a sub-path off of the root of the URL. Your app (Live Cams Pro) does not seem to permit that. I have a camera proxied @ https://mydomin/cam1/ but I cannot specify that path anywhere when adding a camera. Hopefully you can support this??

      1. Did you ever test this?
        Does the reverse proxy Apache setup work OK on iPhone / iPad?
        don;t want to drop money on yet ANOTHER app if it still does not play nicely. (I have 2 Foscams behind an apache reverse proxy – almost exactly as per this atricle)

        Thanks

      2. Yes, please see my comments about each app above. Foscam Pro definitely does not work with it because there is no SSL; Live Cams Pro works partially (does not support proxied cams off of a sub directory)

  5. Our app (v2.2) currently has an issue with iPhone 5 (the menu bar fails to appear until you rotate the phone on its side) but otherwise should be ok. We have a 2.3 release that is almost ready. Most surveillance apps in the store have been copying us since we hit the #1 paid app spot in 2009. Angry Birds knocked us out of place but we’re determined to work our way back :)

  6. @EggmanTech: NOTE, another way to proxy cams is via a sub-path off of the root of the URL. Your app (Live Cams Pro) does not seem to permit that. I have a camera proxied @ https://mydomin/cam1/ but I cannot specify that path anywhere when adding a camera. Hopefully you can support this?

  7. Eggman, you mention these cameras use a ‘custom TCP protocol’ to support audio. Can you give more information on this? I’d like to investigate the limitations and possible alternatives to achieve SSL with audio. THanks.

  8. Hi, Thank you very much for the article which was exactly what I was looking for.
    I’m not an expert of Apache therefore I left more or less your configuration unchanged except for the host and ports.
    When I try to connect to my proxy, everything works fine; I can reach the ip-cam and complete the authentication but after that, no images are shown. The box where I should see the images displays “Login fail”. Do you have any suggestion or tip?
    My cam is a Foscam FI8608W. THANKS

    1. Max – hmm, sort of sounds to me like the HTML being returned back to the browser (regardless of proxy or no proxy), might (maybe) have hardwired http:// [and/or some specific port] prefixed url references in the page causing the browser to make invalid requests. That model is different then the one I tested with. Not sure, I’d have to see the source HTML that your browser is rendering when it shows the login fail in the placeholder for the image.

      1. Hi bitsofinfo, thank you for your reply. I’m afraid you reached my same conclusion, the problem is that it took you a couple of hours while it took me 2 weeks! I got the source HTML but I can’t post it here because with javascript included, it is more than 2600 lines. I also tested a similar solution with Nginx and Node.js (with module node-proxy) and this also failed.

  9. Tinycam Monitor does NOT support the sub-dir path config at least not the free version which annoyingly does not let you even test an SSL connection.

    As soon as you give it a url with the subdir for the camera behind a reverse proxy (i.e., zzz.freedns.com/cam2), it strips the http:// and /cam2 leaving you with a non-functioning url.

    I can’t believe no one supports this config.

    I ended up using changeip for my ddns provider as their free service allows you to have cam1.xxx.name.org, cam2.xxx.name.org, etc. This does make it necessary to generate a wildcard ssl cert, but gets rid of the port proliferation issue.

  10. Just want to say this article has been very helpful. Although instead of setting up Apache, I found quite a neat alternative solution. I run a DD-WRT router at home, and I installed Optware and Pound on it. It is much easier to configure Pound than Apache, and I believe it has a lighter footprint than Apache. So now, I can run a reverse SSL proxy on my DD-WRT router consuming little electricity. I am also able to set up Pound to listen onto multiple ports, each port mapping back to an individual camera.

    1. Hi CTeeee, do you have any step by step instructions for DD-WRT setup? It will be very much helpful for people who don’t wish to keep PC running Apache server 24X7 all time.

      Thanks

  11. Like the issues mentioned above, I also cannot get audio over SSL. May be it is time to put a sniffer on the network to understand the audio packets.

  12. I tried doing the configurations you recommended. I can get through the homepage of my Foscam but I can’t login it always says Connect Failed. I reckon it is the media port not being proxied. I have a Foscam FI9821W that has a media port. Do you happen to know any solution to this?

    1. Sorry I don’t, please see the other comments on this thread. Sounds like the audio issue is affecting just about everyone.

  13. Audio support only works if you use stunnel (https://www.stunnel.org) as reverse proxy daemon with ssl certificate.
    I have made many tests with apache, lighttpd and nginx without success (everything works except the audio).

    I do not understand why with stunnel the audio channel passes…but it works!!!

    Unlike the others, stunnel is not a web server but only a proxy software (which also is configurable as a reverse proxy).
    Probably has a more simple implementation of the mechanism of proxy and therefore does not block the audio stream that is independent from the video stream.

    From “Live Cams Pro” and from chrome browser (html) the connection with webcam through stunnel is perfect with bidirectional audio support in “Live Cams Pro”.

    With “Internet explorer” and “firefox” stunnel mysteriously drop connection during load of html!!!

    With apache lighttpd and nginx no problem at all (chrome, ie, firefox) except for audio support in “Live Cams Pro”.

    At the end I chose lighttpd losing audio support but keeping full compatibility with different browsers and ios apps.

  14. What a great post, very helpful and informative thank you. I have a question which hasn’t been asked yet and I’m not sure if it’s possible or not.

    These cams have the feature to auto-send an image to an email address upon motion detection. To set this up requires inputting details of the email server (username, password) onto the camera’s localserver. My concern is that using the method described above the cam will still send those details unsecured over the net. Is that right?

    If so, any ideas how to fix that one?

    Cheers.

    1. One suggestion might be to setup a local MTA (mail server) on your local network. Have all cams dump their mail to your local server, then setup a gmail account and have your local mail server relay using your gmail account over TLS. There are lots of articles on how to setup a local mailserver to relay though your Gmail account securely. Just do some searching and you will be good to go. http://appgirl.net/blog/2009/configuring-sendmail-to-relay-through-gmail-smtp/

    1. I did all the above but nothing.
      Apache don’t even receive http requests.
      Can anyone explain the port forward?
      Does my router need to map 192.168.1.50:10001 port with
      192.168.1.50:80 port?
      Does apache only listen to the above ports(10000,10001,10002) or
      also need to listen to the 80 port?

  15. I configured Apache on a CentOS 6.4 Virtual Machine, which is running on my Win 7 machine. The host machine itself is configured with Symantec EndPoint Protection, and had to be tweaked a little to allow port forwarding and web service requests to go in/out of the VM. The SSL Reverse Proxy works perfectly, however, I am unable to get any audio. Is there a specific port the cameras use for audio? If so, I feel I may need to relax the Symantec firewall settings to allow outgoing traffic on the audio port as well as http/https.

  16. Great post… I am trying to set up remote connectivity to a VistaCam PT using just port forwarding in a WNDR3400v3 Netear router. My problem is that Netgear has locked down the remote management to an https:// connection. Since the imbedded web server in the camera will not support https:// connections, I cannot access it from the outside world. The connection works fine from within the network using the non-routable address.

    Any suggesetions????

    1. If your router restricts access to its console on 443 that has nothing to do w/ port forwarding for 443 to another server behind the router which acts as a proxy to your camera… which is what this article is all about. client->443->router->443->proxyServer->80->camera

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s