Select the version of your OS from the tabs below. If you don't know the version you are using, run the command cat /etc/os-release
or cat /etc/issue
on the board.
Remember that you can always refer to the Torizon Documentation, there you can find a lot of relevant articles that might help you in the application development.
In this article, we explain how to use OpenVPN and Weston's VNC to make it possible to remotely access the graphical interface on TorizonCore.
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.
Note: Please keep in mind that TorizonCore comes with the WireGuard VPN enabled out-of-the-box, maintained by the TorizonCore team; therefore, it is our recommended solution. Learn more about it on How to Use VPN on TorizonCore.
We will setup two devices (clients) a module with TorizonCore 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 TorizonCore 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:
Here we will focus on VNC for Weston, but for RDP the steps for OpenVPN are still valid.
Note: 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.
The setup of the OpenVPN server on your computer comprehends:
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".
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.
Note: 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.
Warning: 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:
192.168.0.33
(a local IP address) and default port 1194
and client-name-1
, client-name-2
, client-name-3
, ... with certificates client-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
1194
and client-name-1
, client-name-2
, client-name-3
, ... with certificates client-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
server-ip
and default port 1194
and no clients$ ./start-docker-ovpn-server.sh server-ip
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.
Note: 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.
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
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
Warning: 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)
We need to configure and run the OpenVPN Client and also enable Weston’s VNC.
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 TorizonCore.
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.
Note: 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.
Follow the article How to Enable the VNC Backend to enable Weston’s VNC.
ssh
to access the module and execute ip -4 a
. Your module VPN's IP will be that one from the tun0
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
torizon
client has VPN IP 192.168.255.10
and the phone
client has VPN IP 192.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