OpenVPN (Linux)
Introduction
OpenVPN is an open-source software application that allows you to create a secure point-to-point or site-to-site connection to another network over the Internet. It uses a custom security protocol that utilizes SSL/TLS for key exchange.
In addition to this article, you can also check our blog from 26-04-2021 Using a VPN on Embedded Linux Systems. It talks about both OpenVPN and WireGuard.
This article focuses on the Reference Images for Yocto Project. If you are using Torizon, please refer to the article How to Use VPN on Torizon OS.
Toradex Pre-Built Images
OpenVPN does not come pre-installed with the Toradex pre-built images. You can add support by building a custom image using OpenEmbedded. For instructions on how to build an OpenEmbedded image, see OpenEmbedded (core).
Adding OpenVPN using OpenEmbedded
Meta-Networking provides OpenVPN and Bridge-Utils as recipes in OpenEmbedded. To add it to the image add the following line to your local.conf:
...
IMAGE_INSTALL_append = "bridge-utils openvpn"
The Kernel feature BRIDGE must be activated through the following path in menuconfig:
[*] Networking support --->
Networking options --->
<*> 802.1d Ethernet Bridging
Installation
In this guide, we will create an OpenVPN server on the host machine and use a module as the client, however, all certification files will be created on the host machine. Install OpenVPN on your host machine:
Ubuntu 16.04
sudo apt-get install openvpn easy-rsa
Fedora 26
sudo dnf install openvpn easy-rsa
Generating Keys for Server and Client
To generate certificates and keys for an OpenVPN server and multiple clients first copy the easy-rsa directory from "/usr/share/" to your home:
cp -ra /usr/share/easy-rsa/ ~
Edit the vars file adjusting the following lines with your own information. Here is a example:
export KEY_COUNTRY="BR"
export KEY_PROVINCE="SP"
export KEY_CITY="Valinhos"
export KEY_ORG="OpenVPN-TEST"
export KEY_EMAIL="user@example.com"
export KEY_OU=""
Run the following commands to generate the master Certificate Authority (CA) certificate and key:
cd ~/easy-rsa/
source vars
./clean-all
./build-ca
Generate the certificate and private key for the server:
./build-key-server server
In this step, two queries require positive responses, "Sign the certificate? [y/n]" and "1 out of 1 certificate requests certified, commit? [y/n]".
Generate the Diffie Hellman parameters for the OpenVPN server:
./build-dh
Generate the certificate and private key for the client:
./build-key client1
In this step, two queries require positive responses, "Sign the certificate? [y/n]" and "1 out of 1 certificate requests certified, commit? [y/n]".
Server Configuration
Copy the generated server certificates and keys from the directory "~/easy-rsa/keys/" to "/etc/openvpn/".
cd ~/easy-rsa/keys/
sudo mkdir /etc/openvpn/
sudo cp server.crt server.key ca.crt dh2048.pem /etc/openvpn/
Along with the OpenVPN installation, you got a server and a client sample config file, unpack the server sample config file called "server.conf.gz" to "/etc/openvpn".
sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
Edit the unpacked "server.conf" file to make sure the following lines are pointing to the certificates and keys you created in the section above.
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
dh d/etc/openvpn/h2048.pem
You can edit the IP of your VPN server on the following line:
server 10.8.0.4 255.255.255.0
Unconmment the following line in "/etc/sysctl.conf" to enable IP forwarding:
#net.ipv4.ip_forward=1
Reload sysctl:
sudo sysctl -p /etc/sysctl.conf
The systemctl command can be used to start the server, as we kept the configuration file as "server.conf", our service is called openvpn@server:
sudo systemctl start openvpn@server
The "sudo systemctl status openvpn@server" output should be similar to the below if everything works well:
● openvpn@server.service - OpenVPN connection to server
Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2018-04-25 16:48:58 -03; 4s ago
Docs: man:openvpn(8)
https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
https://community.openvpn.net/openvpn/wiki/HOWTO
Process: 27299 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid (code=ex
Main PID: 27301 (openvpn)
CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
└─27301 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: /sbin/ip link set dev tun0 up mtu 1500
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: UDPv4 link local (bound): [undef]
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: UDPv4 link remote: [undef]
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: MULTI: multi_init called, r=256 v=256
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: IFCONFIG POOL LIST
Apr 25 16:48:58 Daniel-PC ovpn-server[27301]: Initialization Sequence Completed
Client Configuration
Copy the generated client certificates and keys from the directory "~/easy-rsa/keys/" to "etc/openvpn/" on the module, you may need to create the directory.
scp ca.crt client1.crt client1.key root@10.22.1.75:/etc/openvpn/
Copy the client sample config file to "/etc/openvpn" on the module:
scp /usr/share/doc/openvpn/examples/sample-config-files/client.conf root@10.22.1.75:/etc/openvpn/
Edit the "client.conf" file to make sure the following lines are pointing to the certificates and keys you copied in the previous step.
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client1.crt
key /etc/openvpn/client1.key
Edit the remote IP with your server IP and respective port number:
remote 10.8.0.1 22
The systemctl command can be used to start the connection, as we kept the configuration file as "client.conf", our service is called openvpn@client:
systemctl start openvpn@client
Ping the server to check if everything works:
ping 10.8.0.1