Skip to content

OpenConnect — sing-box ​

sing-box 提供 OpenConnect 客户端端点(type: "openconnect")。它可以连接 Cisco AnyConnect、Palo Alto GlobalProtect、Fortinet SSL VPN、F5 BIG-IP、Pulse Connect Secure 与 Juniper Network Connect 服务器,并把 VPN 暴露为可路由的端点,承载 TCP、UDP 与 ICMP。配套的 openconnect DNS 服务器通过 VPN 服务器推送的 DNS 设置解析域名。

端点,仅客户端

OpenConnect 位于根级 endpoints[] 数组中,与 WireGuard 和 Tailscale 相同,在路由规则中通过 tag 引用。只实现了客户端一侧。

端点选项 ​

endpoints[] 中的 type: "openconnect":

字段类型默认值允许值描述
systemboolfalsetrue | false使用真实的系统接口,而非 sing-box 的内部网络栈。需要权限,且不能与现有接口冲突。
namestring(auto)<interface name>启用 system 时的接口名称。默认自动生成以 oc 开头的名称。
udp_timeoutbadoption.Duration5m<duration>UDP NAT 会话的过期时间。
udp_mappingUDPNATBehaviorendpoint_independentendpoint_independent | address_dependent | address_and_port_dependentUDP NAT 映射行为:同一来源对所有目标复用一个映射,或按目标地址 / 地址与端口分别映射。
udp_filteringUDPNATBehaviorendpoint_independentendpoint_independent | address_dependent | address_and_port_dependentUDP NAT 过滤行为:接受来自任意远端的回包,或只接受已发送过数据的地址 / 地址与端口。
udp_nat_maxuint320<count>UDP NAT 会话的最大数量;达到上限时关闭最久未使用的会话。0 表示 iOS 上为 4096,其他平台按总内存取 4096–16384。
serverstring(required)<hostname or https:// URL>VPN 服务器的 HTTPS URL;缺少时会自动补上 https://。不支持 URL 中的用户信息、查询串与片段。
flavorstringanyconnectanyconnect | gp | fortinet | f5 | pulse | nc服务器类型:Cisco AnyConnect、Palo Alto GlobalProtect、Fortinet、F5 BIG-IP、Pulse Connect Secure、Juniper Network Connect。
usernamestring(unset)<string>用于填写认证表单中匹配的用户名字段。
passwordstring(unset)<string>用于填写认证表单中匹配的密码字段。
auth_groupstring(unset)<string>在该类型支持时,预先选中匹配的组、realm、域或网关。
cookiestring(unset)<session cookie>已有的认证会话,会先于凭据认证尝试。格式取决于类型(如 AnyConnect 的 webvpn、Fortinet 的 SVPNCOOKIE、Network Connect 的 DSID);服务器拒绝时回退到常规登录。
token*OpenConnectTokenOptions(unset)OpenConnectTokenOptions软件令牌(TOTP、HOTP、RSA SecurID)或 OIDC 访问令牌,用于应答令牌字段或 Bearer 认证。见下文。
reported_osstring(from platform)linux | linux-64 | win | mac-intel | android | apple-ios向 AnyConnect、GlobalProtect 与 Pulse 服务器报告的操作系统标识。默认取当前平台。
user_agentstring(flavor-specific)<string>向服务器报告的 User-Agent。默认值:兼容 AnyConnect 的 OpenConnect 代理标识(AnyConnect、Network Connect、Pulse、F5)、PAN GlobalProtect、Mozilla/5.0 SV1(Fortinet)。
versionstringv9.21<string>与 user_agent 分开报告的客户端版本;目前用于 AnyConnect XML 认证。
local_hostnamestring(system hostname)<string>向服务器报告的主机名;无法获取系统主机名时为 localhost。
mobile*OpenConnectMobileOptions(unset)OpenConnectMobileOptions报告 AnyConnect 移动客户端身份。设置后三个子字段均为必填。见下文。
csd*OpenConnectCSDOptions(built-in){ wrapper_path }AnyConnect 的 CSD / host scan 处理。默认内置实现;设置 wrapper_path 则改为运行外部包装程序。
hip*OpenConnectHIPOptions(built-in){ wrapper_path }GlobalProtect 的 HIP 报告处理。默认内置实现;设置 wrapper_path 则改为运行外部包装程序。
tncc*OpenConnectTNCCOptions(built-in)OpenConnectTNCCOptionsNetwork Connect 的 TNCC 合规检查处理。见下文。
fortinet_host_check*OpenConnectFortinetHostCheckOptions(disabled)OpenConnectFortinetHostCheckOptions覆盖 Fortinet hostcheck 结果;仅当 hostcheck 非空时生效。见下文。
no_udpboolfalsetrue | false禁用 DTLS / ESP 数据通道,全部流量走 TLS 通道。
dtls_local_portuint160<port>直连 DTLS / ESP 数据通道的本地 UDP 端口;0 表示使用临时端口。
compression_disabledboolfalsetrue | false禁用 AnyConnect 压缩协商。与 compression_mode: all 冲突。
compression_modestringstatelessstateless | allAnyConnect 压缩模式:stateless 声明 oc-lz4 / lzs;all 还会为 CSTP 提供有状态的 deflate(DTLS 仍为无状态)。压缩可能泄露隧道内明文的信息。
ipv6_disabledboolfalsetrue | false不请求也不使用 IPv6 隧道配置。
http_keepalive_disabledboolfalsetrue | false在认证与配置请求期间禁用 HTTP 连接复用。
xml_post_disabledboolfalsetrue | false跳过 AnyConnect XML POST 认证,改用旧的 GET 流程开始认证。
external_auth_disabledboolfalsetrue | false为 AnyConnect、GlobalProtect 与 Fortinet 禁用外部浏览器认证(SSO / SAML);意外的外部认证请求会被拒绝。
password_authentication_disabledboolfalsetrue | false当服务器返回非成功表单时中止 AnyConnect 认证(类似 OpenConnect 的 --no-passwd)。不影响其他类型或 cookie。
tcp_keep_alive_enabledboolfalsetrue | false为直连 VPN 服务器的连接启用 TCP keep-alive(与 OpenConnect 一样默认关闭)。设置 tcp_keep_alive 或 tcp_keep_alive_interval 也会启用它。
pfsboolfalsetrue | false对 TLS 1.2 及更早版本要求具备前向保密的加密套件。默认关闭,以兼容需要 RSA 密钥交换的服务器。
mtuuint320<576-65535>首选隧道 MTU;协商得到的 MTU 以此为上限(0 表示按协商)。小于 576 的非零值按 576 处理。
base_mtuuint321406<1280-65535>用于在扣除外层开销后推算隧道 MTU 的路径 MTU(AnyConnect、GlobalProtect、F5、Fortinet)。小于 1280 的值按 1280 处理。
dpd_intervalbadoption.Duration(server-provided)<duration>覆盖 Dead Peer Detection 间隔。小于 2s 的正值按 2s 处理。
reconnect_timeoutbadoption.Duration300s<duration>重连失败时累计退避时间的上限;第一次重试立即进行。
trojan_intervalbadoption.Duration(server-provided)<duration>GlobalProtect HIP 报告 / Network Connect TNCC 检查的间隔。服务器未提供时,GlobalProtect 使用 1h。
queue_lengthuint3232<packets>VPN 传输与隧道接口之间的数据包队列长度。队列满时施加背压,而不是丢弃数据包。
allow_insecure_cryptoboolfalsetrue | false为旧服务器允许弱 TLS / DTLS 加密套件与 TLS 1.0。不会禁用证书校验。
tlsOpenConnectTLSOptions(system trust)OpenConnectTLSOptionsOpenConnect 专用的 TLS 设置(并非 sing-box 通用的 TLS 块)。见下文。
form_entries[]OpenConnectFormEntryOptions[][OpenConnectFormEntryOptions]认证表单字段的覆盖项。见下文。

源码: option/openconnect.go:5-49 · 锚定版本 v1.14.2 (af6e64c)

该端点还嵌入了常规的 拨号字段(detour、bind_interface、tcp_keep_alive 等),它们作用于连接 VPN 服务器的连接。csd 与 hip 各自只有一个 wrapper_path 字段。

token ​

字段类型默认值允许值描述
modestring(required)totp | hotp | stoken | oidc令牌类型:TOTP、HOTP、RSA SecurID 软件令牌(stoken),或作为 HTTP Bearer 认证发送的 OIDC 访问令牌。
secretstring(unset)<secret>令牌密钥:TOTP / HOTP 使用 Base32、带 base32: 前缀的值或 otpauth:// URI;stoken 使用 CTF 令牌内容;oidc 使用访问令牌(仅在服务器要求 Bearer 认证时发送)。secret 与 secret_path 二者必填其一。
secret_pathstring(unset)<file path>从文件读取密钥或 OIDC 访问令牌。与 secret 冲突。
pinstring(unset)<PIN>RSA SecurID 的 PIN(stoken)。
passwordstring(unset)<string>用于解密受密码保护的 SecurID 令牌的密码(stoken)。
device_idstring(unset)<string>用于解密绑定设备的 SecurID 令牌的设备 ID(stoken)。
counteruint640<uint64>HOTP 初始计数器;为 0 时,若存在 otpauth:// URI 则使用其中的计数器。

源码: option/openconnect.go:51-59 · 锚定版本 v1.14.2 (af6e64c)

tls ​

OpenConnect 使用自己的 TLS 块,而非通用的 TLS 选项——这里没有 uTLS、REALITY 或 ECH。

字段类型默认值允许值描述
insecureboolfalsetrue | false跳过服务器证书与主机名校验。这会让主动攻击者冒充服务器;应优先使用 certificate_authority 或 peer_fingerprint。
server_namestring(host from server)<hostname>SNI 以及证书校验所用的名称。
peer_fingerprintbadoption.Listable[string](unset)<SHA-1 hex> | sha1:<hex> | sha256:<hex> | pin-sha256:<base64>允许的服务器证书指纹:不带前缀的 SHA-1 证书哈希(同 OpenConnect 的 --servercert)或 SPKI 哈希。可使用至少 4 个字符的前缀;匹配后可授权本不受信任的证书。
system_trust_disabledboolfalsetrue | false忽略系统 CA 证书池;改用 certificate_authority 或 peer_fingerprint 建立信任。
certificate_authoritybadoption.Listable[string](unset)<PEM>额外信任的 CA 证书(PEM 内容),会加入系统证书池。与 certificate_authority_path 冲突。
certificate_authority_pathstring(unset)<file path>从 PEM 文件读取的额外信任 CA 证书。
client_certificatebadoption.Listable[string](unset)<PEM>客户端证书链(PEM 内容)。证书与私钥必须同时设置。
client_certificate_pathstring(unset)<file path>从 PEM 文件读取的客户端证书链。
client_keybadoption.Listable[string](unset)<PEM>客户端私钥(PEM 内容)。
client_key_pathstring(unset)<file path>从 PEM 文件读取的客户端私钥。
client_key_passwordstring(unset)<string>加密客户端私钥的密码。
mca_certificatebadoption.Listable[string](unset)<PEM>AnyConnect 多证书认证(MCA)的证书链(PEM 内容)。证书与私钥必须同时设置。
mca_certificate_pathstring(unset)<file path>从 PEM 文件读取的 MCA 证书链。
mca_keybadoption.Listable[string](unset)<PEM>MCA 私钥(PEM 内容)。
mca_key_pathstring(unset)<file path>从 PEM 文件读取的 MCA 私钥。
mca_key_passwordstring(unset)<string>加密 MCA 私钥的密码。

源码: option/openconnect.go:93-110 · 锚定版本 v1.14.2 (af6e64c)

form_entries ​

条目按 submission_key 匹配,或按 form_id 加 name 匹配;后出现的匹配项优先。

字段类型默认值允许值描述
form_idstring(unset)<string>表单标识;当 submission_key 为空时与 name 一起匹配。
submission_keystring(unset)<string>字段的提交键。需要设置它,或同时设置 form_id 与 name;后出现的匹配项优先。
namestring(unset)<string>字段名,与 form_id 一起匹配。
valuestring(unset)<string>自动填入的值。与 promote 冲突。
promoteboolfalsetrue | false以交互方式询问该字段,而不是自动填写。与 value 冲突。

源码: option/openconnect.go:112-118 · 锚定版本 v1.14.2 (af6e64c)

tncc ​

字段类型默认值允许值描述
wrapper_pathstring(built-in)<file path>外部 TNCC 包装程序的路径。与其他所有 tncc 字段冲突。
device_idstring(unset)<string>内置处理器报告的设备 ID。
user_agentstringNeoteris HC Http<string>内置处理器使用的 User-Agent。
machine_identification_enabledboolfalsetrue | false让内置处理器报告平台、主机名与观察到的 MAC 地址。
certificates[]OpenConnectTNCCCertificateOptions[][{ certificate | certificate_path }]用于应答证书请求的机器证书(PEM 内容或路径)。需要启用 machine_identification_enabled。

源码: option/openconnect.go:75-81 · 锚定版本 v1.14.2 (af6e64c)

每个 certificates[] 条目二选一:certificate(PEM 内容)或 certificate_path。

fortinet_host_check ​

字段类型默认值允许值描述
hostcheckstring(unset)<status>,<os-version>Hostcheck 结果字符串,例如 0100,10.0.19042——四个 0/1 标志依次表示第三方防火墙、第三方杀毒、FortiClient 防火墙与 FortiClient 杀毒,其后为系统版本。为空则禁用 hostcheck。
check_virtual_desktopstring(empty)<MAC>|<MAC>…虚拟桌面检查结果,惯例为以 | 连接的 MAC 地址。未设置时作为空字段提交。

源码: option/openconnect.go:83-86 · 锚定版本 v1.14.2 (af6e64c)

mobile ​

字段类型默认值允许值描述
platform_versionstring(required)<string>向 AnyConnect 服务器报告的移动操作系统版本。
device_typestring(required)<string>设备型号或类型。
device_unique_idstring(required)<string>设备标识符。

源码: option/openconnect.go:61-65 · 锚定版本 v1.14.2 (af6e64c)

DNS 服务器 ​

dns.servers[] 中的 type: "openconnect":

字段类型默认值允许值描述
endpointstring(required)<endpoint tag>OpenConnect 端点的 tag。查询会发往 VPN 服务器推送的解析器:split-DNS 规则使用各自的解析器,推送的 split-DNS 与搜索域后缀使用通用解析器,最具体的后缀优先。
accept_default_resolversboolfalsetrue | false对未匹配的查询也使用推送的通用解析器——仅当服务器要求所有 DNS 走隧道,或未推送 split-DNS 规则与后缀时。否则未匹配的查询返回 NXDOMAIN。
accept_search_domainboolfalsetrue | false对单标签名称(如 intranet)依次拼接推送的各个搜索域重试,直到解析成功。

源码: option/openconnect.go:120-124 · 锚定版本 v1.14.2 (af6e64c)

示例 ​

最简 AnyConnect 客户端,把一个私有网段路由到 VPN:

json
{
  "endpoints": [
    {
      "type": "openconnect",
      "tag": "oc-client",
      "server": "vpn.example.com",
      "flavor": "anyconnect",
      "username": "alice",
      "password": "<password>"
    }
  ],
  "route": {
    "rules": [
      { "ip_cidr": ["10.0.0.0/8"], "outbound": "oc-client" }
    ]
  }
}

使用 TOTP 令牌的 GlobalProtect,并通过推送的解析器应答 VPN 的 split-DNS 域名:

json
{
  "dns": {
    "servers": [
      { "type": "local", "tag": "local" },
      { "type": "openconnect", "tag": "oc-dns", "endpoint": "gp-client" }
    ],
    "rules": [
      { "preferred_by": "oc-dns", "action": "route", "server": "oc-dns" }
    ],
    "final": "local"
  },
  "endpoints": [
    {
      "type": "openconnect",
      "tag": "gp-client",
      "server": "https://gp.example.com",
      "flavor": "gp",
      "username": "alice",
      "password": "<password>",
      "token": { "mode": "totp", "secret": "<base32 secret>" }
    }
  ]
}

说明 ​

  • 该类型仅在使用 with_openconnect 构建标签时编译进来,默认的用户态模式(system: false)还需要 with_gvisor。缺少时,端点与 DNS 服务器都会在启动时报错并提示重新构建。
  • 配置文件只能完成非交互式登录:username / password、token、cookie 与 form_entries。SSO / SAML 以及其他配置无法应答的提示,需要通过 sing-box 图形客户端或 Dashboard(Tools → Endpoints)完成。
  • 推送的 DNS 设置不会安装到操作系统中。要使用它们,请添加 openconnect DNS 服务器;像上例那样配合 preferred_by,只有 VPN 自己的域名会发往那里。
  • compression_mode: all 会启用有状态压缩,带来额外的保密性风险——仅在服务器要求时使用。
  • tls.insecure 与 allow_insecure_crypto 相互独立:前者跳过证书校验,后者只是重新启用旧加密套件与 TLS 1.0。

跨内核说明 ​

  • mihomo 没有 OpenConnect 客户端;最接近的 VPN 类出站是 OpenVPN — mihomo。
  • Xray-core 不支持 OpenConnect。

源码: option/openconnect.go:5-49 · v1.14.2 (af6e64c)

由 Argsment 出品的 Core Tutorial