Skip to content

feat: support custom peer-info for openvpn outbound (+ handshake timeout fix)#2917

Closed
Easy-Ez wants to merge 2 commits into
MetaCubeX:Alphafrom
Easy-Ez:feat/openvpn-peer-info
Closed

feat: support custom peer-info for openvpn outbound (+ handshake timeout fix)#2917
Easy-Ez wants to merge 2 commits into
MetaCubeX:Alphafrom
Easy-Ez:feat/openvpn-peer-info

Conversation

@Easy-Ez

@Easy-Ez Easy-Ez commented Jun 26, 2026

Copy link
Copy Markdown

Closes #2919

This PR makes the OpenVPN outbound usable against standard OpenVPN servers that gate clients via push-peer-info (e.g. an --client-connect script or PAM plugin checking IV_HWADDR). It contains two related commits.

1. feat: support custom peer-info (068a885f)

Adds a peer-info map to the OpenVPN outbound so users can send custom peer-info entries (e.g. IV_HWADDR, UV_*) during the key-method-2 handshake. Entries are appended after the built-in IV_VER/IV_PROTO/IV_CIPHERS and sorted by key for deterministic output. Fully backward compatible — when peer-info is omitted the emitted bytes are identical to before.

proxies:
  - name: "openvpn"
    type: openvpn
    server: vpn.example.com
    port: 1194
    ca: |
      -----BEGIN CERTIFICATE-----
      ...
      -----END CERTIFICATE-----
    peer-info:
      IV_HWADDR: "52:54:00:ff:72:87"
      UV_DEVICE_ID: "laptop-001"

2. fix: handshake must not inherit the per-dial timeout (1dfb0e0d)

Why a second commit is needed: peer-info alone is not enough. A server that runs push-peer-info / PAM / --client-connect checks needs longer to finish the control-channel handshake than the single connection's dial timeout (C.DefaultTCPTimeout, 5s) that happens to trigger it. handshakeContext was derived from that dial context, so the 30s DefaultHandshakeTimeout was effectively capped at ~5s, and the handshake (key-method-2 exchange + PUSH_REPLY) timed out before it could finish — even with correct credentials and peer-info.

  • Run the handshake under the outbound's run context with the full handshake timeout, since the tunnel is shared infrastructure reused by every connection rather than owned by the dial that triggers it.
  • After the tunnel is established, refresh the dial deadline so the very first request (which paid for the one-time handshake) is not failed for exhausting its own budget.

Testing

Verified against a real OpenVPN server that gates clients by IV_HWADDR:

  • With both commits: the outbound connects — handshake completes and traffic flows on the first request.
  • With only the peer-info commit: the first dial times out during the handshake (the 5s cap fires before PUSH_REPLY).

go test ./transport/openvpn/ passes.


本 PR 让 OpenVPN 出站能连通那些用 push-peer-info(如 --client-connect 脚本 / PAM 插件校验 IV_HWADDR)做设备准入的标准 OpenVPN 服务端,包含两个相关 commit。

1. feat: 支持自定义 peer-info(068a885f) — 新增 peer-info map,可在 key-method-2 握手时上送 IV_HWADDRUV_* 等自定义条目,追加在内置 IV_VER/IV_PROTO/IV_CIPHERS 之后并按 key 排序;不填时与改动前逐字节一致,完全向后兼容。

2. fix: 握手不应继承单次拨号超时(1dfb0e0d) — 为什么需要第二个 commit:仅有 peer-info 不够。运行 push-peer-info / PAM / --client-connect 校验的服务端,完成控制信道握手所需时间比「恰好触发它的那条连接」的拨号超时(C.DefaultTCPTimeout,5s)更久。而 handshakeContext 继承自该拨号 context,导致 30s 的 DefaultHandshakeTimeout 实际被压到 ~5s,握手(key-method-2 交换 + PUSH_REPLY)在完成前就超时 —— 即使账密和 peer-info 都正确。修复:握手改用 outbound 的 run context(隧道是被所有连接复用的共享资源,而非由触发它的拨号拥有)跑满完整握手超时;隧道建立后刷新拨号 deadline,使「为一次性握手买单」的首个请求不因自身预算耗尽而失败。

验证:针对真实按 IV_HWADDR 做准入的 OpenVPN 服务端 —— 两个 commit 都在时首个请求即连通;仅 peer-info commit 时首次拨号在握手中超时。go test ./transport/openvpn/ 通过。

Allow declaring custom peer-info entries (e.g. IV_HWADDR, UV_*) in the
openvpn outbound config. They are appended after the built-in
IV_VER/IV_PROTO/IV_CIPHERS fields and sorted by key for deterministic
output. Omitting peer-info keeps the emitted bytes identical to before,
so the change is fully backward compatible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
An OpenVPN server that performs push-peer-info / PAM / client-connect
checks needs longer to finish the control-channel handshake than the
single connection's dial timeout (C.DefaultTCPTimeout, 5s) that happens
to trigger it. handshakeContext was derived from that dial context, so
the 30s DefaultHandshakeTimeout was effectively capped at ~5s and the
handshake (key-method-2 exchange + PUSH_REPLY) timed out before it could
finish — even with correct credentials and peer-info.

- Run the handshake under the outbound's run context with the full
  handshake timeout, since the tunnel is shared infrastructure reused by
  every connection rather than owned by the dial that triggers it.
- After the tunnel is established, refresh the dial deadline so the very
  first request (which paid for the one-time handshake) is not failed for
  exhausting its own budget.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Easy-Ez Easy-Ez changed the title feat: support custom peer-info for openvpn outbound feat: support custom peer-info for openvpn outbound (+ handshake timeout fix) Jun 27, 2026
@wwqgtxx

wwqgtxx commented Jun 27, 2026

Copy link
Copy Markdown
Collaborator

Please do not modify multiple items in a single PR; otherwise, the PR will be closed immediately.

@wwqgtxx wwqgtxx closed this Jun 28, 2026
@Easy-Ez

Easy-Ez commented Jun 29, 2026

Copy link
Copy Markdown
Author

Thanks for the feedback. I've split this into two single-purpose PRs against Alpha:

Closing this combined one in favor of those.


感谢反馈。已按「一个 PR 只做一件事」拆成两个独立 PR(均提到 Alpha):

本合并 PR 以这两个为准。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants