Chat freely about anything...

User avatar
By abl
#14229 Hi folks! Since SSL is pretty difficult to use right now (iirc the only general firmware with working SSL is ESP_MQTT - NodeMCU/Frankenstein/ESPduino do not support it), here are a couple ways to provide secure(-ish) remote access to your projects, assuming you trust your local network.

DISCLAIMER: The below, properly implemented, will protect you from casual attacks (and stops all unauthenticated traffic, which helps cut down on what your ESP8266 has to handle gracefully.) Implemented poorly? No security at all.

What will I need?
You'll need something that isn't the ESP8266 on your network handling SSL termination. This can be a Raspberry Pi, a Windows computer, basically anything. I'm going to refer to "rPi" in this document.

Why shouldn't I just port forward?

Opening a port means anyone who knows that port is open can send data to your ESP8266. If your ESP8266 is hooked up to anything interesting, or annoying, this represents a pretty major risk!

What are the options?

Here are a few in order of simplicity:

  • SSH port forwarding
  • ngrok
  • A VPN
  • STunnel and google_oauth_proxy (or Doorman)

SSH port forwarding

This is the easiest option; this is also the only option that works if your ESP8266 project isn't using HTTP. (Note that it's pretty easy to fake HTTP.)

  1. Set up SSH on your rPi
  2. Forward port 22 to your rPi (I personally recommend using a public port that is NOT 22 - any five-digit port should work. Open port 22 means you'll get a lot of casual password guessers trying to break in.)

That's it! From anywhere, you can now:

ssh -N <your username>@<your public ip> -p <your public port> -L 22222:<your ESP8266's IP>:33333

This will connect port 22222 on your local machine to port 33333 on your ESP8266. Stopping SSH will close the connection. (The -N flag prevents SSH from starting a shell on your rPi - this way it just sets up a port forward.

If you have multiple ESP8266s, you can forward multiple ports by adding more -L flags - make sure the local port (the first argument) is unique.

The downside to this approach is that it's somewhat cumbersome - you have to run an SSH client that supports port forwarding, so if you want to access this on your mobile device, it's a bit of effort (iOS port forwarding is kind of awful. Android port forwarding can be a battery drainer.)

ngrok

ngrok (from ngrok.com) is an amazing, open-source, swiss army knife service/tool - and it's free for everything you'd want. You can even run your own ngrok server if you want, but theirs is, again, free. :)

Just install ngrok, register for an account (which lets you save a few preferences and select custom subdomains) and then run:

ngrok -subdomain="mycoolproject" -proto=https -httpauth="<username>:<password>" <your ESP8266's IP>:33333

(note that using the -subdomain flag requires signing up for a free ngrok account.)

Assuming your ESP8266 is serving something HTTP-like on port 33333, you can now go to https://mycoolproject.ngrok.com and access it - not only that, but the computer running ngrok will show you a log of all requests, and you'll be prompted (securely) for the username and password you provided to it. The log is great if you're building a client application - super easy debugging of what exactly was transmitted.

You can also use proto=http to disable HTTPS, but there's no advantage there.

You can also use proto=tcp to proxy a raw socket (like with SSH) but then there's no security - it's functionally the same as a port forward.

The downside to ngrok is that it's somewhat slow - it only proxies one connection at a time - but that's sort of a nonissue for the ESP8266.

A VPN

Setting up a VPN is painful, and there are a lot of downsides, but it's technically easier than what I'm about to suggest, so...

STunnel and google_oauth_proxy (or Doorman)

This is another HTTP-only solution.

STunnel is a SSL swiss army knife - you'll open a port, forward to it, and it will forward to one of the two proxies I mentioned. It also has SNI support, which lets you run multiple domains (with different certificates, not a wildcard) off of a single port.

google_oauth_proxy and Doorman are security proxies - they handle authentication via, for example, Google - so if you have a GMail account, and whitelist it, you're done. This makes it really easy to add and remove users.

NOTE: You could replace STunnel with ngrok, but you'd need a paid ngrok account and you'd get SSL warnings since the certificate won't match. (They don't offer custom certificates yet.)

The final puzzle piece is your own domain and StartSSL - StartSSL will issue free, fully trusted, SSL certificates that work in every browser I've touched. The wildcard certificates aren't free, which is why SNI support is so helpful. :)

This means you could, in theory, set things up so that...

https://esp8266-1.mydomain.com
https://esp8266-2.mydomain.com
https://esp8266-3.mydomain.com

All shared a single authentication cookie (via Google, or any of the Doorman-supported services) and transparently connected you to ESP8266es connected to your local network!

I'm not going to cover the steps for this because there are many, many ways to set this up incorrectly - this is what I've got running right now and it's quite nice, if a little painful to add new nodes. Read docs, give it a try, and if you hit a wall ask about it here and I'll try to answer it. :)
User avatar
By tomte76
#31324 Thank you for the interesting post:

I'd like to add, that since SDK-1.3 it is possible to use TLS-v1.1 HTTPS. I suceeded in sending data to my emoncms server. This is a log-entry from the apache-server:

Code: Select all12/Oct/2015:20:58:41 +0200] 11.22.33.44 TLSv1.1 AES256-SHA “GET /emoncms/input/post.json?node=esp02&json={temp:21.89,humid:39.70,rssi:-57,vdd:3562,heap:45272}&apikey=myniceandsecretapikey HTTP/1.1” 2


Also I succeded in sending data to Thingspeak using HTTPS. I used esphttpclient from https://github.com/Caerbannog/esphttpclient in my akku-powered sensor project. It runs for serveral days now without any issues.