Skip to content

VPN

ctx can automatically connect and disconnect VPN when switching contexts. Supports OpenVPN, WireGuard, Tailscale, NetBird, and custom VPN solutions.

Configuration

vpn:
  type: openvpn                   # openvpn, wireguard, tailscale, netbird, custom
  config_file: ~/vpn/myproject.ovpn
  auto_connect: true              # Connect automatically on context switch
  auto_disconnect: true           # Disconnect when switching away

Supported VPN Types

OpenVPN

vpn:
  type: openvpn
  config_file: ~/vpn/project.ovpn
  auth_user_pass: ~/vpn/auth.txt    # Optional credentials file
  auto_connect: true

The auth_user_pass file should contain username on the first line and password on the second line.

WireGuard

vpn:
  type: wireguard
  interface: wg0
  auto_connect: true

Uses wg-quick up/down to manage the interface.

Tailscale

vpn:
  type: tailscale
  exit_node: us-west-1              # Optional exit node
  auto_connect: true

NetBird

vpn:
  type: netbird
  profile: my-profile                      # Optional, NetBird client profile name
  management_url: https://vpn.example.com  # Optional, for self-hosted NetBird
  setup_key: "XXXXXXXX-XXXX-..."           # Optional, for headless auth
  auto_connect: true

NetBird is an open-source WireGuard-based VPN/network mesh tool. Supports both NetBird Cloud and self-hosted instances. The management_url option specifies the management server (defaults to NetBird Cloud if omitted). The setup_key enables headless/automated authentication. The profile field maps to netbird up --profile for switching between different NetBird accounts.

ctx automatically creates NetBird profiles if they don't exist, and handles the disconnect/reconnect cycle when switching between contexts.

Switching between NetBird servers

NetBird only supports one active connection at a time. If you switch between different NetBird servers (e.g., self-hosted and cloud), use separate profiles — each profile stores its own management URL, keys, and auth state. Create profiles with netbird profile add <name>, then set the profile field in each context. Always set management_url explicitly in both contexts when using different servers.

Custom VPN

For any VPN that isn't directly supported, use custom commands:

vpn:
  type: custom
  connect_cmd: "sudo vpn-connect --profile myprofile"
  disconnect_cmd: "sudo vpn-disconnect"
  status_cmd: "vpn-status"
  auto_connect: true

Commands

ctx vpn connect                  # Connect VPN for current context
ctx vpn disconnect               # Disconnect VPN
ctx vpn status                   # Show VPN connection status

Auto-Connect Behavior

When auto_connect: true:

  • VPN connects automatically when you run ctx use <context>
  • Connection happens after environment variables are set but before tunnels start

When auto_disconnect: true:

  • VPN disconnects when you switch to a different context
  • VPN disconnects when you run ctx deactivate

Shared VPN Contexts

If multiple contexts share the same VPN, you can prevent disconnection when switching between them:

# context-a.yaml
name: context-a
vpn:
  type: wireguard
  interface: wg0
  auto_connect: true

deactivate:
  disconnect_vpn: false          # Keep VPN when switching away

# context-b.yaml
name: context-b
vpn:
  type: wireguard
  interface: wg0
  auto_connect: true

deactivate:
  disconnect_vpn: false          # Keep VPN when switching away

Now switching between context-a and context-b keeps the VPN connected.

Example: Corporate VPN

name: corp-prod
environment: production

vpn:
  type: openvpn
  config_file: ~/.config/ctx/vpn/corporate.ovpn
  auth_user_pass: ~/.config/ctx/vpn/corp-auth.txt
  auto_connect: true
  auto_disconnect: true

# Once connected, access internal services
tunnels:
  - name: database
    local_port: 5432
    remote_host: db.internal.corp.com
    remote_port: 5432
    auto_connect: true

Example: Tailscale Exit Node

name: geo-restricted
vpn:
  type: tailscale
  exit_node: us-east-1
  auto_connect: true