This section details how to set up squeeze-alexa using the SSL Tunnel transport option.
Note how the arbitrary ports are not labelled - see setting up ports.
- Generally the connections go
lambda -> router:extport -> server:sslport -> lms:9090
(see diagram above). Most people will havelms
andserver
on the same host (Synology / ReadyNAS / whatever). - Choose some values for
extport
andsslport
e.g.19090
. For sanity, it's probably easiest to use the same port externally as internally, i.e.extport == sslport
- On your router, forward
extport
to the stunnel / haproxy /nginx port (sslport
) on that server.
- This is recommended if you don't have fixed IP, so that there's a consistent address to reach your home...
- Try www.dyndns.org or www.noip.com, or better still your NAS drive or router might be pre-configured with its own (Synology has their own dynamic DNS setup, for example).
- Note down this external (Internet) address (e.g.
bob-the-builder.noip.com
). We'll call itMY_HOSTNAME
later.
- If you have your own domain name (e.g.
house.example.com
) available, I strongly suggest using the DDNS to forward to this (withCNAME
) especially if on dynamic IP. Why? Because DNS takes too long to refresh, but DDNS is near immediate. - This will also allow you to create better-looking certificates against a meaningful subject (domain name). It's then this that will be your
MY_HOSTNAME
later.
You can skip this step if you already have one, of course, so long as it's the same address used for MY_HOSTNAME
above.
This should be working on your local network as well, i.e. make sure your server knows that it's the address at MY_HOSTNAME
.
It's worth reading up on OpenSSL, it's crazily powerful. If that's a bit TL;DR then here is a fairly secure setup, inspired largely by this openssl SO post
openssl req -x509 -newkey rsa:2048 -sha256 -nodes -keyout key.pem -out cert.pem -subj "/CN=$MY_HOSTNAME" -days 3650
cat cert.pem key.pem > etc/certs/squeeze-alexa.pem && rm -f key.pem cert.pem
TODO: document optional creation of separate server cert for more complicated better(ish) security.
From your server, check this works (substitute MY-SERVER
as before)
$ ping -c 4 localhost
$ ping -c 4 MY-SERVER
If the latter fails, try using localhost
, but it's better to set up your DNS to work internally, e.g. add this to your /etc/hosts
:
127.0.0.1 localhost MY-SERVER
See TROUBLESHOOTING for detailed diagnosis of connection problems.
When you open up your LMS to the world, well, you don't really want do that, but for Alexa to work this generally* needs to happen.
See connecting remotely on the wiki, but it's more around Web than CLI (which is how squeeze-alexa
works).
You could use the username / password auth LMS CLI provides, but for these problems:
- It's in plain text, so everyone can see and log everything. This is pretty bad.
- The credentials aren't rotated so once they're gone, they're good to go
- Nor do they include a token (à la CSRF) or nonce - so replay attacks are easy too.
- There is no rate limiting or banning in LMS, so brute-forcing the password is easy (though it does hang up IIRC).
By mandating client-side TLS (aka SSL) with a private cert, squeeze-alexa
avoids most of these problems.
* Or you could use MQTT of course.
There are quite a few ways to do this with existing open-source software. Pick your favourite!
- stunnel. This is old but the most supported here (see details below), but other options should work here (feedback wanted!)
- nginx 1.9+ supports TCP Load Balancing which can be used with the nginx SSL module to do this.
- HAProxy does support TLS-wrapping of generic TCP.
- Also, there's ssl_wrapper but I've not tried this.
Whichever one of these you choose, make sure you configure a new (safe) TLS, minimum TLS v1.2.
Follow this excellent Synology forum post to install Entware if you don't have it.
opkg install stunnel
Your config will live at /Apps/opt/etc/stunnel/stunnel.conf
.
There are various ways of getting a script to start up automatically on Synology.
You could "do this properly" and make it a system service, you can create Upstart scripts.
Just drop the script:
#!/bin/sh
if [ -n "`pidof stunnel`" ] ;then
killall stunnel 2>/dev/null
fi
/Apps/opt/bin/stunnel
to /Apps/opt/etc/init.d/S20stunnel
. Make sure it's executable:
chmod +x /Apps/opt/etc/init.d/S20stunnel
You should try running it and checking the process is a live and logging where you expect (as per your stunnel.conf
).
You could set the script above to run as a scheduled startup task in your Synology DSM GUI.
I've tried this on Synology but it should be similar on Netgear ReadyNAS - this forum posting seems helpful.
Some other NAS drives can also use ipkg
/ opkg
, in which case see above.
Else, find a way of installing it (you can build from source if you know how).
This should work (untested):
sudo apt-get install stunnel4 openssl -y
See a great stunnel on RPi article (though that's more complicated than we need).
Copy the squeeze-alexa.pem
to somewhere stunnel can see it, e.g. the same location as stunnel.conf
(see above).
See the example stunnel.conf
for a fuller version, but you'll need changes of course.
To do so you'll need something to edit your stunnel.conf
(e.g. vim
or nano
) and add this at the end, referring to the cert path you just used above e.g. (for Entware):
[slim]
accept = MY-PORT
connect = MY-HOSTNAME:9090
verify = 3
CAfile = /Apps/opt/etc/stunnel/squeeze-alexa.pem
cert = /Apps/opt/etc/stunnel/squeeze-alexa.pem
As before MY-PORT
and MY-HOSTNAME
should be substituted with your own values.
Note that here MY-HOSTNAME
here is referring to the LMS address as seen from the proxy, i.e. internally.
This will usually just be blank (==localhost
) if your LMS is on the same machine as stunnel.
🆕 Nginx (1.9+) is known to work for squeeze-alexa.
- If you're on Raspberry Pi, make sure you have a new enough version.
- Try this example config, or something similar (remember to replace
LMS_SERVER
andSSL_PORT
, or set them in your environment). - You'll usually want to override the default nginx.conf (e.g.
etc/nginx/nginx.conf
). - You'll need to copy the cert across to
/etc/ssl/squeeze-alexa.pem
- Make sure to start / restart (e.g.
systemctl restart nginx
) once you're done and start testing...
🆕 This can be Dockerised easily for people who prefer Docker (and have it available on their server). See the nginx-tcp-ssl directory. The hard bit is probably getting your networking stable and port-forwarding appropriately. Remember the certificate name has to match this server's hostname...
From the directory above, first copy your squeeze-alexa.pem
file in, then:
docker build --build-arg INTERNAL_SERVER_HOSTNAME=192.168.1.123 -t $(basename $PWD) .
docker run -p 19090:19090 $(basename $PWD)