Someone sends you a profile, you import it, and thirty seconds later a client is dialling a destination nobody checked. Read the file in a text editor first, because the whole of what matters sits in a handful of directives: remote, proto, port, ca, cert, tls-crypt and verify-x509-name. Everything else is defaults, and the defaults are where the surprises live.

List every endpoint the file can use

Begin with the endpoints, because one profile can hold several. grep -nE '^[[:space:]]*(remote|proto|port|remote-random|connection)' profile.ovpn prints every candidate in file order, including the ones nested inside inline <connection> blocks.

When a directive omits a port, the client falls back to the listener default, so remote vpn.example.com alone means port 1194 with whatever proto appears later in the file. Several plain remote lines are alternatives: the client tries them in order unless remote-random shuffles them, and it never silently substitutes a different operator's host. Two remote lines on unrelated domains is the point where you stop and ask which one was meant.

Note the proto spelling too. tcp is accepted as a synonym for the client-side tcp-client, but tcp-server in a client profile is a configuration error that tends to hang rather than fail cleanly.

Confirm the name, then the port

dig +short vpn.example.com tells you whether the name exists and which addresses it returns, and a multi-homed or proxied endpoint may legitimately return several. Resolution is a prerequisite, not evidence of ownership; anyone can point a name at an address, and one address can answer for many names.

Then check the listener on the port you found, matching the transport. Over TCP, openssl s_client -connect vpn.example.com:1194 -servername vpn.example.com prints the chain the server presents. Over UDP you need DTLS: openssl s_client -dtls1_2 -connect vpn.example.com:1194 runs the same handshake across datagrams. A completed handshake proves that something is listening and holding a certificate, which is more than a ping shows and less than the profile's own trust settings demand.

When the handshake fails and the host pings, the port is probably wrong or filtered. Treat that as a reason to request the correct port, not an invitation to sweep the nearby ones. nc -vzu also reports success on some stacks with nothing listening, so a bare UDP probe means nothing without a handshake behind it.

Read the trust pins separately from the address

The address decides where the client goes; the trust block decides who it believes once it arrives. verify-x509-name "vpn.example.com" name pins the subject common name, and remote-cert-tls server requires the extended key usage for server authentication. A profile handed to you by an operator should carry both.

Look for ca, an inline <ca> block, and either tls-crypt or tls-auth. A profile using tls-auth needs key-direction 1 on the client when the server side uses direction 0, and a mismatch fails the handshake with a TLS error that reads like a certificate fault. An inline CA that does not belong to the operator whose name you just resolved means the file was assembled from two sources, and that is the case worth refusing outright.

verify-x509-name takes name, name-prefix or subject modes, and the last one expects a full distinguished name in the exact order the server prints it. Pick a mode that matches the value's shape, because the client rejects every connection rather than warning about a near miss. For a file you did not author, name with a plain hostname is the least surprising choice.

Check the options that fail quietly

OpenVPN 2.6 negotiates ciphers through data-ciphers, and a profile carrying only an old cipher AES-256-CBC line can complete the control channel and then stall on data. Reading that value tells you whether the file predates the server you are joining; the 2.6 man page lists the negotiation order if you need to quote it back to the operator.

auth-user-pass with no filename means the client will prompt, so a profile that looks self-contained still needs credentials. auth-user-pass credentials.txt means it expects a file you were probably not sent. nobind and resolv-retry infinite are ordinary and harmless, while explicit-exit-notify is UDP-only and pointless over TCP.

None of these change where the profile connects, but each changes whether it connects at all, and none of them is visible in a client's import dialog.

Decide, then record what you decided

Three outcomes exist after this reading, and only one is import. When the endpoint and the pins match instructions you got through a separate channel, import it. When the endpoint looks right but the pins or the CA do not match, ask for a corrected file. When the file mixes endpoints or CA material from different sources, delete it and request a fresh copy.

Record the hash you reviewed, so the next person can tell whether the file changed: sha256sum profile.ovpn, pasted next to the endpoint in your notes. A profile is a whole arrangement, not a list of addresses, so never splice a working remote into someone else's trust block while keeping their credentials.

Keep private keys and passwords out of screenshots and chat threads while you compare notes. The endpoint and the non-secret options are enough to ask a precise question, and the rest belongs in the file.

If you do import it and the first attempt fails, run the client with --verb 3 and read the first ten lines: the resolved remote address, the negotiated proto and the TLS error appear in that order, which tells you which of the checks above you skipped.

Zvinyorwa zvakafanana