Using a AWS Linux server, and Raspberry Pi Zero 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 OpenVPN Server and CA
- 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/
Setup of Raspi Client
Coming soon. Spoiler: write a long script to do a million little things to get a key.