How To Install OpenVPN on Fedora 45

Install OpenVPN on Fedora 45

OpenVPN remains one of the most dependable ways to build a private, encrypted network path between remote users and a Fedora server. It is mature, flexible, well supported across operating systems, and straightforward enough to run on a small VPS while still scaling to a production remote-access environment.

This guide walks through installing OpenVPN on Fedora 45, creating a proper certificate authority with Easy-RSA, configuring the server, opening the necessary firewall rules, issuing client certificates, and testing the connection. It also covers SELinux, systemd, NAT, troubleshooting, and the operational details that matter once real users depend on the VPN.

The instructions assume you are setting up a road-warrior VPN: remote clients connect to a central Fedora 45 server and receive access to the internet, a private network, or both. The same foundation works for site-to-site links, though those require additional routing and firewall planning.

Prerequisites

Before touching OpenVPN, make sure the server has the basics in place.

  • A Fedora 45 server with root or sudo access
  • A public IPv4 address, or a correctly forwarded UDP port if the server sits behind NAT
  • UDP port 1194 available externally, unless you plan to use another port
  • Accurate system time, preferably maintained by chronyd or another NTP service
  • A domain name pointing to the server, which makes certificate management and client configuration easier
  • At least 512 MB RAM for a small deployment; 1 GB or more is more comfortable for multiple users

Fedora’s official OpenVPN documentation recommends installing both openvpn and easy-rsa, copying the Easy-RSA files into /etc/openvpn/easy-rsa, and keeping the CA private key off the VPN server whenever possible. [16]

A quick health check is worth doing first:

sudo dnf upgrade --refresh -y
sudo systemctl status chronyd
ip -brief address
sudo firewall-cmd --state

If chronyd is inactive, enable it:

sudo systemctl enable --now chronyd

Certificate validation depends heavily on correct time. A clock drift of even a few minutes can cause confusing TLS errors later, especially after certificates are renewed or clients reconnect from different time zones.

Install OpenVPN and Easy-RSA

Fedora ships OpenVPN and Easy-RSA in its standard repositories, so there is no need to add third-party repositories for a normal deployment.

sudo dnf install -y openvpn easy-rsa

Confirm the installed versions:

openvpn --version
rpm -q easy-rsa

You should see OpenVPN 2.x and Easy-RSA 3.x. Avoid older tutorials that reference Easy-RSA 2, build-key, or pkitool; those workflows are obsolete and can produce certificates that modern OpenVPN configurations handle poorly.

Create a dedicated working directory for the PKI:

sudo mkdir -p /etc/openvpn/easy-rsa
sudo cp -rai /usr/share/easy-rsa/3/* /etc/openvpn/easy-rsa/
cd /etc/openvpn/easy-rsa

Fedora’s wiki uses this same approach: copy Easy-RSA version 3 into /etc/openvpn/easy-rsa, edit vars, initialize the PKI, then build the CA and server certificate. [16]

Plan the Certificate Authority

This is the part people rush, and it usually causes problems later.

OpenVPN uses a public key infrastructure. The server and every client need a certificate signed by a trusted certificate authority. If someone obtains your CA private key, they can issue valid certificates for themselves. That is why the CA should be treated as sensitive infrastructure, not as just another configuration directory.

For a small personal VPN, creating the CA on the same server is acceptable if the server is properly hardened. For a business or production environment, generate the CA on a separate offline machine or a tightly controlled administrative host. The OpenVPN project explicitly recommends separating CA duties from the VPN server because compromise of the CA key undermines the entire PKI. [18]

The files matter:

File Purpose Where it belongs
ca.crt Public CA certificate Server and every client
ca.key CA private signing key Secure CA system only
server.crt Server certificate OpenVPN server
server.key Server private key OpenVPN server only
dh.pem Diffie-Hellman parameters OpenVPN server
client.crt Client certificate Individual client
client.key Client private key Individual client only

Never distribute ca.key, server.key, or a client private key through a public channel. Use SFTP, SCP, or an encrypted transfer method.

Configure Easy-RSA Variables

Copy the example variables file and edit it:

sudo cp vars.example vars
sudo nano vars

Set values appropriate for your organization. These fields appear in certificates and help identify issued credentials later.

set_var EASYRSA_REQ_COUNTRY    "ID"
set_var EASYRSA_REQ_PROVINCE   "Yogyakarta"
set_var EASYRSA_REQ_CITY       "Yogyakarta"
set_var EASYRSA_REQ_ORG        "Example Company"
set_var EASYRSA_REQ_EMAIL      "admin@example.com"
set_var EASYRSA_REQ_OU         "IT Operations"
set_var EASYRSA_KEY_SIZE       2048
set_var EASYRSA_CA_EXPIRE      3650
set_var EASYRSA_CERT_EXPIRE    825

For most deployments, RSA 2048 is still practical and compatible. If you prefer modern elliptic-curve cryptography, Easy-RSA supports EC certificates, but check client compatibility before committing to it. Mixed client environments, older mobile apps, and unusual embedded devices sometimes behave differently with EC-based PKIs.

Initialize a clean PKI:

sudo ./easyrsa init-pki

If you are rebuilding an existing PKI, stop and make a backup first. clean-all or deleting the pki directory will remove certificates that may still be in use.

Build the CA and Server Certificate

Create the certificate authority:

sudo ./easyrsa build-ca

Easy-RSA will ask for a CA passphrase. Use a strong passphrase and store it in your organization’s password manager. Do not use nopass for the CA unless you fully understand the operational tradeoff.

Next, build the server certificate and key:

sudo ./easyrsa build-server-full server nopass

The nopass option is common for servers because OpenVPN must start automatically at boot without a human entering a passphrase. The server private key is still sensitive, so restrict its permissions and ensure only the OpenVPN service can read it.

Generate Diffie-Hellman parameters:

sudo ./easyrsa gen-dh

This can take a few minutes on a small VPS. It is normal. The resulting dh.pem file is used during TLS key exchange and is not secret, but it should still be stored safely with the other server files.

Create the OpenVPN Server Directory

Fedora’s systemd integration expects server configurations under /etc/openvpn/server/. Create that directory and copy only the files the VPN server needs:

sudo mkdir -p /etc/openvpn/server
sudo cp pki/ca.crt /etc/openvpn/server/
sudo cp pki/issued/server.crt /etc/openvpn/server/
sudo cp pki/private/server.key /etc/openvpn/server/
sudo cp pki/dh.pem /etc/openvpn/server/

Set restrictive permissions:

sudo chown root:root /etc/openvpn/server/*
sudo chmod 600 /etc/openvpn/server/server.key
sudo chmod 644 /etc/openvpn/server/ca.crt \
  /etc/openvpn/server/server.crt \
  /etc/openvpn/server/dh.pem

The Fedora documentation emphasizes that the OpenVPN server only needs ca.crt, server.crt, server.key, and the DH parameters. It does not need the CA private key or the full Easy-RSA PKI. [16]

Generate a TLS Crypt Key

A TLS control-channel protection key adds another layer of defense. It helps protect against denial-of-service attempts and unauthorized packets reaching the OpenVPN process.

Generate the key:

sudo openvpn --genkey secret /etc/openvpn/server/tls-crypt.key
sudo chmod 600 /etc/openvpn/server/tls-crypt.key

This key must also be copied to every client. Unlike a certificate, it is shared between server and clients, so protect it carefully. If it leaks, rotate it and redistribute new client profiles.

tls-crypt is generally preferable to the older tls-auth approach because it encrypts as well as authenticates control-channel traffic. tls-auth still works, but there is rarely a reason to choose it for a new deployment unless compatibility requires it.

Create the OpenVPN Server Configuration

Create the main server configuration:

sudo nano /etc/openvpn/server/server.conf

A solid baseline configuration looks like this:

port 1194
proto udp
dev tun

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
tls-crypt /etc/openvpn/server/tls-crypt.key

server 10.8.0.0 255.255.255.0

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"

keepalive 10 120
remote-cert-tls client

user nobody
group nobody
persist-key
persist-tun

explicit-exit-notify 1
auth SHA256
cipher AES-256-GCM
data-ciphers AES-256-GCM:AES-128-GCM
data-ciphers-fallback AES-256-GCM

status /var/log/openvpn-status.log
log-append /var/log/openvpn.log
verb 3

A few settings deserve explanation.

proto udp is usually the best default. UDP handles packet loss more gracefully for VPN traffic and generally performs better for interactive use. Use TCP only when UDP is blocked or unreliable, such as on some restrictive corporate or hotel networks.

server 10.8.0.0 255.255.255.0 defines the virtual VPN subnet. Choose a range that does not overlap with your office LAN, home network, cloud VPC, or Docker networks. Overlapping subnets are one of the most common causes of “the VPN connects but nothing works.”

push "redirect-gateway def1 bypass-dhcp" sends all client traffic through the VPN. Remove that line if you only want clients to reach specific internal resources.

remote-cert-tls client requires client certificates to have the correct extended key usage attributes. The OpenVPN project recommends this directive for man-in-the-middle protection, especially because older Netscape certificate attributes are deprecated. [18]

data-ciphers AES-256-GCM:AES-128-GCM uses authenticated encryption. Avoid legacy BF-CBC, DES, or old static-key configurations in new deployments.

Enable IP Forwarding

If VPN clients should reach the internet or other machines on the server’s network, enable IPv4 forwarding.

Check the current setting:

sysctl net.ipv4.ip_forward

Enable it temporarily:

sudo sysctl -w net.ipv4.ip_forward=1

Make it persistent:

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-openvpn-forward.conf
sudo sysctl --system

Without forwarding, clients can connect to the VPN but cannot route traffic beyond the server. This is a frequent source of confusion: the tunnel comes up, the client receives an IP address, yet browsing fails.

Configure firewalld and NAT

Fedora uses firewalld by default. The OpenVPN service definition references UDP port 1194, and Fedora’s documentation recommends allowing OpenVPN traffic, adding the tunnel interface, enabling forwarding, and enabling masquerading. [16]

First, identify your public interface:

ip route get 1.1.1.1

Assume it is eth0. Adjust the commands if yours is ens3, enp1s0, or something else.

Allow OpenVPN:

sudo firewall-cmd --permanent --add-service=openvpn

If you changed the port or protocol, open it explicitly instead:

sudo firewall-cmd --permanent --add-port=1194/udp

Enable masquerading so VPN clients can reach the internet through the server:

sudo firewall-cmd --permanent --add-masquerade

Allow forwarding within the active zone:

sudo firewall-cmd --permanent --add-forward

Reload the firewall:

sudo firewall-cmd --reload

Verify the configuration:

sudo firewall-cmd --list-all

You should see openvpn under services, masquerade: yes, and forwarding enabled.

For a more restrictive production setup, avoid exposing broad forwarding rules. Permit only the VPN subnet to reach the specific internal networks or services it needs. For example, if clients should access only a database server at 192.168.10.20, use targeted rich rules rather than allowing unrestricted access to the entire LAN.

Fix SELinux Contexts

SELinux is enabled by default on Fedora, and that is a good thing. It can prevent an OpenVPN process from reading files with unexpected labels or writing logs to unintended locations.

After copying certificates and creating configuration files, restore the correct contexts:

sudo restorecon -Rv /etc/openvpn

Fedora’s OpenVPN documentation specifically calls out this step after placing keys and configuration files under /etc/openvpn. [16]

Check for SELinux denials if the service fails:

sudo ausearch -m avc -ts recent

Do not disable SELinux to solve a VPN problem. In most cases, restoring contexts, placing logs in an approved location, or adding a targeted local policy is the correct fix.

Start and Enable OpenVPN

Fedora uses template systemd units. The service name matches the configuration filename, minus the .conf extension.

With a file named /etc/openvpn/server/server.conf, start:

sudo systemctl enable --now openvpn-server@server

Check its status:

sudo systemctl status openvpn-server@server

Confirm the tunnel interface exists:

ip addr show tun0

Check that OpenVPN is listening:

sudo ss -lunp | grep 1194

You should see a UDP socket bound to port 1194.

Review logs if something fails:

sudo journalctl -u openvpn-server@server -e
sudo tail -n 100 /var/log/openvpn.log

Create a Client Certificate

Each user or device should have its own certificate. Sharing one client certificate across a team makes revocation and auditing difficult.

From the Easy-RSA directory:

cd /etc/openvpn/easy-rsa
sudo ./easyrsa build-client-full alice

Easy-RSA will prompt for a passphrase for the client key. For laptop and mobile users, a passphrase-protected key is strongly recommended. If the device is lost, the certificate alone is not enough for someone to connect.

Copy the required files into a staging directory:

sudo mkdir -p /tmp/openvpn-client-alice
sudo cp pki/ca.crt /tmp/openvpn-client-alice/
sudo cp pki/issued/alice.crt /tmp/openvpn-client-alice/
sudo cp pki/private/alice.key /tmp/openvpn-client-alice/
sudo cp /etc/openvpn/server/tls-crypt.key /tmp/openvpn-client-alice/

Transfer those files securely to the client. Then remove the temporary directory from the server:

sudo rm -rf /tmp/openvpn-client-alice

Create an Inline Client Profile

An .ovpn profile is convenient because it bundles the configuration, CA certificate, client certificate, client key, and TLS key into one file.

Create a base client configuration:

sudo nano /tmp/client-base.conf

Use the following:

client
dev tun
proto udp
remote vpn.example.com 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA256
data-ciphers AES-256-GCM:AES-128-GCM
verb 3

Replace vpn.example.com with your server’s public hostname or IP address.

Now build the inline profile:

cd /etc/openvpn/easy-rsa

{
  cat /tmp/client-base.conf
  echo '<ca>'
  sudo cat pki/ca.crt
  echo '</ca>'
  echo '<cert>'
  sudo cat pki/issued/alice.crt
  echo '</cert>'
  echo '<key>'
  sudo cat pki/private/alice.key
  echo '</key>'
  echo '<tls-crypt>'
  sudo cat /etc/openvpn/server/tls-crypt.key
  echo '</tls-crypt>'
} | sudo tee /tmp/alice.ovpn > /dev/null

Move the profile somewhere secure and transfer it to the user:

sudo chown $(whoami):$(whoami) /tmp/alice.ovpn

After transfer, delete it from the server:

rm /tmp/alice.ovpn /tmp/client-base.conf

For Linux clients using NetworkManager, install the OpenVPN plugin:

sudo dnf install -y NetworkManager-openvpn NetworkManager-openvpn-gnome

Then import the profile through the desktop network settings, or use nmcli if you prefer the terminal.

Test the VPN Connection

On a client machine, import alice.ovpn and connect.

Then verify the tunnel:

ip addr show tun0

Check the assigned VPN address:

ip route

Test general connectivity:

ping -c 4 1.1.1.1
curl -4 https://ifconfig.me

If curl returns the VPN server’s public IP, full-tunnel routing and NAT are working. If it returns the client’s original IP, the client connected but redirect-gateway or masquerading is not configured correctly.

On the server, watch live connections:

sudo tail -f /var/log/openvpn.log

Or inspect connected clients:

cat /var/log/openvpn-status.log

Common OpenVPN Problems and Fixes

The service fails to start

Run:

sudo journalctl -u openvpn-server@server -xe

Typical causes include:

  • A wrong certificate or key path in server.conf
  • A missing dh.pem file
  • Incorrect permissions on server.key
  • A typo in tls-crypt
  • SELinux denying access to a file

Check paths first. Then run:

sudo restorecon -Rv /etc/openvpn
sudo systemctl restart openvpn-server@server

Clients connect but cannot access the internet

This almost always means one of three things:

  1. IP forwarding is disabled.
  2. firewalld masquerading is missing.
  3. The client is not receiving the redirect-gateway directive.

Verify:

sysctl net.ipv4.ip_forward
sudo firewall-cmd --query-masquerade

Both should indicate that forwarding and masquerading are enabled.

The VPN connects but DNS does not work

The client may be using a DNS server unreachable through the tunnel. Push reliable DNS servers:

push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 1.0.0.1"

For a corporate VPN, push internal DNS servers instead, provided they are reachable from the VPN subnet.

UDP port 1194 is blocked

Some networks block UDP entirely or restrict nonstandard outbound traffic. Test from the client:

nc -vzu vpn.example.com 1194

If UDP is blocked, configure OpenVPN on TCP 443 as a fallback. It is not always the fastest option, but it can get users connected from restrictive networks.

A second OpenVPN instance can listen on TCP 443 while the primary instance remains on UDP 1194. Use a separate configuration file, such as /etc/openvpn/server/server-tcp.conf, and start:

sudo systemctl enable --now openvpn-server@server-tcp

Remember to open TCP 443 in firewalld and ensure no web server is already using that port.

Certificate errors appear

Common messages include certificate is not yet valid, certificate has expired, or unable to get local issuer certificate.

Check time synchronization:

timedatectl

Then inspect certificate dates:

sudo openssl x509 -enddate -noout -in /etc/openvpn/server/server.crt

If the CA certificate expired, you generally need to build a new PKI and reissue client certificates. Plan CA expiry carefully; a ten-year CA lifetime is common, while client certificates should expire much sooner.

A client certificate must be revoked

Revoke the certificate:

cd /etc/openvpn/easy-rsa
sudo ./easyrsa revoke alice
sudo ./easyrsa gen-crl

Copy the new certificate revocation list to the server:

sudo cp pki/crl.pem /etc/openvpn/server/crl.pem

Add this to server.conf:

crl-verify /etc/openvpn/server/crl.pem

Restart OpenVPN:

sudo systemctl restart openvpn-server@server

Without a CRL, revoking a certificate does not actually prevent it from connecting.

r00t is an experienced Linux enthusiast and technical writer with a passion for open-source software. With years of hands-on experience in various Linux distributions, r00t has developed a deep understanding of the Linux ecosystem and its powerful tools. He holds certifications in SCE and has contributed to several open-source projects. r00t is dedicated to sharing her knowledge and expertise through well-researched and informative articles, helping others navigate the world of Linux with confidence.

Related Posts