Skip to main content
Version: 5.0

OpenVPN and Weston's VNC/RDP on TorizonCore


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.


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.


  • A smartphone capable of using VPN (e.g. installing a VPN application via application market).
  • Computer on Module with TorizonCore installed.
  • Basic knowledge about computer networking.
  • A computer with


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.

Figure 1

Figure 2

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:

  • 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 from the torizon-samples GitHub repository.


The 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:

./ [server-name] [client-name1 [client-name2 [client-name3 [...]]]]


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 (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, ...
$ ./ client-name-1 client-name-2 client-name-3
  • Starting OpenVPN Server with your current public IP 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, ...
$ ./ client-name-1 client-name-2 client-name-3
  • Starting OpenVPN Server with name server-ip and default port 1194 and no clients
$ ./ server-ip
  • Starting OpenVPN Server with your current public IP and default port 1194 and no clients
$ ./

This will create all the issued certificates as well, as displayed by the end of the script, e.g.:

OpenVPN Server created on for clients:

Client Name | Certificate
module | /home/grilo/module-cert.ovpn
phone | /home/grilo/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 TorizonCore

We need to configure and run the OpenVPN Client and also enable Weston’s VNC.

Preparing OpenVPN Client for TorizonCore

First, clone the repository leibaogit/docker-openvpn-client

$ git clone

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


RUN echo "" >> /etc/apk/repositories && \
echo "" >> /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.

OpenVPN Client Configuration on 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.

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 TorizonCore

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 your alternatives:
  1. Use ssh to access the module and execute ip -4 a. Your module VPN's IP will be that one from the tun0 network interface (, in the example below)
# ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 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 brd 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 brd 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 brd 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 peer scope global tun0
valid_lft forever preferred_lft forever
  1. Use the OpenVPN Server container on the computer to retrieve the client's IP. In this example, the torizon client has VPN IP and the phone client has VPN IP
$ docker exec ovpn-server ovpn_status
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
torizon,,178695395,5307706,Wed Mar 3 18:38:20 2021
phone,,15837,24451,Wed Mar 3 23:02:06 2021
Virtual Address,Common Name,Real Address,Last Ref,phone,,Wed Mar 3 23:02:10 2021,torizon,,Wed Mar 3 23:01:35 2021
Max bcast/mcast queue length,0
  • 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.
Send Feedback!