The VPN answers nothing on its port, and the two possible causes need opposite repairs: either no process opened the socket, or the socket exists and something between the machines stops the packets. One command settles the first half of that question, which is why it belongs before any firewall rule is touched. The order below removes one explanation per step instead of adding another guess. Guessing between the two is what turns a ten-minute diagnosis into an evening.

Assume you can log in to the server and that the client is a real profile rather than a scanner. Both assumptions matter, because a generic probe cannot answer a protocol-specific question.

Does the socket exist at all

Start with the service's own account of itself: whether it came up and, more useful, what its first startup error was. A parse failure, a missing key or a bind error stops the listener from ever existing, and the process can exit quietly enough that a status line reads as ambiguous. A unit that reports active is not proof on its own, since the main process can be alive while the component that should bind the port has already given up.

systemctl status openvpn-server@server --no-pager
journalctl -u openvpn-server@server -n 30 --no-pager
ss -lunp

The socket listing is the fact the rest of the diagnosis rests on. Read the local address column rather than the port alone, because that column is where loopback binds and wrong-interface binds show up. A listener that exists on 127.0.0.1 is running perfectly and is still invisible to your laptop.

Which address and family the socket answers on

Two mistakes look identical from the client and account for most "not reachable" reports. A server bound to the loopback address never accepts traffic from another machine, and a server bound only to an IPv4 address never answers a client dialling the IPv6 address of the same host. Compare the address in the socket table against the address the client is actually dialling, character by character, before assuming anything about policy.

Restricting the listing to one port keeps this readable when the host runs several services. The sport filter takes the port together with the transport you are testing:

ss -lun 'sport = :51820'
ss -ltnp 'sport = :1194'

The protocol column changes the whole answer

The socket table keys on protocol as well as port, and the two are independent entries. A service answering TCP on 1194 tells you nothing about whether anything is listening on UDP 1194, and the client will only ever use one of them. Confirm which transport the server configuration selects and which the client profile sends, then look for that exact row.

UDP has a second wrinkle: an unauthenticated probe is not an error the service has to answer. A scan that reports the port as silent has measured the service's discretion, not its availability, so test with the real client and profile.

One attempt, three places to look

From an approved client make exactly one attempt and write down the time to the second. Then read three sources for that window: the provider's network rule or console, the host's firewall counters or log, and the service's own log. Doing this once is what makes the three accounts comparable, and it costs less than repeating an attempt whose timestamp nobody recorded.

The two outcomes point in opposite directions. If no packet reached the host, the path is dropping it and the listener is irrelevant. If the packet arrived at the socket and the service rejected it, the path is fine and the answer lies in protocol, cryptography or credentials. Opening a port for a service that already accepted a connection makes the next diagnosis harder, not easier.

Naming the stage before you change a rule

Negotiation that starts and authentication that fails is one failure, and a tunnel that establishes while forwarding stalls is a completely different one. Naming the stage first keeps the repair narrow: a credential problem is not fixed by a firewall rule, and a data-path problem is not fixed by a restart.

Use the narrowest diagnostic that answers the question. A temporary packet observation on one port, under an administrator's control, is a reasonable instrument; disabling the whole firewall is not, because the result becomes impossible to attribute. The ss documentation covers the filters used above, and it is a cheaper first step than any capture. Record which of the two branches you proved, and the next occurrence starts from a known answer.

Amanqephe ahlobene