// DevOps

OpenVPN: setting up Ubuntu server and Keenetic client

Published on 2026-09-22

This guide explains how to set up an OpenVPN server on Ubuntu and connect a Keenetic router to it. This scenario is convenient when you need to provide access to a home network or expose services (for example, a PBX or a web server) over a VPN.

Since 2025 in Russia, routers of this platform have been released under the Netcraze brand (Netcraze LLC, formerly Kinetik LLC), models NC-xxxx; the firmware is the same — NDMS, so everything described applies to them as well.

How the OpenVPN certificate infrastructure is organized and what each key is for is covered in detail in the article OpenVPN: Part 2 — How It Works: PKI, Certificates, and Basic Setup. Here — a practical scenario.


1. Prepare the Ubuntu server

1.1 Install packages

bash
sudo apt update
sudo apt install -y openvpn easy-rsa iptables-persistent

1.2 Create the PKI (Easy-RSA v3)

bash
make-cadir ~/easy-rsa
cd ~/easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopass

Server keys

bash
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dh

Client keys (for Keenetic)

bash
./easyrsa gen-req keenetic nopass
./easyrsa sign-req client keenetic

Shared TLS key for tls-auth

bash
openvpn --genkey secret ta.key

1.3 Place the keys

  • In /etc/openvpn/server/:

    • ca.crt (from pki/), server.crt (from pki/issued/), server.key (from pki/private/), dh.pem (from pki/), ta.key
  • In /etc/openvpn/ccd/keenetic (we’ll create it later) — the subnet behind the Keenetic.

The filename in ccd must match the Common Name of the client certificate — in the example this is keenetic.


2. OpenVPN server configuration

File /etc/openvpn/server/server.conf:

conf
port 1194
proto udp
dev tun
user nobody
group nogroup
topology subnet

server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt

ca ca.crt
cert server.crt
key server.key
dh dh.pem

# TLS protection
tls-auth ta.key 0
auth SHA256
# Data ciphers: GCM for clients supporting cipher negotiation (OpenVPN 2.4+),
# CBC — fallback for clients without negotiation
data-ciphers AES-256-GCM:AES-128-GCM:AES-256-CBC
data-ciphers-fallback AES-256-CBC

keepalive 10 120
persist-key
persist-tun
explicit-exit-notify 1

# Route to the network behind Keenetic into the server kernel routing table (together with iroute in ccd)
route 192.168.45.0 255.255.255.0

# Push only the necessary routes
push "route 10.8.0.0 255.255.255.0"
push "route 192.168.45.0 255.255.255.0"

# Per-client configuration directory
client-config-dir /etc/openvpn/ccd

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

3. Specify the network behind Keenetic (CCD)

File /etc/openvpn/ccd/keenetic:

conf
iroute 192.168.45.0 255.255.255.0

Both directives are required: route in server.conf directs packets from the server kernel into OpenVPN, while iroute inside OpenVPN tells which client should receive them. Without route, traffic to 192.168.45.0/24 will not enter the tunnel (this is how OpenVPN’s --iroute help explains it).

Start the server (on Ubuntu the configuration from /etc/openvpn/server/ is started by the openvpn-server@ template):

bash
sudo mkdir -p /var/log/openvpn
sudo systemctl enable --now openvpn-server@server

4. Enable IP forwarding

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

5. iptables setup (DNAT + SNAT)

Example for:

  • Web server: 192.168.45.230:443
  • PBX: 192.168.45.235:5060–5065 TCP, 10000–20000 UDP
bash
EXT_IF=enp3s0   # external interface

# DNAT
iptables -t nat -A PREROUTING -i $EXT_IF -p tcp --dport 443        -j DNAT --to-destination 192.168.45.230
iptables -t nat -A PREROUTING -i $EXT_IF -p tcp --dport 5060:5065   -j DNAT --to-destination 192.168.45.235
iptables -t nat -A PREROUTING -i $EXT_IF -p udp --dport 10000:20000 -j DNAT --to-destination 192.168.45.235

# FORWARD (there and back)
iptables -A FORWARD -i $EXT_IF -o tun0 -d 192.168.45.230 -p tcp --dport 443 \
  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $EXT_IF -o tun0 -d 192.168.45.235 -p tcp --dport 5060:5065 \
  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $EXT_IF -o tun0 -d 192.168.45.235 -p udp --dport 10000:20000 \
  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i tun0 -o $EXT_IF \
  -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# SNAT (so responses go through the VPN server)
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 192.168.45.0/24 -o tun0 -j MASQUERADE

Save rules:

bash
netfilter-persistent save

6. Keenetic client configuration

File keenetic.ovpn:

conf
client
dev tun
proto udp
remote <PUBLIC_IP_UBUNTU> 1194
resolv-retry infinite
nobind
persist-key
persist-tun

remote-cert-tls server
tls-auth ta.key 1
key-direction 1
auth SHA256
cipher AES-256-CBC
verb 3

<ca>
-----BEGIN CERTIFICATE-----
... ca.crt ...
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
... keenetic.crt ...
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN PRIVATE KEY-----
... keenetic.key ...
-----END PRIVATE KEY-----
</key>

<tls-auth>
-----BEGIN OpenVPN Static key V1-----
... ta.key ...
-----END OpenVPN Static key V1-----
</tls-auth>

Keenetic requirements for the file (according to the manufacturer’s documentation):

  • the entire configuration, certificates and keys — in a single file;
  • only options from the OpenVPN 2.4 manual; IPv6 options are not supported;
  • the private key must be without a password — there is no place in the router interface to enter one;
  • the file is not saved in startup-config, keep a backup separately.

The line cipher AES-256-CBC in the client is a fallback: an OpenVPN 2.4 client with cipher negotiation will advertise AES-256-GCM and AES-128-GCM, and the server will select a GCM cipher from its data-ciphers list.

To run OpenVPN on Keenetic you need the component “OpenVPN client and server”. The connection is created on the page Other connections → VPN connections → Create connection: type — OpenVPN, paste the contents of keenetic.ovpn into the configuration field.

  • Disable “Use for internet access”, otherwise all traffic will go through the VPN.
  • To allow traffic from the tunnel to reach the home network, in the Keenetic command line set the interface to the private security level and allow communication between private interfaces (commands from the site-to-site example in the Keenetic documentation):
cli
(config)> interface OpenVPN0 security-level private
(config)> no isolate-private
(config)> system configuration save

Check the interface number (OpenVPN0) with the show interface command — it depends on the number of created connections. Other VPN client options on Keenetic are covered in the article Keenetic: Part 3 — VPN client for the entire network.


✅ Summary

The Ubuntu server acts as a VPN gateway, and the Keenetic provides access to its local network 192.168.45.0/24. Services behind the router are accessible from outside via port forwarding on the server’s public address.

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply