Skip to content

OpenVPN — mihomo

mihomo can dial an OpenVPN server as an outbound, running a userspace client that stands up a tun-style stack device and routes matched traffic through the encrypted tunnel. The control channel is authenticated with certificates (ca / cert / key), optional tls-crypt, and/or auth-user-pass credentials; the data channel is encrypted with the negotiated cipher.

Outbound

Entry under proxies: with type: openvpn. Embeds BasicOption (common outbound fields).

FieldTypeDefaultAllowed valuesDescription
namestring(required)<string>Unique proxy name.
serverstring(required)<host>OpenVPN server host/IP.
portint(required)<port>Server port.
protostringudpudp | tcpTransport protocol of the OpenVPN tunnel.
devstringtuntunVirtual device type (e.g. `tun`).
cipherstring(server-negotiated)AES-256-GCM | AES-128-GCM | <cipher>Data-channel cipher, e.g. `AES-256-GCM`.
authstring(unset)SHA256 | SHA512 | <digest>HMAC digest for the control channel, e.g. `SHA256`.
comp-lzostring(unset)yes | no | adaptiveLZO compression setting.
castring(required)<PEM>CA certificate (PEM, inline or file path).
certstring(unset)<PEM>Client certificate (PEM).
keystring(unset)<PEM>Client private key (PEM).
tls-cryptstring(unset)<key>tls-crypt static key for control-channel encryption/authentication.
usernamestring(unset)<string>auth-user-pass username.
passwordstring(unset)<string>auth-user-pass password.
pingint(unset)<seconds>Keepalive ping interval (seconds).
ping-restartint(unset)<seconds>Restart the tunnel after this many seconds without a ping (seconds).
mtuint1500<integer>Tunnel MTU.
udpboolfalsetrue | falseAllow UDP traffic through the proxy.
remote-dns-resolveboolfalsetrue | falseResolve destination names using the tunnel's DNS.
dns[]string[][<server>]DNS servers used for the tunnel.

Source: adapter/outbound/openvpn.go:43-66 · pinned at v1.19.27 (5184081)

Examples

Outbound — certificate authentication:

yaml
proxies:
  - name: ovpn-cert
    type: openvpn
    server: vpn.example.com
    port: 1194
    proto: udp
    cipher: AES-256-GCM
    auth: SHA256
    ca: |
      -----BEGIN CERTIFICATE-----
      <ca-certificate>
      -----END CERTIFICATE-----
    cert: |
      -----BEGIN CERTIFICATE-----
      <client-certificate>
      -----END CERTIFICATE-----
    key: |
      -----BEGIN PRIVATE KEY-----
      <client-private-key>
      -----END PRIVATE KEY-----
    udp: true

Outbound — username/password authentication with keepalive:

yaml
proxies:
  - name: ovpn-userpass
    type: openvpn
    server: vpn.example.com
    port: 1194
    proto: tcp
    ca: |
      -----BEGIN CERTIFICATE-----
      <ca-certificate>
      -----END CERTIFICATE-----
    username: <username>
    password: <password>
    ping: 10
    ping-restart: 60
    udp: true

Notes

  • proto selects the link transport: udp (default) or tcp. The data-channel cipher is negotiated with the server; set it explicitly to pin a value such as AES-256-GCM.
  • ca is required. cert + key provide certificate authentication; username + password provide auth-user-pass authentication. They can be combined when the server requires both. PEM material may be given inline (block scalar) or as a file path.
  • tls-crypt supplies the static key that encrypts and authenticates the control channel, hiding the OpenVPN handshake.
  • ping sends a keepalive at the given interval; ping-restart tears the tunnel down after that many seconds with no received packet so it can be re-established. Both are expressed in seconds.
  • mtu sets the tunnel MTU and defaults to 1500.
  • remote-dns-resolve routes destination-name lookups through the tunnel using the servers listed in dns; it has no effect unless dns is non-empty.

Cross-core notes

  • OpenVPN is mihomo-specific among these three cores. Neither Xray-core nor sing-box ships an OpenVPN outbound — to bridge an OpenVPN endpoint with those cores you would run a separate OpenVPN client and point a socks/http or TUN inbound at it.

Source: adapter/outbound/openvpn.go:43-66 · v1.19.27 (5184081)

Core Tutorial by Argsment