Learn Some Linux Series - AWS, OpenVPN and NoMachines - Part 2

In this part 2 of 3 part series, we are going to install OpenVPN Server using PiVPN on our AWS lightsail based virtual machine (also called VM or Instance).

We SSH into our instance using its public IP (and port 55222 if you did change port as in Part 1) and then follow the process below:

  1. There are few ways to install any software package in Linux. One could be the case for say a third party vendor (like a firewall/router manufacturer) software/firmware update package.

a) download the package as .deb (for debian/Ubuntu) using browser and then run it as command below. Note dpkg is a debian package manager that takes care of running the software installer and also taking care of downloading and installing any required dependency packages (libraries that are common use software packages that are used by many packages). Flag i here means install.

sudo dpkg -i <softwareupdate.deb>. 

b) download on a terminal using command line interface (CLI) using wget utility, a program that is meant to download (non-interactively though) software from web using not only http or https but also thru FTP (file transfer protocol). Note if you find wget not installed on your device, use, sudo apt install wget

wget http://ourvendorwebsite.com/support/downloads/softwareupdate.deb

This will download to the current working directory (pwd) and then you install using

sudo dpkg -i <softwareupdate.deb>

c) download on a terminal using command line interface (CLI) using cURL utility, O flag is for output file name/path. cURL is not only a utility to download from http using a URL, but also from many other protocols including FTP/SFTP/SCP/Telnet etc, and is also a programming language that gets the name from curly brackets. Research yourself if you need more information.

curl http://ourvendorwebsite.com/support/downloads/softwareupdate.deb -O softwareupdate.deb
sudo dpkg -i <softwareupdate.deb>

d) download a script on a terminal using command line interface (CLI) using cURL utility, which then executes into bash directly and downloads the full package and installs it. This type of install is called a pipe installer, wherein curl downloads and then pipes that into bash to execute it. So we should only do it for trusted URLs (hopefully the site below is never compromised). And this initial page in the URL may need to go to other pages as specified in the script, so a L flag is used called -location to follow the redirects to other pages.

curl -L https://install.pivpn.io | bash

and here since we are going to directly install the software thru automatic script execution, we will run it as a superuser (sudo su , where sudo means do as a superuser does, so giving us privilege of root, and specifying su after that indicates that superuser here is the root itself). Note in our ubunbtu VM, we don’t have root password set, so as long as our ubuntu username is a sudoer (which is the case here for the first user account that is created in VM), we wont be asked for any password for root.

So we will actually use the following commands to install our pivpn server

sudo su
curl -L https://install.pivpn.io | bash

Or should simply a single command, where we should be asked for ubuntu account password

curl -L https://install.pivpn.io | sudo bash

There is some confusion on use of sudo su and why not sudo -s as per separate discussion with @MichaIng but I think I may come back to do a separate tutorial on proper use of sudo. I think my reasoning of use of sudo su is elaborated in explanation above.

e) just to complete this section of methods of installation, we use following to download and install standard packages that debian / ubuntu provides us in their software download repositories (repos).

sudo apt update
sudo apt install curl
  1. After we run the curl command as explained in d) above, we will be seeing small graphical screens (non GUI but menu based colored screens, called text based UI or TUI, which is a way of using some kind of menu based interface on SSH / terminal screens and it uses a library of code available as ncurses, for new curses, which makes it simple to set up such TUI interfaces by having ncurses or curses lib to do most of work. curses comes from cursor manipulation). Please make it a point to read text on these screens to be knowledgeable, but we are simply going to accept defaults presented by pressing enter, all the way thru to the end. It will ask us to set a static IP, but will then detect that it is not a RPi and that if it is AWS, you would have pre-setup the static/elastic public IP.

Our server will have IP for its VPN tunnel interface.

After our openVPN server is installed using pivpn, we need to generate a client profile for each device (dietPi on RPi, windows machine or even iPad) with the simple commands below on the server (this can be done anytime you need to add a new device).

pivpn add nopass

This command is adding/creating a new account with certificate (a public / private key pair generation, with private key signed by server’s own root certificate). This cert is then copied (scp or sftp) from server to client, for it to then send back to server at the time of connection.

This command results into couple of questions, one is the name, which you can type in a descriptive unique name for the client, like RPi01, second is validity / duration of the cert, which can be set to a max of 10 years in terms of days. Don’t use the same profile on any other machine, else you will have IP conflicts. And if a device gets stolen, then you will need to upload new cert / account on all other devices.

This will then generate a certificate with some other required information like server’s public IP and tcp port etc. and stored as RPi.ovpn under the directory /home/Ubuntu/ovpn.

Open the file to make sure it has correct public IP (in case you installed pivpn server before you assigned static IP, it will show old IP). Edit it for correct IP if need be. In my case, I installed pivpn first and then set up static / elastic IP on AWS instance and in this case, any new cert profile file, still uses old dynamic IP of AWS instance and I need to manually edit every time. I have yet to figure out as to where is this seed public IP is coming from, so that I can update that file with correct new static Public IP. Note: See post below for permanent fix.

sudo nano /home/Ubuntu/ovpn/RPi.ovpn

For any VPN service, a virtual adaptor/NIC is created. And we will like to have static VPN IPs allocated to the clients every time for their VPN adapter. That static IP needs to be defined on server for each such client. We will find a file created for each client profile we add to server using pivpn add nopass command:

sudo nano /etc/openvpn/ccd/RPi

It will have a single line as below


change this IP to whatever you want and save it.

Now we can get to our RPi and SCP (or SFTP) download this file from our VPN server at AWS. This file needs to be placed into our client device at the directory below


Client (RPi running dietpi) side configuration and setup:

As a first step, it is good idea to update the software package lists and then apply available updates.

sudo apt update && sudo apt upgrade

The && allows us to specify multiple command lines to be processed one after the other. Note && will only process the next command, if previous command was successful. In this case, we could also simply replace && with ; which implies completion of command and then to go to next and in our case, if update fails because of some sources list issue, then we don’t care and we want to move on to do the upgrade.

We need to install pivpn client (not server) so we will not use standard method of installation using dietpi-software as that will install both server and client.

sudo apt install openvpn

That will take care of installation of our VPN client.

We will cd (change directory) into location below and then download file in there directly from our server. We can use secure copy or secure FTP to download the file from server and rename the file extension to the required .conf

cd /etc/openvpn

In the command below, note upper P flag (instead of p for ssh) and also note no space between IP, colon and server file path.

And ./ indicates local current directory, which is /etc/openvpn

If we were not changing file name, we will simply use a . (dot) for destination file location as we are right into required directory.

scp -P 55222 ubuntu@ourServerPublicIP:/home/Ubuntu/ovpn/RPi.ovpn ./RPi.conf

or we could use the sftp method (which is little slower, but if we have flaky/slow internet, then sftp will provide reliable/acknowledged data transfer and resumption of transfer if there is small interruption in internet connection. A separate discussion with @MichaIng revealed that SCP is actually been deprecated because of some security issues (not that serious though) but best practices should be to replace SCP with SFTP which is a better protocol.

sftp -P 55222 ubuntu@ourServerPublicIP:/home/Ubuntu/ovpn/RPi.ovpn ./RPi.conf

and note if we were using the same username on client and server, then we will simply do something like below for SCP or SFTP

sftpp -P 55222 ourServerPublicIP:/home/Ubuntu/ovpn/RPi.ovpn ./RPi.conf

BTW, if we were to upload a file from our local device to server in home directory of ubuntu user

scp -P 55222 ./ourlocalfile.txt ubuntu@ourServerPublicIP:/home/Ubuntu/

And if we were to download a full directory from server to local machine, note trailing / at source and destination as this will copy the contents of ubuntu (not directory ubuntu) into local directory with a new directory in there. And note -r for recursively copying all files and folders from source directory into destination location.

If we skip trailing / at source, then it will copy Ubuntu directory also with all its content.

scp -P 55222 -r ubuntu@ourServerPublicIP:/home/Ubuntu/ ./svrbak/

VPN Connection testing from our client

openvpn --config /etc/openvpn/RPi.conf &     

This is needed first time only to test and after that it will autoconnect on reboot.
The & pushes the process to background and then we can close the terminal window. And open another one, else terminal will not bring us to the prompt to do our testing and doing ctrl+C to regain the terminal prompt will cause VPN to disconnect.


or new scheme for listing IP addresses

ip address

will show that we have an IP in 10.8.0.x. And now we can ping our server at Note that ip address can also be abbreviated as ip add or ip a

Make doubly sure to copy the profile to /etc/openvpn and change its extension from ovpn to conf, and then it will autoconnect on reboot.

Restart openvpn at the client RPi or reboot

service openvpn restart

Now onward, our RPi will auto connect to VPN.

Next step in our tutorial is to install OpenVPN on our windows based machine. I have tested it on both windows 10 Pro and Windows 11 pro.

Download Windows 64-bit MSI installer from the link below:


Community Downloads | OpenVPN

Visit this page to download the latest version of the open source VPN, OpenVPN.

Install it by accepting defaults. If you need to run this as a service so that this PC always connects to the VPN, then at first screen, choose to run it as custom installation and to run it as service.

You can download the client profile created for this machine from server by either using WInSCP GUI utility or use Windows Terminal to scp following procedure explained above. Copy the new client profile (separate for each machine please) with ovpn extension (don’t change it to .conf as we did for our RPis) into the

C:\Program Files\OpenVPN\config-auto

Now you can reboot your PC and it should auto connect (may take a minute or two) and you should be able to ping the server at and any other VPN device like RPi that you may have already enabled for VPN.

If you have any Android and iPad tablet, you can download OpenVPN app and then email yourself the client profile that you can open from tablet and then associate to the app.

We will cover NoMachines setup on server and devices in Part 3 to wrap this tutorial.

1 Like

Here is the file that we need to update if we did not have correct public IP in the first place when we installed pivpn (as was my case wherein I attached static public IP afterwards). This may also be needed if you ever were to change your IP (like new ISP) unless you were using dynamicDNS (did not try if the file will actually take a DNS FQDN).

sudo nano /etc/openvpn/easy-rsa/pki/Default.txt