// 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
sudo apt update
sudo apt install -y openvpn easy-rsa iptables-persistent1.2 Create the PKI (Easy-RSA v3)
make-cadir ~/easy-rsa
cd ~/easy-rsa
./easyrsa init-pki
./easyrsa build-ca nopassServer keys
./easyrsa gen-req server nopass
./easyrsa sign-req server server
./easyrsa gen-dhClient keys (for Keenetic)
./easyrsa gen-req keenetic nopass
./easyrsa sign-req client keeneticShared TLS key for tls-auth
openvpn --genkey secret ta.key1.3 Place the keys
In
/etc/openvpn/server/:ca.crt(frompki/),server.crt(frompki/issued/),server.key(frompki/private/),dh.pem(frompki/),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:
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 33. Specify the network behind Keenetic (CCD)
File /etc/openvpn/ccd/keenetic:
iroute 192.168.45.0 255.255.255.0Both 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):
sudo mkdir -p /var/log/openvpn
sudo systemctl enable --now openvpn-server@server4. Enable IP forwarding
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl --system5. iptables setup (DNAT + SNAT)
Example for:
- Web server:
192.168.45.230:443 - PBX:
192.168.45.235:5060–5065 TCP, 10000–20000 UDP
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 MASQUERADESave rules:
netfilter-persistent save6. Keenetic client configuration
File keenetic.ovpn:
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):
(config)> interface OpenVPN0 security-level private
(config)> no isolate-private
(config)> system configuration saveCheck 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)
Или оставьте заявку здесь:
// Related