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 设置解析域名。
端点选项
endpoints[] 中的 type: "openconnect":
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
system | bool | false | true | false | 使用真实的系统接口,而非 sing-box 的内部网络栈。需要权限,且不能与现有接口冲突。 |
name | string | (auto) | <interface name> | 启用 system 时的接口名称。默认自动生成以 oc 开头的名称。 |
udp_timeout | badoption.Duration | 5m | <duration> | UDP NAT 会话的过期时间。 |
udp_mapping | UDPNATBehavior | endpoint_independent | endpoint_independent | address_dependent | address_and_port_dependent | UDP NAT 映射行为:同一来源对所有目标复用一个映射,或按目标地址 / 地址与端口分别映射。 |
udp_filtering | UDPNATBehavior | endpoint_independent | endpoint_independent | address_dependent | address_and_port_dependent | UDP NAT 过滤行为:接受来自任意远端的回包,或只接受已发送过数据的地址 / 地址与端口。 |
udp_nat_max | uint32 | 0 | <count> | UDP NAT 会话的最大数量;达到上限时关闭最久未使用的会话。0 表示 iOS 上为 4096,其他平台按总内存取 4096–16384。 |
server | string | (required) | <hostname or https:// URL> | VPN 服务器的 HTTPS URL;缺少时会自动补上 https://。不支持 URL 中的用户信息、查询串与片段。 |
flavor | string | anyconnect | anyconnect | gp | fortinet | f5 | pulse | nc | 服务器类型:Cisco AnyConnect、Palo Alto GlobalProtect、Fortinet、F5 BIG-IP、Pulse Connect Secure、Juniper Network Connect。 |
username | string | (unset) | <string> | 用于填写认证表单中匹配的用户名字段。 |
password | string | (unset) | <string> | 用于填写认证表单中匹配的密码字段。 |
auth_group | string | (unset) | <string> | 在该类型支持时,预先选中匹配的组、realm、域或网关。 |
cookie | string | (unset) | <session cookie> | 已有的认证会话,会先于凭据认证尝试。格式取决于类型(如 AnyConnect 的 webvpn、Fortinet 的 SVPNCOOKIE、Network Connect 的 DSID);服务器拒绝时回退到常规登录。 |
token | *OpenConnectTokenOptions | (unset) | OpenConnectTokenOptions | 软件令牌(TOTP、HOTP、RSA SecurID)或 OIDC 访问令牌,用于应答令牌字段或 Bearer 认证。见下文。 |
reported_os | string | (from platform) | linux | linux-64 | win | mac-intel | android | apple-ios | 向 AnyConnect、GlobalProtect 与 Pulse 服务器报告的操作系统标识。默认取当前平台。 |
user_agent | string | (flavor-specific) | <string> | 向服务器报告的 User-Agent。默认值:兼容 AnyConnect 的 OpenConnect 代理标识(AnyConnect、Network Connect、Pulse、F5)、PAN GlobalProtect、Mozilla/5.0 SV1(Fortinet)。 |
version | string | v9.21 | <string> | 与 user_agent 分开报告的客户端版本;目前用于 AnyConnect XML 认证。 |
local_hostname | string | (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) | OpenConnectTNCCOptions | Network Connect 的 TNCC 合规检查处理。见下文。 |
fortinet_host_check | *OpenConnectFortinetHostCheckOptions | (disabled) | OpenConnectFortinetHostCheckOptions | 覆盖 Fortinet hostcheck 结果;仅当 hostcheck 非空时生效。见下文。 |
no_udp | bool | false | true | false | 禁用 DTLS / ESP 数据通道,全部流量走 TLS 通道。 |
dtls_local_port | uint16 | 0 | <port> | 直连 DTLS / ESP 数据通道的本地 UDP 端口;0 表示使用临时端口。 |
compression_disabled | bool | false | true | false | 禁用 AnyConnect 压缩协商。与 compression_mode: all 冲突。 |
compression_mode | string | stateless | stateless | all | AnyConnect 压缩模式:stateless 声明 oc-lz4 / lzs;all 还会为 CSTP 提供有状态的 deflate(DTLS 仍为无状态)。压缩可能泄露隧道内明文的信息。 |
ipv6_disabled | bool | false | true | false | 不请求也不使用 IPv6 隧道配置。 |
http_keepalive_disabled | bool | false | true | false | 在认证与配置请求期间禁用 HTTP 连接复用。 |
xml_post_disabled | bool | false | true | false | 跳过 AnyConnect XML POST 认证,改用旧的 GET 流程开始认证。 |
external_auth_disabled | bool | false | true | false | 为 AnyConnect、GlobalProtect 与 Fortinet 禁用外部浏览器认证(SSO / SAML);意外的外部认证请求会被拒绝。 |
password_authentication_disabled | bool | false | true | false | 当服务器返回非成功表单时中止 AnyConnect 认证(类似 OpenConnect 的 --no-passwd)。不影响其他类型或 cookie。 |
tcp_keep_alive_enabled | bool | false | true | false | 为直连 VPN 服务器的连接启用 TCP keep-alive(与 OpenConnect 一样默认关闭)。设置 tcp_keep_alive 或 tcp_keep_alive_interval 也会启用它。 |
pfs | bool | false | true | false | 对 TLS 1.2 及更早版本要求具备前向保密的加密套件。默认关闭,以兼容需要 RSA 密钥交换的服务器。 |
mtu | uint32 | 0 | <576-65535> | 首选隧道 MTU;协商得到的 MTU 以此为上限(0 表示按协商)。小于 576 的非零值按 576 处理。 |
base_mtu | uint32 | 1406 | <1280-65535> | 用于在扣除外层开销后推算隧道 MTU 的路径 MTU(AnyConnect、GlobalProtect、F5、Fortinet)。小于 1280 的值按 1280 处理。 |
dpd_interval | badoption.Duration | (server-provided) | <duration> | 覆盖 Dead Peer Detection 间隔。小于 2s 的正值按 2s 处理。 |
reconnect_timeout | badoption.Duration | 300s | <duration> | 重连失败时累计退避时间的上限;第一次重试立即进行。 |
trojan_interval | badoption.Duration | (server-provided) | <duration> | GlobalProtect HIP 报告 / Network Connect TNCC 检查的间隔。服务器未提供时,GlobalProtect 使用 1h。 |
queue_length | uint32 | 32 | <packets> | VPN 传输与隧道接口之间的数据包队列长度。队列满时施加背压,而不是丢弃数据包。 |
allow_insecure_crypto | bool | false | true | false | 为旧服务器允许弱 TLS / DTLS 加密套件与 TLS 1.0。不会禁用证书校验。 |
tls | OpenConnectTLSOptions | (system trust) | OpenConnectTLSOptions | OpenConnect 专用的 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
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
mode | string | (required) | totp | hotp | stoken | oidc | 令牌类型:TOTP、HOTP、RSA SecurID 软件令牌(stoken),或作为 HTTP Bearer 认证发送的 OIDC 访问令牌。 |
secret | string | (unset) | <secret> | 令牌密钥:TOTP / HOTP 使用 Base32、带 base32: 前缀的值或 otpauth:// URI;stoken 使用 CTF 令牌内容;oidc 使用访问令牌(仅在服务器要求 Bearer 认证时发送)。secret 与 secret_path 二者必填其一。 |
secret_path | string | (unset) | <file path> | 从文件读取密钥或 OIDC 访问令牌。与 secret 冲突。 |
pin | string | (unset) | <PIN> | RSA SecurID 的 PIN(stoken)。 |
password | string | (unset) | <string> | 用于解密受密码保护的 SecurID 令牌的密码(stoken)。 |
device_id | string | (unset) | <string> | 用于解密绑定设备的 SecurID 令牌的设备 ID(stoken)。 |
counter | uint64 | 0 | <uint64> | HOTP 初始计数器;为 0 时,若存在 otpauth:// URI 则使用其中的计数器。 |
源码: option/openconnect.go:51-59 · 锚定版本 v1.14.2 (af6e64c)
tls
OpenConnect 使用自己的 TLS 块,而非通用的 TLS 选项——这里没有 uTLS、REALITY 或 ECH。
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
insecure | bool | false | true | false | 跳过服务器证书与主机名校验。这会让主动攻击者冒充服务器;应优先使用 certificate_authority 或 peer_fingerprint。 |
server_name | string | (host from server) | <hostname> | SNI 以及证书校验所用的名称。 |
peer_fingerprint | badoption.Listable[string] | (unset) | <SHA-1 hex> | sha1:<hex> | sha256:<hex> | pin-sha256:<base64> | 允许的服务器证书指纹:不带前缀的 SHA-1 证书哈希(同 OpenConnect 的 --servercert)或 SPKI 哈希。可使用至少 4 个字符的前缀;匹配后可授权本不受信任的证书。 |
system_trust_disabled | bool | false | true | false | 忽略系统 CA 证书池;改用 certificate_authority 或 peer_fingerprint 建立信任。 |
certificate_authority | badoption.Listable[string] | (unset) | <PEM> | 额外信任的 CA 证书(PEM 内容),会加入系统证书池。与 certificate_authority_path 冲突。 |
certificate_authority_path | string | (unset) | <file path> | 从 PEM 文件读取的额外信任 CA 证书。 |
client_certificate | badoption.Listable[string] | (unset) | <PEM> | 客户端证书链(PEM 内容)。证书与私钥必须同时设置。 |
client_certificate_path | string | (unset) | <file path> | 从 PEM 文件读取的客户端证书链。 |
client_key | badoption.Listable[string] | (unset) | <PEM> | 客户端私钥(PEM 内容)。 |
client_key_path | string | (unset) | <file path> | 从 PEM 文件读取的客户端私钥。 |
client_key_password | string | (unset) | <string> | 加密客户端私钥的密码。 |
mca_certificate | badoption.Listable[string] | (unset) | <PEM> | AnyConnect 多证书认证(MCA)的证书链(PEM 内容)。证书与私钥必须同时设置。 |
mca_certificate_path | string | (unset) | <file path> | 从 PEM 文件读取的 MCA 证书链。 |
mca_key | badoption.Listable[string] | (unset) | <PEM> | MCA 私钥(PEM 内容)。 |
mca_key_path | string | (unset) | <file path> | 从 PEM 文件读取的 MCA 私钥。 |
mca_key_password | string | (unset) | <string> | 加密 MCA 私钥的密码。 |
源码: option/openconnect.go:93-110 · 锚定版本 v1.14.2 (af6e64c)
form_entries
条目按 submission_key 匹配,或按 form_id 加 name 匹配;后出现的匹配项优先。
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
form_id | string | (unset) | <string> | 表单标识;当 submission_key 为空时与 name 一起匹配。 |
submission_key | string | (unset) | <string> | 字段的提交键。需要设置它,或同时设置 form_id 与 name;后出现的匹配项优先。 |
name | string | (unset) | <string> | 字段名,与 form_id 一起匹配。 |
value | string | (unset) | <string> | 自动填入的值。与 promote 冲突。 |
promote | bool | false | true | false | 以交互方式询问该字段,而不是自动填写。与 value 冲突。 |
源码: option/openconnect.go:112-118 · 锚定版本 v1.14.2 (af6e64c)
tncc
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
wrapper_path | string | (built-in) | <file path> | 外部 TNCC 包装程序的路径。与其他所有 tncc 字段冲突。 |
device_id | string | (unset) | <string> | 内置处理器报告的设备 ID。 |
user_agent | string | Neoteris HC Http | <string> | 内置处理器使用的 User-Agent。 |
machine_identification_enabled | bool | false | true | 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
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
hostcheck | string | (unset) | <status>,<os-version> | Hostcheck 结果字符串,例如 0100,10.0.19042——四个 0/1 标志依次表示第三方防火墙、第三方杀毒、FortiClient 防火墙与 FortiClient 杀毒,其后为系统版本。为空则禁用 hostcheck。 |
check_virtual_desktop | string | (empty) | <MAC>|<MAC>… | 虚拟桌面检查结果,惯例为以 | 连接的 MAC 地址。未设置时作为空字段提交。 |
源码: option/openconnect.go:83-86 · 锚定版本 v1.14.2 (af6e64c)
mobile
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
platform_version | string | (required) | <string> | 向 AnyConnect 服务器报告的移动操作系统版本。 |
device_type | string | (required) | <string> | 设备型号或类型。 |
device_unique_id | string | (required) | <string> | 设备标识符。 |
源码: option/openconnect.go:61-65 · 锚定版本 v1.14.2 (af6e64c)
DNS 服务器
dns.servers[] 中的 type: "openconnect":
| 字段 | 类型 | 默认值 | 允许值 | 描述 |
|---|---|---|---|---|
endpoint | string | (required) | <endpoint tag> | OpenConnect 端点的 tag。查询会发往 VPN 服务器推送的解析器:split-DNS 规则使用各自的解析器,推送的 split-DNS 与搜索域后缀使用通用解析器,最具体的后缀优先。 |
accept_default_resolvers | bool | false | true | false | 对未匹配的查询也使用推送的通用解析器——仅当服务器要求所有 DNS 走隧道,或未推送 split-DNS 规则与后缀时。否则未匹配的查询返回 NXDOMAIN。 |
accept_search_domain | bool | false | true | false | 对单标签名称(如 intranet)依次拼接推送的各个搜索域重试,直到解析成功。 |
源码: option/openconnect.go:120-124 · 锚定版本 v1.14.2 (af6e64c)
示例
最简 AnyConnect 客户端,把一个私有网段路由到 VPN:
{
"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 域名:
{
"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 设置不会安装到操作系统中。要使用它们,请添加
openconnectDNS 服务器;像上例那样配合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)
