Anasayfa / Cyber Security / How to Install and Configure a VPN Server on Linux: A Step‑by‑Step Guide

How to Install and Configure a VPN Server on Linux: A Step‑by‑Step Guide

Linux VPN server

Running your own VPN server gives you full control over your traffic, keeps your data private, and lets you bypass geo‑restrictions. If you’re comfortable with the Linux command line but haven’t set up a VPN before, this guide will walk you through installing and configuring OpenVPN on a fresh Ubuntu 24.04 LTS server. We’ll cover every step—from installing packages to generating client configs—while pointing out common mistakes and sharing handy tips to keep the process smooth.

What You’ll Need

  • A clean Ubuntu 24.04 LTS server (or any Debian‑based distro) with root or sudo access.
  • Basic knowledge of SSH, package management, and firewall configuration.
  • An external IP address or a dynamic DNS hostname if your ISP changes your IP.
  • Enough disk space (a few GB) for keys and certificates.
  • Optional: A client device (Windows, macOS, Android, iOS) to test the VPN later.

Step 1: Update Your System and Install Dependencies

Before diving into OpenVPN, make sure your system is up to date and install the required packages. Open a terminal and run:

sudo apt update && sudo apt upgrade -y
sudo apt install openvpn easy-rsa ufw -y

The easy-rsa package will help us generate a Public Key Infrastructure (PKI) for the VPN, while ufw will manage our firewall rules.

Step 2: Set Up the Public Key Infrastructure

Create a working directory for EasyRSA and copy the template files:

make-cadir ~/openvpn-ca
cd ~/openvpn-ca
cp vars.example vars

Edit the vars file to set your organization details. Open it in your favorite editor:

nano vars

Change the following lines to match your environment:

export KEY_COUNTRY=”US”
export KEY_PROVINCE=”CA”
export KEY_CITY=”SanFrancisco”
export KEY_ORG=”MyOrg”
export KEY_EMAIL=”[email protected]”
export KEY_OU=”IT”

Once you’re done, source the file and build the CA:

source vars
./clean-all
./build-ca –batch

After the CA is created, generate the server certificate and key:

./build-key-server –batch server
./build-dh
openvpn –genkey –secret keys/ta.key

These commands will create server.crt, server.key, ca.crt, dh2048.pem, and a TLS‑Auth key ta.key in the keys folder.

Step 3: Configure the OpenVPN Server

Create a new server configuration file:

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz
sudo nano /etc/openvpn/server.conf

Make the following adjustments:

  • Set ca, cert, key, and dh paths to point to the files we just created. For example:
  • ca /etc/openvpn/ca.crt
  • cert /etc/openvpn/server.crt
  • key /etc/openvpn/server.key
  • dh /etc/openvpn/dh2048.pem
  • Enable TLS‑Auth:
  • tls-auth ta.key 0
  • Set the subnet for VPN clients:
  • server 10.8.0.0 255.255.255.0
  • Enable client‑to‑client communication if you want peers to talk to each other:
  • client-to-client
  • Push routes to clients for internet access:
  • push "redirect-gateway def1 bypass-dhcp"
    push "dhcp-option DNS 8.8.8.8"
    push "dhcp-option DNS 8.8.4.4"
  • Ensure the following lines are uncommented to allow IP forwarding:
  • push "route-gateway 10.8.0.1"
  • At the end of the file, add:
  • user nobody
    group nogroup

After saving the file, copy the key files into /etc/openvpn:

sudo cp ~/openvpn-ca/keys/ca.crt /etc/openvpn/
sudo cp ~/openvpn-ca/keys/server.crt /etc/openvpn/
sudo cp ~/openvpn-ca/keys/server.key /etc/openvpn/
sudo cp ~/openvpn-ca/keys/dh2048.pem /etc/openvpn/
sudo cp ~/openvpn-ca/keys/ta.key /etc/openvpn/

Step 4: Enable IP Forwarding

Open /etc/sysctl.conf and ensure the following line is present and uncommented:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

Apply the changes:

sudo sysctl -p

Step 5: Configure the Firewall

Allow OpenVPN traffic and enable NAT for the VPN subnet:

sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
sudo ufw enable

Now add a masquerade rule to the /etc/ufw/before.rules file. Open it:

sudo nano /etc/ufw/before.rules

Add these lines before the *filter section:

# OpenVPN NAT rule
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT

Replace eth0 with your actual external interface name (use ip link show to find it). Save and close the file, then reload UFW:

sudo ufw disable
sudo ufw enable

Step 6: Start and Enable OpenVPN Service

Start the service and enable it to start on boot:

sudo systemctl start openvpn@server
sudo systemctl enable openvpn@server

Check the status to confirm:

sudo systemctl status openvpn@server

You should see “active (running)” if everything is working.

Step 7: Generate Client Configuration

On the server, build a client certificate:

cd ~/openvpn-ca
source vars
./build-key –batch client1

Create a client config template:

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/client1.ovpn

Edit client1.ovpn to include the following directives:

  • remote YOUR_SERVER_IP 1194 – replace with your public IP or DNS name.
  • proto udp
  • dev tun
  • resolv-retry infinite
  • nobind
  • persist-key
  • persist-tun
  • remote-cert-tls server
  • cipher AES-256-CBC
  • auth SHA256
  • key-direction 1
  • Include the CA, client cert, key, and TLS‑Auth key inline:
  • <ca> … </ca>
  • <cert> … </cert>
  • <key> … </key>
  • <tls-auth> … </tls-auth>

To embed the certificates, run:

sed -n ‘//, //p’ /etc/openvpn/ca.crt | sed ‘s/^/ /’ >> client1.ovpn
sed -n ‘//, //p’ /etc/openvpn/server.crt | sed ‘s/^/ /’ >> client1.ovpn
sed -n ‘//, //p’ /etc/openvpn/server.key | sed ‘s/^/ /’ >> client1.ovpn
sed -n ‘//, //p’ /etc/openvpn/ta.key | sed ‘s/^/ /’ >> client1.ovpn

Now transfer client1.ovpn to your client device and import it into the OpenVPN app.

Common Mistakes to Avoid

1. Forgot to enable IP forwarding – Without this, clients can connect but cannot reach the internet.

2. Using the wrong network interface in the UFW NAT rule – Double‑check eth0 vs ens3 or enp0s3 etc.

3. Leaving the client-to-client directive commented out when needed – Some users want peers to talk; if you want that, uncomment it.

4. Mis‑typing the TLS‑Auth key direction – Server must use 0 and client 1.

5. Using outdated cipher settings – Modern OpenVPN defaults to strong ciphers; keep cipher AES-256-CBC and auth SHA256 unless you have a specific requirement.

Tips and Tricks

• Use a dynamic DNS service if your ISP frequently changes your IP. Services like DuckDNS or No-IP provide free subdomains that you can update automatically.

• Automate client config generation by scripting the sed commands. This saves time when you add multiple clients.

• Monitor traffic with tcpdump or iftop

• Consider using WireGuard for simpler setup and higher performance. The steps above are for OpenVPN, but WireGuard’s wg-quick tool makes it almost trivial.

Frequently Asked Questions

How do I add more clients after the server is up?

Run ./build-key --batch client2 in the EasyRSA directory, then create a new client2.ovpn file following the same embedding steps. Transfer the file to the client device.

Can I use a static IP for clients instead of DHCP?

Yes. Add ifconfig-push 10.8.0.10 255.255.255.0 to the server config under a client block that matches the client’s common name. This forces that client to receive the specified IP.

Why am I getting a “TLS Error: TLS handshake failed” on the client?

Common causes: mismatched ca.crt or ta.key, wrong server IP, or firewall blocking UDP 1194. Verify the certificates are embedded correctly and that the UFW rule allows UDP 1194.

Conclusion

Setting up a Linux VPN server is surprisingly straightforward once you understand the key components: a PKI, a server configuration, and proper firewall rules. With OpenVPN, you get a battle‑tested, widely supported solution that works on nearly every platform. Follow the steps above, watch out for the common pitfalls, and you’ll have a secure tunnel to your network in under an hour. Happy hacking—just remember to keep your keys safe and your server updated!

Photo by Albert Stoynov on Unsplash

Etiketlendi: