Step-by-Step: Create Your Own VPN Server

YolandiYolandi
9 min read

Follow Steps 1-4 to deploy an OpenVPN server on a VPS (Virtual Private Server).
If you want to mask VPN traffic as regular HTTPS traffic, follow additional Steps 5-6.

Here is a concise guide for deploying an OpenVPN server. Assume you have purchased a VPS running Debian OS, and you have the root user password and public IP (e.g., 89.123.123.123) for SSH connections to your VPS.

VPS minimum specifications:

  • RAM: 2 GB

  • Disk Drive: 40 GB

  • CPU: 2 cores

  • 1 public IP address with an Internet connection speed of at least 250 Mbps.


STEP 1 - Initial VPS configuration: Setting Up Your Server for Success

Connect to your VPS using SSH:
ssh root@89.123.123.123

We are going to use the openvpn package for VPN server deployment, which requires a virtual network adapter TUN/TAP on your VPS.
Let's check if TUN/TAP is enabled by running:
cat /dev/net/tun
Here is output interpretation:

  • cat: /dev/net/tun: File descriptor in bad state - means TUN/TAP is enabled and we can continue server configuring;

  • сat: /dev/net/tun: No such file or directory - TUN/TAP adapter is disabled, you have to contact your VPS provider for technical support.

1.1 - Change root password specified by VPS provider

Change the root password:
passwd root
Type in a strong password.

1.2 - Create new user

Create a new user (for example, maria) for secure management purposes:
adduser maria
Add maria to the sudo group:
usermod -aG sudo maria

1.3 - Update OS and install essential applications

Update the package list of the OS:
apt update
Upgrade the OS:
apt upgrade

Install some essential applications for future needs:
apt install speedtest-cli curl nano net-tools

1.4 - Disable IPv6 interfaces for enhanced security

Check network interfaces to see if IPv6 (inet6) is enabled:
ip addr
If IPv6 support is enabled and you don't have any specific reasons for using this protocol, it's recommended to disable it for security reasons. IPv6 can introduce additional attack vectors that are not present in IPv4.
Let's edit the sysctl.conf configuration file to disable IPv6 support.
Open sysctl.conf:
nano /etc/sysctl.conf
Add the following lines at the bottom of the file and save the changes:

# disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Apply the changes for IPv6:
sysctl -p
Now you can check if IPv6 is disabled:
ip addr
Now you should not see any ipv6 interfaces in the output if you've successfully completed previous steps.

1.5 - Hardening SSH connections for better protection

Let's edit the SSH configuration file to improve the protection level for SSH connections.
Open it with nano /etc/ssh/sshd_config and:

  • change default SSH port 22 to any port you choose in the range 1024-49151. For example you've chosen 4444 port, so you have to find appropriate entry and write down this number:
    Port 4444

  • prohibit the use of the root account for SSH connections to the VPS. You have to find appropriate entry and write down:
    PermitRootLogin no
    Make sure all the entries you have edited are active, i.e., there are no comment symbols # at the beginning of these lines.
    Save changes and exit file.

Restart sshd service to apply changes for SSH configuration:
systemctl restart sshd
You can check if service is running correctly and using port 4444 which you've specified earlier:
systemctl status sshd

From now on, you can access your VPS using this command:
ssh -p 4444 maria@89.123.123.123

STEP 2 - Install and configure OpenVPN on Your VPS

Use the automation script published by angristan on GitHub:
https://github.com/angristan/openvpn-install

Download script onto your VPS:
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh

Make the script executable:
chmod +xopenvpn-install.sh

Launch the script:
./openvpn-install.sh
You will be asked some questions during the script execution:

  1. Check if the server IP is specified correctly. If it's correct, press Enter

  2. Do you want to enable IPv6 support? - n

  3. What port do you want OpenVPN to listen to? - Choose option 3, which means "random [49152-65535]". You'll get a random port in the output, for example, 6138.

  4. What protocol do you want OpenVPN to use? - Choose option 2, which means 'TCP'. Choosing TCP is mandatory if you are going to use stunnel in the future for disguising VPN traffic as SSL traffic.

  5. What DNS resolvers do you want to use with the VPN? - Choose the one which is closer to your VPS, for example, option 11 - AdGuard DNS (Anycast: worldwide)

  6. Do you want to use compression? - n

  7. Further, you can choose the default (client.ovpn) or a custom name for your VPN client configuration file, and you can choose the option to protect this file with a password.
    When the script running is finished, you'll find VPN client configuration file in the /root

Now you can download this VPN client configuration file onto your computer or phone. You need to install openvpn client on your device and point out this file to it.

You cannot use the same configuration file simultaneously with different devices. So if you need simultaneous VPN connections with different devices, you have to generate configuration files for each VPN user.

STEP 3 - Configure OpenVPN on Your Client Machine (OS Manjaro)

Use SFTP to download configuration file.
Open SFTP connection:
sftp -P 4444 root@89.123.123.123
Then download client.ovpn to your home directory:
get client.ovpn /home/alex
Close SFTP session:
exit

Use pacman packet manager to install openvpn package on your computer.

Now you can enable VPN connection using terminal:
sudo openvpn --config client.ovpn
If you see "Initialization Sequence Completed" in the output then it's ok, your traffic is protected by VPN. You can check it by getting your IP on public web service like WhatIsMyIP, whoer.net and so on. You'll see your VPS public IP.

It is not obligatory to use terminal for activating VPN connection. You can use GUI if you import VPN configuration file in "System settings" and add static key for this VPN connection.

You can configure activating VPN in automatic mode and specify different VPN servers for certain connections. For example you may activate VPN connection to Canadian VPS if you use WiFi, and you may activate connection to Japanise VPS if you're wire connected.

STEP 4 - Set Up Firewall Rules on Your VPS

Due to security reasons it's recommended to allow only necessary connections to your VPS.

Download ufw package onto VPS for managing linux firewall:
apt install ufw

The ufw (Uncomplicated Firewall) is a frontend for managing firewall rules in Linux. It is recommended for its simplicity and ease of use.

It is crucially important to allow the SSH port you specified earlier (see Step 1.5). If you haven't allowed it before activating ufw, you'll lose the ability to open SSH connections to your VPS!!! So nobody will help you, and you'll have to deploy your server from the very beginning.
Let's allow connections on port 4444 for example:
ufw allow 4444

Now we need to allow connections on the TCP port which was randomly chosen during the openvpn configuration (see Step 2, script question №3):
ufw allow 61318/tcp

Start ufw service and make it enabled on system startup:
ufw enable

You can check firewall rules which have been set earlier:
ufw status

STEP 5 - Configure stunnel on Your VPS

The stunnel program is used to create secure tunnels for network connections, effectively disguising VPN traffic as HTTPS traffic.

You may not need to use stunnel if your internet provider doesn't block OpenVPN traffic.
But if you are not so lucky, stunnel is the solution. It disguises VPN traffic as SSL traffic.

Install stunnel:
apt install stunnel4

5.1 - Create configuration file for stunnel on VPS

Create configuration file for stunnel:
nano /etc/stunnel/stunnel.conf
This is template for data in configuration file:

cert = /etc/stunnel/stunnel.pem
options = NO_SSLv2
[<openvpn>]
client = no
accept = "public IP address for VPS":"port for stunnel"
connect = localhost:"port for openvpn service"

For example, let's write down the data as follows:

cert = /etc/stunnel/stunnel.pem
options = NO_SSLv2
[<openvpn>]
client = no
accept = 443
connect = localhost:61318

Pay attention to the value of the accept parameter - 443. We haven't explicitly specified the public IP address for the VPS because stunnel will find out this information by itself. We have chosen port 443 because we are going to disguise OpenVPN traffic as HTTPS traffic.

Port 61318 is the port which was specified during the OpenVPN configuration.(see Step 2, script question №3). In this example we use port 61318 for the openvpn service. If you've forgotten the port number for the openvpn service, you can find it in client.ovpn file.

5.2 - Set up firewall rule for stunnel

Now you need to allow connections on port 443:
ufw allow 443
You can check if all the necessary rules have been set (pay attention to ports for SSH, stunnel, OpenVPN):
ufw status numbered

5.3 - Create SSL certificate for VPS

Create server-side certificate for stunnel:

cd /etc/stunnel/
openssl genrsa -out key.pem 4096
openssl req -new -x509 -key key.pem -out cert.pem
cat key.pem cert.pem >> stunnel.pem
rm key.pem cert.pem

5.4 - Start stunnel

Start stunnel service on VPS:
systemctl start stunnel4
Check if the service is running:
systemctl status stunnel4

STEP 6 - Configure stunnel on client machine (OS Manjaro)

6.1 - Download certificate

Use SFTP to download the certificate.
Open SFTP connection:
sftp -P 4444 root@89.123.123.123
Then download the certificate to your home directory:
get /etc/stunnel/stunnel.pem /home/alex
Close SFTP session:
exit

6.2 - Install stunnel

You need stunnel to be installed both on the VPS and the client device.
Use pacman packet manager to install stunnel package on your computer.

6.3 - Create configuration file for stunnel on client device

Create configuration file for stunnel:
sudo nano /etc/stunnel/stunnel.conf
This is template for data in configuration file:

cert = /etc/stunnel/stunnel.pem
options = NO_SSLv2
[<openvpn>]
client = yes
accept = localhost:"port for openvpn service"
connect = "public IP address for VPS":"port for stunnel"

For example, let's write down the data as follows:

cert = /etc/stunnel/stunnel.pem
options = NO_SSLv2
[<openvpn>]
client = yes
accept = localhost:61318
connect = 89.123.123.123:443

6.4 - Start stunnel on client device

Copy the certificate .pem to the stunnel directory:
sudo cp stunnel.pem /etc/stunnel
Check if it has been copied:
ls /etc/stunnel

Start stunnel service:
sudo systemctl start stunnel
Check if the service is running:
sudo systemctl status stunnel

The stunnel service may not start if you have been using an OpenVPN connection before the stunnel configuration. In this case, you have to disconnect the VPN connection and restart the NetworkManager service. Then you can try to start stunnel again.

You can check with etherape if stunnel is doing its job, i.e., masking VPN traffic as HTTPS traffic. etherape is a network monitor with a GUI. Use it to compare traffic before and after starting stunnel.


Conclusion

Deploying your own VPN server can significantly enhance your online privacy and security. By following the steps outlined in this guide, you can set up an OpenVPN server on a VPS, ensuring that your internet traffic is encrypted and protected. Additionally, configuring stunnel to mask VPN traffic as HTTPS can help you bypass network restrictions and avoid detection. With the proper setup and configuration, you can enjoy a secure and private internet experience, tailored to your specific needs.

0
Subscribe to my newsletter

Read articles from Yolandi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yolandi
Yolandi