agentleFS
sentineldesksentineldesk/agent/skills/vpn-client/SKILL.md

vpn-client

Skill0 starsChanged 3 months agoApache-2.0View on GitHub

Bring up and troubleshoot VPN connections from this desktop — WireGuard, OpenVPN, PPTP/L2TP and Fortinet — checking that the tunnel is up, that traffic actually routes through it, and that DNS is not leaking. Use when the task needs a VPN, or when one is connected and something still cannot be reached.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If the VPN pushed DNS servers and they are not there, the client did not apply them — on systemd-resolved that is usually a missing …

    line 93
  2. Distinctive:

    When you write a config, set the mode and say you did.

    line 101

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

"Connected" is three separate claims

A VPN client saying connected means the tunnel came up. It does not mean traffic uses it, and it does not mean DNS resolves through it. Check all three, in this order, every time — most VPN problems are the second or third:

1. run_command   ip -brief addr        → is there a tun0/wg0 with an address?
2. run_command   ip route get 1.1.1.1  → does traffic actually leave via it?
3. run_command   dig +short whoami.akamai.net @ns1-1.akamaitech.net
   or            curl -sS https://ifconfig.me
                                       → which exit are you really using?

Step 2 is the one people skip. A tunnel with no route through it is a tunnel that changed nothing, and the symptom — "the VPN is on but I can't reach the server" — sends people to the firewall for an hour.

WireGuard

The quickest to reason about, because it is stateless:

run_command   wg show                       (handshakes, transfer counters)
run_command   wg-quick up wg0 / down wg0
service_control wg-quick@wg0                (for one that persists)

A peer with no recent handshake is not connected, whatever the interface says. wg show prints "latest handshake" — if it is empty or minutes old with traffic flowing, the far side is not answering. AllowedIPs is both the routing table and the access filter: 0.0.0.0/0 sends everything, a narrower range sends only that, and a peer that cannot be reached often just is not in it.

OpenVPN

job_start   openvpn --config /etc/openvpn/client.conf
job_status  → read the log until "Initialization Sequence Completed"
job_abort   to bring it down

It never returns, so it is a job, always. That line is the only thing that means it worked; anything before it is progress. service_control openvpn-client@<name> is the managed way when the config is installed.

Auth failures, expired certificates and TLS handshake failed all appear in that output — read it rather than guessing, and read the tail.

PPTP and L2TP

Say this out loud when somebody asks for PPTP: its encryption is broken and has been for years. It still works and is sometimes the only option a remote device offers; if it is a choice, WireGuard is the answer. Use it when required, and note in your report that the link is not confidential.

pon/poff with a peer in /etc/ppp/peers/, and the credentials live in /etc/ppp/chap-secrets (mode 0600) — not in your arguments.

Fortinet

openfortivpn is the client that works headlessly:

job_start   openfortivpn vpn.example.com:443 --config /etc/openfortivpn/config

The official forticlient wants a GUI, so on a desktop with a screen it is launch_app and a person driving it — say so rather than trying to automate a window that expects a human. Fortinet gateways commonly require a second factor, which is by definition the person's to supply: ask_human.

DNS leaking is the failure nobody notices

The tunnel is up, traffic routes, and the resolver is still the local one — so internal names do not resolve and every query is visible to the local network.

run_command   resolvectl status        (or cat /etc/resolv.conf)
run_command   dig +short internal.host

If the VPN pushed DNS servers and they are not there, the client did not apply them — on systemd-resolved that is usually a missing update-systemd-resolved hook for OpenVPN, or DNS=/PostUp missing in the WireGuard config.

Credentials and config files

A VPN password, a certificate passphrase or a 2FA code is never a tool argument — it goes in the client's config file with mode 0600, or the person supplies it. When you write a config, set the mode and say you did.

Bringing a VPN up changes what this whole desktop can reach, including for anyone else watching it. Say what you are connecting to and why before you do it, and bring it down when the task is over.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.