The instance boots, package installs succeed, and the service even reports a running state, yet nothing connects. That pattern is common on virtual private servers because a guest that reaches the internet comfortably can still be unable to create the interface your protocol wants. Five checks separate a host that can serve a tunnel from one that only looks ready, and the first failing check usually explains everything after it. Each one is cheap to run and ends in a decision rather than a note.

Confirm the Interface the Protocol Needs

OpenVPN over TUN needs the character device and the kernel module behind it; WireGuard needs its own kernel support or a userspace implementation with matching expectations. Managed containers may share a host kernel that never exposes the device, and some platforms forbid creating tunnel interfaces outright regardless of what is installed.

Test capability instead of reading a support page, because marketing labels change faster than the underlying limits. A feature list written for one plan may not describe the kernel the guest actually runs on. Two short commands answer the question for the protocols in common use, and both clean up after themselves. The commands below create nothing permanent and are removed immediately.

sudo ip tuntap add dev tun9 mode tun
sudo ip tuntap del dev tun9 mode tun
sudo ip link add wgtest type wireguard && sudo ip link del wgtest

A refusal on the first pair means TUN is unavailable and OpenVPN's default mode cannot start; a refusal on the last line means the WireGuard kernel interface is missing. The kernel TUN/TAP documentation describes the device the first check exercises. Neither failure is repaired by reinstalling the VPN package.

Remember That the Inbound Path Has Two Owners

Provider network rules and the guest firewall are separate systems, and traffic must survive both. A listener bound on the guest means nothing if the provider's security group drops the port, and an open provider rule does nothing if the guest rejects the packet. Verify the listener, then the guest rules, then the provider panel, in that order, and confirm the protocol as well as the port number. Skipping to the provider panel first is how people end up opening a range they did not need.

UDP is the common casualty: many platforms allow TCP by default and treat UDP rules as a separate entry. If the instance sits behind provider NAT rather than holding a public address, port forwarding on the provider side becomes a third configuration to reconcile.

Plan the Return Path, Not Only the Exit

Full-tunnel service needs forwarding enabled, a translation or routing scheme for client traffic, and a return path that reaches the client pool. Opening a listener supplies none of these. A tunnel that establishes but carries no useful traffic usually fails here rather than at authentication. Treat a successful handshake as the start of the diagnosis, not the end of it.

Write the plan as three concrete decisions: which source range clients receive, how their traffic leaves toward the internet, and how replies find their way back. Then confirm the kernel agrees with the plan before testing a client, so a silent mismatch is not mistaken for a client-side fault.

sysctl -n net.ipv4.ip_forward
sudo nft list ruleset | head -n 40
ip -4 route show default

Decide the IPv6 Story Explicitly

IPv6 arrives by several mechanisms that behave differently for a gateway: an address on the instance, a routed prefix, or nothing at all. Only a routed prefix lets the server hand addresses to clients in the ordinary way. Assuming that a working IPv6 address on the host implies a usable client prefix is a mistake that surfaces later as half-broken connectivity. It is the kind of fault that survives every test performed with IPv4 only.

If the provider routes no prefix, decide whether the tunnel is IPv4-only and whether clients should be told so. A documented absence is safer than a partial configuration that silently blackholes IPv6 destinations for connected users.

Prove It From an Outside Client

Local service status describes one process on one host. The useful test is an authorized client on a different network, connecting with the profile you intend to distribute, then reaching an application and resolving a name. Reconnect once as well, since a tunnel that only works on the first attempt fails the requirement that matters most in practice.

sudo wg show wg0 latest-handshakes
ip -4 route get 203.0.113.44
sudo journalctl -u wg-quick@wg0 -n 15 --no-pager

Keep the operational basics alongside the test: room for updates, bounded logs, administrative access that does not depend on the tunnel, a recovery console, and a note about what happens to client profiles when the instance is rebuilt and its public address changes. If a required interface or forwarding model is simply not available, no client-side change will supply it, and the honest next step is a different instance type rather than more configuration.

Qillqakuna t'inkisqa