OpenVPN and Weston's VNC/RDP on Torizon OS
Introduction
In this article, we explain how to use OpenVPN and Weston's VNC to make it possible to remotely access the graphical interface on Torizon OS.
Virtual Private Network (VPN) is a technology that enables local-like communications over the internet and OpenVPN is an open-source implementation of this technology.
Virtual Network Computing (VNC) is a technology that makes it possible to share the desktop screen of a device with another device.
Please keep in mind that Torizon OS comes with the WireGuard VPN enabled out-of-the-box, maintained by the Torizon OS team; therefore, it is our recommended solution. Learn more about it on How to Use VPN on Torizon OS.
Prerequisites
- A smartphone capable of using VPN (e.g. installing a VPN application via application market).
- System on Module with Torizon OS installed.
- Basic knowledge about computer networking.
- A computer with
- Linux installed (tested with Ubuntu 20.04).
- Build environment for Torizon containers configured.
- A network port publicly available (optional).
Instructions
We will setup two devices (clients) a module with Torizon OS installed and a smartphone. We also will need a computer to be the OpenVPN server. It makes sense to think about how will be our network architecture. On Figure 1 and Figure 2, solid arrows are "real" connections over the internet between OpenVPN client and server. Dashed lines represent a "direct" connection between clients through a VPN, established by the server. All packets sent by a device through the VPN are actually sent to the server and are then redirected, by the server, to the original target.
In Figure 1 we have the Torizon OS running on a module that is in the same network as the OpenVPN server and the smartphone is in another network, e.g. using mobile data. This is the architecture that we will use in this step by step as a test bench.
In Figure 2, the scenario would be a more realistic one: each device is in a separated network and the clients need to have access to each other. It is good to point out that this case is useful to several solutions and not only for remotely access a graphical interface.
This tutorial is based on two Docker images:
- For the OpenVPN server: kylemanna/docker-openvpn
- This one can be used as-is.
- Its README is very good for starters
- For the OpenVPN client: leibaogit/docker-openvpn-client
- The OpenVPN client Dockerfile from this repository needs to be modified to run on processors other than x86_64, which is the case of Toradex's modules.
Here we will focus on VNC for Weston, but for RDP the steps for OpenVPN are still valid.
If you are going to test it over the internet, you will probably need to do a port-forwarding on your router for UDP on port 1194 (default OpenVPN port, but you can use another, of course). If you want to test on your local network, you won’t need to configure your router.
OpenVPN Server Setup on Computer
The setup of the OpenVPN server on your computer comprehends:
- Set up the IP and port through which the server will be accessible
- Here we define if the OpenVPN server will be accessible inside the local network or for the internet
- Configure some data in it: Name, Location, Password
- Create the certificates to be used on the client devices (in our case, a Toradex module and a smartphone)
In the next section, you can get a script that helps you with the configuration commented above. If you would like to do the configuration step-by-step without the script, you can skip the "Using script" section directly to "Doing Step-by-Step".
Configuring the OpenVPN Server
If you follow the steps of one of the tabs below, you don't need to follow another.
You can download the start-docker-ovpn-server.sh
from the torizon-samples GitHub repository.
The start-docker-ovpn-server.sh is a simple script made to carry out some configuration steps to make it easier. It isn't meant to be a complete command-line tool.
All the certificates created by this script need no password to be used. This makes the tests easier to be carried out, but represents a security issue and should not be used in a real application
The script can be used as follows:
./start-docker-ovpn-server.sh [server-name] [client-name1 [client-name2 [client-name3 [...]]]]
Arguments:
server-name (optional)
: IP address that will be used by OpenVPN server. It can be a local IP address or a public IP address. If no IP address is provided, the public IP address of the machine will be used.
client-name1, client-name2, ... (optional)
: The (arbitrary) name of the clients that will connect to the OpenVPN server. One certificate without a password will be created for each client. The name of the certificate will be like client-name1-cert.ovpn
. All the certificates will be placed in the present working directory.
You will be asked to enter some information in order to initialize the OpenVPN Server (like a name, a location and a password). All the information asked is internally used by the OpenVPN server to realize internal configurations.
Follwing, we have some usage examples:
- Starting OpenVPN Server with IP
192.168.0.33
(a local IP address) and default port1194
andclient-name-1
,client-name-2
,client-name-3
, ... with certificatesclient-name-1-cert.ovpn
,client-name-2-cert.ovpn
,client-name-3-cert.ovpn
, ...
$ ./start-docker-ovpn-server.sh 192.168.0.33 client-name-1 client-name-2 client-name-3
- Starting OpenVPN Server with your current public IP and default port
1194
andclient-name-1
,client-name-2
,client-name-3
, ... with certificatesclient-name-1-cert.ovpn
,client-name-2-cert.ovpn
,client-name-3-cert.ovpn
, ...
$ ./start-docker-ovpn-server.sh client-name-1 client-name-2 client-name-3
- Starting OpenVPN Server with name
server-ip
and default port1194
and no clients
$ ./start-docker-ovpn-server.sh server-ip
- Starting OpenVPN Server with your current public IP and default port
1194
and no clients
$ ./start-docker-ovpn-server.sh
This will create all the issued certificates as well, as displayed by the end of the script, e.g.:
OpenVPN Server created on 187.66.82.17:1194 for clients:
Client Name | Certificate
--------------------------------------------------
module | /home/grilo/module-cert.ovpn
phone | /home/grilo/phone-cert.ovpn
In this section, we will realize the minimum necessary steps to setup our OpenVPN server.
If you want to save time, follow the previous section Using script, and skip this current section and the next section Generating client certificates.
We will use a docker volume to store the OpenVPN data, so we need to create one.
$ docker volume create --name ovpn-server-data
Now we will start using the OpenVPN server Docker image. We need to launch its container to configure through which IP our OpenVPN server will answer. Here you can use your public IP to be accessible from the internet or a local IP to do the tests only inside your local network. You can also use a server name (public or local, just like previously said), if you have one configured and working.
Replace the <MY_SERVER_NAME>
with the IP (or server name) that you will use.
$ docker run -v ovpn-server-data:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://<MY_SERVER_NAME>
$ docker run -v ovpn-server-data:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki
Then, we will start the server process. Here, we are binding the port 1194
of the container (the one to the left of the :
) to the port 1194
of the computer (the one to the right of the :
), which is the default port for OpenVPN.
$ docker run -v ovpn-server-data:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN --name ovpn-server kylemanna/openvpn
This is what we need for this step-by-step regarding the server.
Generating Client Certificates
We need at least two certificates: one for the Toradex module and one for the smartphone. All the certificates will be generated without a password.
To generate a client certificate named torizon, for the module:
# to create the client with named torizon without password
$ docker run -v ovpn-server-data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full torizon nopass
# to retrieve the certificate file of the client named torizon
$ docker run -v ovpn-server-data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient torizon > torizon-cert.ovpn
To generate a client certificate named phone, for the smartphone:
# to create the client with named phone without password
$ docker run -v ovpn-server-data:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full phone nopass
# to retrieve the certificate file of the client named phone
$ docker run -v ovpn-server-data:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient phone > phone-cert.ovpn
The steps needed on the server are done. Now will focus on the clients
Sending Certificates to Devices
To send the certificate torizon-cert.ovpn
to the module, we can use the scp
command to copy it into the /home/torizon
directory.
scp torizon-cert.ovpn torizon@module_family-name-serial_number.local:/home/torizon
Some networking problems may happen if you have an OpenVPN client and the OpenVPN server in the same local network and the certificate of the client points to the public IP of the OpenVPN server. If your network fails under these circumstances, you can edit the certificate of the client (that is in the same network of the server) to replace the public IP of the OpenVPN server with its local IP. This should be enough to carry out the test. If you edit the file on Windows, be sure to save it using End Of Line of Unix systems.
To send the certificate phone-cert.ovpn
to the smartphone, you can use any way you find convenient (e.g.: email, USB stick, instant messaging, USB cable, etc)
Setup on Torizon OS
We need to configure and run the OpenVPN Client and also enable Weston’s VNC.
Preparing OpenVPN Client for Torizon OS
First, clone the repository leibaogit/docker-openvpn-client
$ git clone https://github.com/leibaogit/docker-openvpn-client
We will need to modify the Dockerfile of the repository. We will add --platform=linux/arm/v7
to its FROM
layer of the Dockerfile (line 2) to make it work for the ARM architecture of the module. Be sure to have Arm Emulation enabled on your computer. The modified Dockerfile will be like this:
FROM --platform=linux/arm/v7 alpine:3.4
MAINTAINER Bali Bao <bali.baolei@cn.ibm.com>
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community/" >> /etc/apk/repositories && \
echo "http://dl-4.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
apk add --update openvpn bash && \
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
# Needed by scripts
ENV OPENVPN /etc/openvpn
VOLUME ["/etc/openvpn"]
CMD ["ovpn_client_run"]
ADD ./bin /usr/local/bin
RUN chmod a+x /usr/local/bin/*
Now you can build it and push it to your Docker Hub account. Replace the your-dockerhub-user
with your username on Docker Hub.
$ docker build . -t your-dockerhub-user/arm32-openvpn-client
$ docker push your-dockerhub-user/arm32-openvpn-client
There are other ways to deploy an image to the board. To learn more, read our article Deploying Container Images to Torizon OS.
OpenVPN Client Configuration on Torizon OS
We will use a docker volume as storage for the OpenVPN client container, so we need to create one:
docker volume create --name ovpn-client-data
Now we will copy the torizon-cert.ovpn
into this ovpn-client-data
volume
sudo cp /home/torizon/torizon-cert.ovpn /var/lib/docker/volumes/ovpn-client-data/_data
Then we will launch the OpenVPN Client indicating it to use the certification file we provided. Replace the your-dockerhub-user
with your username on Docker Hub.
docker run -d -v ovpn-client-data:/etc/openvpn --cap-add NET_ADMIN --net=host --name ovpn-client your-dockerhub-user/arm32-openvpn-client ovpn_client_run --config /etc/openvpn/torizon-cert.ovpn
As you can notice from the command above, the flag --cap-add NET_ADMIN
has been used. Additionally, we have use the --net=host
option to allow networking changes made inside the container to affect the host OS networking environment. If you want to learn more about container capabilities, have a look at our article Torizon Best Practices Guide.
You can learn more about running containers in our article Run and Manage Containers with Portainer and the Command-line on Torizon.
Setup on the Smartphone
- Install an OpenVPN Client on your phone (e.g.: for Android users, you can use the OpenVPN Client from Google Play)
- From the app, import the phone-cert.ovpn file to create a connection setup.
- Connect to your OpenVPN server
To test the OpenVPN connection over the internet, you can use your mobile data network.
This ends the OpenVPN chapter. Now we will test the VNC remote access through a VPN connection.
VNC Setup on Torizon OS
Follow the article How to Enable the VNC Backend to enable Weston’s VNC.
VNC Setup on the Smartphone
- Install a VNC capable app (e.g.: for Android users, you can use the Remote Desktop Manager)
- Set up a new connection to your module's IP. Make sure to use the IP given by the VPN connection. To get your module VPN's IP you have some alternatives:
- Use
ssh
to access the module and executeip -4 a
. Your module VPN's IP will be that one from thetun0
network interface (192.168.255.10
, in the example below)
# ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: ethernet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 192.168.0.160/24 brd 192.168.0.255 scope global noprefixroute ethernet0
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
5: br-d183fbdfe20a: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-d183fbdfe20a
valid_lft forever preferred_lft forever
8: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
inet 192.168.255.10 peer 192.168.255.9/32 scope global tun0
valid_lft forever preferred_lft forever
- Use the OpenVPN Server container on the computer to retrieve the client's IP. In this example, the
torizon
client has VPN IP192.168.255.10
and thephone
client has VPN IP192.168.255.6
.
$ docker exec ovpn-server ovpn_status
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
torizon,192.168.0.160:40746,178695395,5307706,Wed Mar 3 18:38:20 2021
phone,186.246.0.186:7845,15837,24451,Wed Mar 3 23:02:06 2021
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
192.168.255.6,phone,186.246.0.186:7845,Wed Mar 3 23:02:10 2021
192.168.255.10,torizon,192.168.0.160:40746,Wed Mar 3 23:01:35 2021
GLOBAL STATS
Max bcast/mcast queue length,0
END
- Now you can try to open your VNC connection from the smartphone to the module and control the mouse pointer (and also type) from the smartphone's touch screen.