Using a AWS Linux server, and Raspberry Pi, Ubuntu or Robustel router clients
Situation
- Lots of linux devices (and embedded devices) behind firewalls without public IP address
- Publicly accessible computer (AWS)
Goals
- Connect from the server (or office PC) to these devices
- Something easier than ssh port forwarding
- Ability to connect a publicly accessible site (e.g. MyIoT.com/device1) to the device1 network (private) on arbitrary port. This will allow viewing of devices from the internet.
- Secure, robust and expandable
Solution
- OpenVPN (this post)
- Other options are SSH tunnels, IPSec, propriety VPN, etc
Details
Setup
- Setup OpenVPN CA, clients and server with excellent linux tutorial.
- Use
nc
to test UDP ports and firewall - Modifed some scripts to facilitate key creation
add_client.sh
Run on the openvpa server to create a new client
#!/bin/bash
#
# Create a OpenVPN client configuration, wait for CA signing, then configure the client machine with it
#
# Requires "client" to be ssh accessible to setup client machine
#
# First argument: Client identifier
if [ $# -ne 1 ] then
echo Wrong args - supply name like "client3"
exit 1
fi
EASY_RSA_DIR=~/easyrsa3/
KEY_DIR=~/client-configs/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf
# make keys
cd "$EASY_RSA_DIR"
./easyrsa --batch --req-cn="$1" gen-req "$1" nopass
# copy req to CA
read -p "Run 'make_client $1' on the CA machine,copy back '$1.crt' and then press enter"
# put everything in KEY_DIR
cp pki/private/$1.key ~/client-configs/keys/
# package up
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
${KEY_DIR}/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
${KEY_DIR}/ta.key \
<(echo -e '</tls-auth>') \
| sudo tee ${OUTPUT_DIR}/${1}.ovpn 1>/dev/null
# copy client openvpn config to client. It includes everything required for the client.
scp $OUTPUT_DIR/$1.ovpn $1:.
# install openvpn on client and start
scp install_openvpn_client.sh $1.ovpn
ssh $1
install_openvpn_client.sh
Run on the client machine to start openvpn
#!/bin/sh
# run on the client
# First argument: Client identifier
if [ $# -ne 1 ]
then
echo Wrong args - supply name of .ovpn file like "client1.ovpn"
exit 1
fi
sudo apt install openvpn openvpn-systemd-resolved
sudo cp $1 /etc/openvpn/client.ovpn
sudo systemctl enable openvpn@client
sudo systemctl start openvpn@client
make_client_cert.sh
Run on the CA machine to sign the certificate request
#!/bin/bash
# First argument: Client identifier
if [ $# -ne 1 ]; then
echo Wrong args - supply name like "client3"
exit 1
fi
SERVER=live.openvpnserver-changeme.com
KEY_DIR=$SERVER:client-configs/keys
REQ_DIR=$SERVER:easyrsa3/pki/reqs
EASY_RSA_DIR=~/easyrsa3/
cd "$EASY_RSA_DIR"
# get .req from openvpn server
scp $REQ_DIR/$1.req /tmp
# process request
./easyrsa --batch import-req /tmp/$1.req $1
./easyrsa --batch sign-req client $1
# put client cert to openvpn server
scp pki/issued/$1.crt $KEY_DIR/
Robustel Router OpenVPN
The above clients are linux boxes. Sometimes I use a R1510-4L Robustel Wifi/3G router. This is the setup to connect to the OpenVPN server configured above.
- OpenVPN tunnel tab: edit connection and set to match your OpenVPN server.conf:
- Auth Type: x509CA
- Mode: Client
- Encrypt Algo: AES-256
- Auth Algo: SHA256
- Enable compression: OFF(1)
- Enable HMAC Firewall: ON (2)
(1) ensure this is on at the server. Symptom was “unknown IP version=15” openvpn server log indicating compression problems. Also not contactable even if connected.
(2) sympton was HMAC errors in the openvpn server log
- x509 tab: upload your files
- Root CA: ca.crt : the CA’s certificate
- Certificate File: client1.crt : the client’s certificate
- Private Key: client1.key : the client’s key
- TLS-Auth Key: ta.key
- PKCS#12: not required (was possible to create with
openssl
but didn’t need)
Saving data:
- A resting router with an active open seems to use a lot of data (5 Mb/hour = 100 Mb/day!)
- I increased ping and openvpn keep alive (60 ping : 600 failed)
- New test with computer disconnected and openvpn running
- RX:8224KiB TX:15511KiB ALL:23MiB @ 21:55
- RX:8489KiB TX:15762KiB ALL:23MiB @ 12:00 next day
- Hence 516kB/hour or ~1Mb/day or 26Mb/month
- Test with not openvpn, just a Rpi running autossh
- TX:10420KiB TX:18037KiB ALL:27MiB @ 14:00
Connecting Remotely
- Can’t connect via OpenVPN from a client’s browser.
- But CAN ping and wget the index.html page. WTF?
- Tried some
route -n
and interface priority stuff: no luck. - Tried on windows : no luck.
- Maybe a local proxy or SOCKs server: no luck
- Cannot connect. Giving up. Use a openvpn client behind the router on a pizero instead.