Search by Tags

OpenVPN + Weston's VNC/RDP on TorizonCore

 

Article updated at 13 Apr 2021
Subscribe for this article updates

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.

TorizonCore 5.0.0

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 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.

Prerequisites

  • 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

Instructions

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 1


  • Figure 2

    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.

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.

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.

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:

  • Starting OpenVPN Server with IP 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
  • 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, ...
$ ./start-docker-ovpn-server.sh client-name-1 client-name-2 client-name-3
  • Starting OpenVPN Server with name server-ip and default port 1194 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.

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.

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

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)

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 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.

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 --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. 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

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.

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 (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
  1. Use the OpenVPN Server container on the computer to retrieve the client's IP. In this example, the 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 
  • 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.