> ## Documentation Index
> Fetch the complete documentation index at: https://help.freakhosting.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Set Up an OpenVPN Server on Linux

> Set up an OpenVPN server on Ubuntu, Debian, AlmaLinux or Rocky: build certificates with Easy-RSA, write server.conf, enable NAT and connect with a .ovpn file.

To set up an OpenVPN server on Linux, install `openvpn` and `easy-rsa`, build a certificate authority and server and client certificates, put `server.conf` in `/etc/openvpn/server/`, enable IP forwarding and NAT, open port 1194/UDP, then start it with `sudo systemctl enable --now openvpn-server@server`. Each device connects with its own `.ovpn` file.

| Difficulty | Time | Works on | Needs |
| - | - | - | - |
| Intermediate | 30–45 minutes | Ubuntu 22.04 / 24.04, Debian 12 / 13, AlmaLinux / Rocky 9 / 10 | Root or sudo access, a VPS or dedicated server |

## Before you start

* **A VPN** (virtual private network) sends a device's traffic through an encrypted tunnel to your server. OpenVPN does this with TLS certificates.
* Commands use `sudo`; root users can leave it out. Examples use the server IP `203.0.113.10` and a client called `alex`.
* **Keep a second SSH session open** while you change the firewall. If you lose access, use the [VNC console](https://help.freakhosting.com/portals/vps-panel/how-to-enable-and-use-vnc-console-access.md).
* **Find your public network interface.** Run `ip route show default`. The name after `dev` (for example `eth0` or `ens3`) is used in the NAT rules below.

## OpenVPN or WireGuard: which should I use?

| | OpenVPN | WireGuard |
| - | - | - |
| Setup | Certificate authority, more config | Key pairs, short config |
| Transport | UDP or TCP | UDP only |
| Built into Linux | No, a separate program | Yes, in the kernel since 5.6 |
| Best for | Networks that block UDP, existing OpenVPN clients | New setups, phones, low overhead |

For a simpler setup, see [WireGuard VPN server](https://help.freakhosting.com/portals/other/how-to-set-up-a-wireguard-vpn-server.md) or [wg-easy with a web UI](https://help.freakhosting.com/portals/other/how-to-set-up-wg-easy-wireguard-vpn.md).

## Step 1: Install OpenVPN and Easy-RSA

> [tab] Ubuntu / Debian
>
> ```bash theme={null}
> sudo apt update
> sudo apt install -y openvpn easy-rsa
> make-cadir ~/openvpn-ca
> cd ~/openvpn-ca
> ```

> [tab] AlmaLinux / Rocky
>
> OpenVPN and Easy-RSA come from the EPEL repository:
>
> ```bash theme={null}
> sudo dnf install -y epel-release
> sudo dnf install -y openvpn easy-rsa
> mkdir ~/openvpn-ca
> cd ~/openvpn-ca
> ln -s /usr/share/easy-rsa/3/* .
> ```

## Step 2: Build the certificates

Easy-RSA manages a small certificate authority (CA) that signs the server and client certificates. Run these in `~/openvpn-ca`:

```bash theme={null}
./easyrsa init-pki
./easyrsa build-ca
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-req alex nopass
./easyrsa sign-req client alex
openvpn --genkey secret tc.key
```

`build-ca` asks for a CA passphrase and a name. Each `sign-req` asks you to type `yes` and enter the CA passphrase. `tc.key` is a shared key for `tls-crypt`, which encrypts and authenticates OpenVPN's control channel. That hides the certificates and makes OpenVPN traffic harder to identify.

> [!WARNING]
>
> `pki/private/ca.key` can sign new client certificates. Keep the CA passphrase safe and never copy `ca.key` to a client.

## Step 3: Write the server configuration

Copy the server files into the directory the `openvpn-server@` service reads:

```bash theme={null}
sudo cp pki/ca.crt pki/issued/server.crt pki/private/server.key tc.key /etc/openvpn/server/
```

Create `/etc/openvpn/server/server.conf`:

```ini theme={null}
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh none
tls-crypt tc.key
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 198.51.100.53"
keepalive 10 120
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
verb 3
explicit-exit-notify 1
```

This is the official sample `server.conf` with three changes: `dh none` uses ECDH key exchange so you don't need a Diffie-Hellman file ([OpenVPN manual](https://openvpn.net/community-resources/reference-manual-for-openvpn-2-6/)), `tls-crypt` adds the shared key, and the two `push` lines send all client traffic and DNS lookups through the VPN. Replace `198.51.100.53` with the DNS resolver you want clients to use. Clients get addresses from `10.8.0.0/24`.

Make sure the log directory exists with `sudo mkdir -p /var/log/openvpn`.

## Step 4: Turn on IP forwarding

Forwarding lets the server pass VPN traffic on to the internet:

```bash theme={null}
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl --system
```

## Step 5: Open the port and add NAT

NAT (masquerading) rewrites VPN client addresses to the server's public IP.

> [tab] Ubuntu / Debian (UFW)
>
> Add this block to the end of `/etc/ufw/before.rules`, after the `COMMIT` of the `*filter` section, with your interface name in place of `eth0`:
>
> ```text theme={null}
> *nat
> :POSTROUTING ACCEPT [0:0]
> -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
> COMMIT
> ```
>
> Then allow the VPN port and forwarded traffic, and reload:
>
> ```bash theme={null}
> sudo ufw allow OpenSSH
> sudo ufw allow 1194/udp
> sudo ufw route allow in on tun0 out on eth0 from 10.8.0.0/24
> sudo ufw reload
> ```
>
> This follows the masquerading example in the [ufw-framework manual](https://manpages.ubuntu.com/manpages/noble/man8/ufw-framework.8.html). See [set up a firewall with UFW](https://help.freakhosting.com/portals/other/how-to-set-up-a-firewall-with-ufw.md).

> [tab] AlmaLinux / Rocky (firewalld)
>
> ```bash theme={null}
> sudo firewall-cmd --permanent --add-service=openvpn
> sudo firewall-cmd --permanent --add-masquerade
> sudo firewall-cmd --reload
> ```
>
> The `openvpn` service opens 1194/UDP. See [set up a firewall with firewalld](https://help.freakhosting.com/portals/other/how-to-set-up-a-firewall-with-firewalld.md).

For raw `iptables` or `nftables` rules, see [port forwarding and NAT with iptables](https://help.freakhosting.com/portals/other/how-to-set-up-port-forwarding-and-nat-with-iptables.md).

## Step 6: Start the OpenVPN server

```bash theme={null}
sudo systemctl enable --now openvpn-server@server
```

The `openvpn-server@` unit reads `/etc/openvpn/server/<name>.conf`, so `@server` loads `server.conf`. Older guides use `openvpn@server` with files in `/etc/openvpn/`. Both work, but don't mix them.

## Step 7: Create the client .ovpn file

A `.ovpn` file holds the client settings plus the certificates in one file. Run this in `~/openvpn-ca`, with your server IP in `remote`:

```bash theme={null}
cat > alex.ovpn <<EOF
client
dev tun
proto udp
remote 203.0.113.10 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verb 3
<ca>
$(cat pki/ca.crt)
</ca>
<cert>
$(openssl x509 -in pki/issued/alex.crt)
</cert>
<key>
$(cat pki/private/alex.key)
</key>
<tls-crypt>
$(cat tc.key)
</tls-crypt>
EOF
```

Download it with [scp or rsync](https://help.freakhosting.com/portals/other/how-to-copy-files-with-scp-and-rsync.md), then delete it from the server. Import it into [OpenVPN Connect](https://openvpn.net/client/) or the community OpenVPN client. On a Linux client, run `sudo openvpn --config alex.ovpn`.

> [!WARNING]
>
> The `.ovpn` file contains the client's private key. Anyone with it can connect, so send it only over SSH or another encrypted channel.

## How to check it worked

On the server:

```bash theme={null}
sudo systemctl status openvpn-server@server --no-pager
ip -4 addr show tun0
```

The service shows `active (running)` and `tun0` has `inet 10.8.0.1/24`. When a client connects, its log ends with `Initialization Sequence Completed`, and `sudo journalctl -u openvpn-server@server` shows `[alex] Peer Connection Initiated`. Your public IP on the client now shows as `203.0.113.10`.

## Frequently asked questions

### How do I add another client?

Run `./easyrsa gen-req name nopass` and `./easyrsa sign-req client name` in `~/openvpn-ca`, then build a new `.ovpn` file with that name. Give every device its own certificate.

### How do I revoke a client?

Run `./easyrsa revoke alex` and `./easyrsa gen-crl`, copy `pki/crl.pem` to `/etc/openvpn/server/`, add `crl-verify crl.pem` to `server.conf` and restart the service. Easy-RSA's CRL is valid for 180 days by default, so re-run `gen-crl` and copy it again before then.

### Why does the VPN connect but the internet doesn't work?

Forwarding or NAT is missing. Check `sysctl net.ipv4.ip_forward` returns `1`, that the NAT rule uses your real interface name, and that the client's DNS server is reachable.

### Can OpenVPN run on TCP port 443?

Yes. Set `proto tcp` and `port 443` on the server and in the client file, open 443/TCP instead of 1194/UDP, and remove `explicit-exit-notify`, which is a UDP option. Port 443 must not be used by a web server on the same IP.

## Related guides

> [card] [VPS and dedicated server guides](https://help.freakhosting.com/portals/other/vps-and-dedicated-server-guides.md)
>
> Every guide in this section.

> [card] [WireGuard VPN server](https://help.freakhosting.com/portals/other/how-to-set-up-a-wireguard-vpn-server.md)
>
> A faster, simpler VPN.

> [card] [wg-easy WireGuard VPN](https://help.freakhosting.com/portals/other/how-to-set-up-wg-easy-wireguard-vpn.md)
>
> WireGuard with a web UI.

> [card] [Port forwarding and NAT](https://help.freakhosting.com/portals/other/how-to-set-up-port-forwarding-and-nat-with-iptables.md)
>
> iptables NAT rules explained.

> [card] [Set up a firewall with UFW](https://help.freakhosting.com/portals/other/how-to-set-up-a-firewall-with-ufw.md)
>
> Open only the ports you use.

> [card] [Set up a firewall with firewalld](https://help.freakhosting.com/portals/other/how-to-set-up-a-firewall-with-firewalld.md)
>
> Zones and services on AlmaLinux and Rocky.

***

> [!NOTE]
>
> **Checked against the official [OpenVPN 2.6 reference manual](https://openvpn.net/community-resources/reference-manual-for-openvpn-2-6/), the [Ubuntu Server OpenVPN guide](https://documentation.ubuntu.com/server/how-to/security/install-openvpn/) and the [Rocky Linux OpenVPN guide](https://docs.rockylinux.org/guides/security/openvpn/)** on 5 November 2026; certificates, server and client configuration tested with OpenVPN 2.6 on Ubuntu 24.04 LTS. Commands can differ on other distributions or releases.

> [!NOTE]
>
> ### Need Extra Help?
>
> If you encounter any issues, our support team is ready to assist:
>
> * **Live Chat:** Quick assistance via our website.
> * **Support Ticket:** [Open a Ticket](https://freakhosting.com/clientarea/submitticket.php)
> * **Discord:** [Join our Community](https://discord.gg/freakhosting)
> * **Email:** [support@freakhosting.com](mailto:support@freakhosting.com)

> [!TIP]
>
> ### Save on Your Hosting
>
> Ready to upgrade your hosting? Use code **KB20** at checkout for **20% off** your first order!

***

**Last Updated:** November 2026


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.