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. Сопутствующий DNS-сервер openconnect разрешает имена через DNS-настройки, переданные VPN-сервером.
Конечная точка, только клиент
OpenConnect находится в корневом массиве endpoints[], как WireGuard и Tailscale, и указывается в правилах маршрутизации по тегу. Реализована только клиентская сторона.
Параметры конечной точки
type: "openconnect" в endpoints[]:
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
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 означает 4096 на iOS и 4096–16384 (по объёму памяти) на остальных платформах. |
server | string | (required) | <hostname or https:// URL> | HTTPS-URL VPN-сервера; при отсутствии https:// добавляется автоматически. Данные пользователя, строка запроса и фрагмент не поддерживаются. |
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> | Уже аутентифицированная сессия, пробуемая до запроса учётных данных. Формат зависит от семейства (например, webvpn для AnyConnect, SVPNCOOKIE для Fortinet, DSID для Network Connect); если сервер её отклоняет, выполняется обычный вход. |
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; сейчас используется XML-аутентификацией AnyConnect. |
local_hostname | string | (system hostname) | <string> | Имя хоста, сообщаемое серверу; localhost, если системное имя недоступно. |
mobile | *OpenConnectMobileOptions | (unset) | OpenConnectMobileOptions | Сообщать идентичность мобильного клиента AnyConnect. Если задано, все три подполя обязательны. См. ниже. |
csd | *OpenConnectCSDOptions | (built-in) | { wrapper_path } | Обработка CSD / host scan в AnyConnect. По умолчанию встроенная; wrapper_path запускает вместо неё внешнюю программу-обёртку. |
hip | *OpenConnectHIPOptions | (built-in) | { wrapper_path } | Обработка отчётов HIP в GlobalProtect. По умолчанию встроенная; wrapper_path запускает вместо неё внешнюю программу-обёртку. |
tncc | *OpenConnectTNCCOptions | (built-in) | OpenConnectTNCCOptions | Обработка проверок соответствия TNCC в Network Connect. См. ниже. |
fortinet_host_check | *OpenConnectFortinetHostCheckOptions | (disabled) | OpenConnectFortinetHostCheckOptions | Переопределение результата hostcheck Fortinet; действует, только если hostcheck не пуст. См. ниже. |
no_udp | bool | false | true | false | Отключить канал данных DTLS / ESP и передавать весь трафик через канал TLS. |
dtls_local_port | uint16 | 0 | <port> | Локальный UDP-порт прямого канала данных DTLS / ESP; 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 | Пропустить XML POST-аутентификацию AnyConnect и начать с устаревшего GET-процесса. |
external_auth_disabled | bool | false | true | false | Отключить аутентификацию через внешний браузер (SSO / SAML) для AnyConnect, GlobalProtect и Fortinet; неожиданные запросы внешней аутентификации отклоняются. |
password_authentication_disabled | bool | false | true | false | Прерывать аутентификацию AnyConnect, если сервер возвращает форму без успеха (как --no-passwd в OpenConnect). Не влияет на другие семейства и на cookie. |
tcp_keep_alive_enabled | bool | false | true | false | Включить TCP keep-alive для прямых соединений с VPN-сервером (по умолчанию выключен, как в 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> | Интервал между отчётами HIP GlobalProtect / проверками TNCC Network Connect. Если сервер его не передаёт, 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 | Собственные настройки TLS для OpenConnect (не общий блок TLS sing-box). См. ниже. |
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) или токен доступа OIDC, отправляемый как HTTP Bearer-аутентификация. |
secret | string | (unset) | <secret> | Секрет токена: для TOTP / HOTP — Base32, значение с префиксом base32: или URI otpauth://; для stoken — содержимое CTF-токена; для oidc — токен доступа (отправляется только по запросу Bearer-аутентификации сервером). Обязательно одно из secret / secret_path. |
secret_path | string | (unset) | <file path> | Читать секрет или токен доступа OIDC из файла. Конфликтует с secret. |
pin | string | (unset) | <PIN> | PIN для RSA SecurID (stoken). |
password | string | (unset) | <string> | Пароль для расшифровки защищённого паролем токена SecurID (stoken). |
device_id | string | (unset) | <string> | Идентификатор устройства для расшифровки привязанного к устройству токена SecurID (stoken). |
counter | uint64 | 0 | <uint64> | Начальный счётчик HOTP; при 0 используется счётчик из URI otpauth://, если он есть. |
Исходный код: 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-хеш сертификата без префикса (как --servercert в OpenConnect) или хеши 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> | Дополнительные доверенные сертификаты CA из PEM-файла. |
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> | Цепочка сертификатов для многосертификатной аутентификации (MCA) AnyConnect (содержимое PEM). Сертификат и ключ задаются вместе. |
mca_certificate_path | string | (unset) | <file path> | Цепочка сертификатов MCA из PEM-файла. |
mca_key | badoption.Listable[string] | (unset) | <PEM> | Закрытый ключ MCA (содержимое PEM). |
mca_key_path | string | (unset) | <file path> | Закрытый ключ MCA из PEM-файла. |
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> | Идентификатор устройства, сообщаемый встроенным обработчиком. |
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-сервер
type: "openconnect" в dns.servers[]:
| Поле | Тип | По умолчанию | Допустимые значения | Описание |
|---|---|---|---|---|
endpoint | string | (required) | <endpoint tag> | Тег конечной точки OpenConnect. Запросы идут к резолверам, переданным 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" }
]
}
}GlobalProtect с токеном TOTP, отвечающий на split-DNS-имена VPN через переданные резолверы:
{
"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-настройки никогда не устанавливаются в операционную систему. Чтобы использовать их, добавьте DNS-сервер
openconnect; с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)
