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. Сопутствующий DNS-сервер openconnect разрешает имена через DNS-настройки, переданные VPN-сервером.

Конечная точка, только клиент

OpenConnect находится в корневом массиве endpoints[], как WireGuard и Tailscale, и указывается в правилах маршрутизации по тегу. Реализована только клиентская сторона.

Параметры конечной точки ​

type: "openconnect" в endpoints[]:

ПолеТипПо умолчаниюДопустимые значенияОписание
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_dependentОтображение UDP NAT: одно отображение на источник для всех назначений либо отдельное для каждого адреса / адреса и порта назначения.
udp_filteringUDPNATBehaviorendpoint_independentendpoint_independent | address_dependent | address_and_port_dependentФильтрация UDP NAT: принимать ответы от любого удалённого узла или только от уже использованных адресов / пар адрес-порт.
udp_nat_maxuint320<count>Максимальное число сессий UDP NAT; при достижении предела закрывается давно не использовавшаяся. 0 означает 4096 на iOS и 4096–16384 (по объёму памяти) на остальных платформах.
serverstring(required)<hostname or https:// URL>HTTPS-URL VPN-сервера; при отсутствии https:// добавляется автоматически. Данные пользователя, строка запроса и фрагмент не поддерживаются.
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>Уже аутентифицированная сессия, пробуемая до запроса учётных данных. Формат зависит от семейства (например, webvpn для AnyConnect, SVPNCOOKIE для Fortinet, DSID для Network Connect); если сервер её отклоняет, выполняется обычный вход.
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; сейчас используется XML-аутентификацией AnyConnect.
local_hostnamestring(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_udpboolfalsetrue | falseОтключить канал данных DTLS / ESP и передавать весь трафик через канал TLS.
dtls_local_portuint160<port>Локальный UDP-порт прямого канала данных DTLS / ESP; 0 — эфемерный порт.
compression_disabledboolfalsetrue | falseОтключить согласование сжатия AnyConnect. Конфликтует с compression_mode: all.
compression_modestringstatelessstateless | allСжатие AnyConnect: stateless предлагает oc-lz4 / lzs; all добавляет для CSTP deflate с состоянием (DTLS остаётся без состояния). Сжатие может раскрывать сведения об открытом тексте в туннеле.
ipv6_disabledboolfalsetrue | falseНе запрашивать и не использовать конфигурацию туннеля IPv6.
http_keepalive_disabledboolfalsetrue | falseОтключить повторное использование HTTP-соединений при запросах аутентификации и конфигурации.
xml_post_disabledboolfalsetrue | falseПропустить XML POST-аутентификацию AnyConnect и начать с устаревшего GET-процесса.
external_auth_disabledboolfalsetrue | falseОтключить аутентификацию через внешний браузер (SSO / SAML) для AnyConnect, GlobalProtect и Fortinet; неожиданные запросы внешней аутентификации отклоняются.
password_authentication_disabledboolfalsetrue | falseПрерывать аутентификацию AnyConnect, если сервер возвращает форму без успеха (как --no-passwd в OpenConnect). Не влияет на другие семейства и на cookie.
tcp_keep_alive_enabledboolfalsetrue | falseВключить TCP keep-alive для прямых соединений с VPN-сервером (по умолчанию выключен, как в 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>Интервал между отчётами HIP GlobalProtect / проверками TNCC Network Connect. Если сервер его не передаёт, GlobalProtect использует 1h.
queue_lengthuint3232<packets>Длина очереди пакетов между транспортом VPN и интерфейсом туннеля. Заполненная очередь создаёт обратное давление, а не отбрасывает пакеты.
allow_insecure_cryptoboolfalsetrue | falseРазрешить слабые наборы шифров TLS / DTLS и TLS 1.0 для устаревших серверов. Проверку сертификата не отключает.
tlsOpenConnectTLSOptions(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 ​

ПолеТипПо умолчаниюДопустимые значенияОписание
modestring(required)totp | hotp | stoken | oidcТип токена: TOTP, HOTP, программный токен RSA SecurID (stoken) или токен доступа OIDC, отправляемый как HTTP Bearer-аутентификация.
secretstring(unset)<secret>Секрет токена: для TOTP / HOTP — Base32, значение с префиксом base32: или URI otpauth://; для stoken — содержимое CTF-токена; для oidc — токен доступа (отправляется только по запросу Bearer-аутентификации сервером). Обязательно одно из secret / secret_path.
secret_pathstring(unset)<file path>Читать секрет или токен доступа OIDC из файла. Конфликтует с secret.
pinstring(unset)<PIN>PIN для RSA SecurID (stoken).
passwordstring(unset)<string>Пароль для расшифровки защищённого паролем токена SecurID (stoken).
device_idstring(unset)<string>Идентификатор устройства для расшифровки привязанного к устройству токена SecurID (stoken).
counteruint640<uint64>Начальный счётчик HOTP; при 0 используется счётчик из URI otpauth://, если он есть.

Исходный код: 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-хеш сертификата без префикса (как --servercert в OpenConnect) или хеши 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>Дополнительные доверенные сертификаты CA из PEM-файла.
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>Цепочка сертификатов для многосертификатной аутентификации (MCA) AnyConnect (содержимое PEM). Сертификат и ключ задаются вместе.
mca_certificate_pathstring(unset)<file path>Цепочка сертификатов MCA из PEM-файла.
mca_keybadoption.Listable[string](unset)<PEM>Закрытый ключ MCA (содержимое PEM).
mca_key_pathstring(unset)<file path>Закрытый ключ MCA из PEM-файла.
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>Идентификатор устройства, сообщаемый встроенным обработчиком.
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-сервер ​

type: "openconnect" в dns.servers[]:

ПолеТипПо умолчаниюДопустимые значенияОписание
endpointstring(required)<endpoint tag>Тег конечной точки OpenConnect. Запросы идут к резолверам, переданным 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" }
    ]
  }
}

GlobalProtect с токеном TOTP, отвечающий на split-DNS-имена VPN через переданные резолверы:

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-настройки никогда не устанавливаются в операционную систему. Чтобы использовать их, добавьте 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)

Core Tutorial от Argsment