Эта страница поможет, если другие страницы раздела указали на сеть или устройства не могут подключиться к серверу Ринго или к Apple. Для проверок нужны
curl,openssl,ncиdig(они есть в macOS и большинстве дистрибутивов Linux). Запускайте проверки из той сети, в которой возникает проблема, то есть из сети устройств, а не с сервера: иначе вы проверите другой маршрут.
Устройства и агенты ──HTTPS, WSS 443──▶ Reverse proxy ──▶ backend :5000 ──▶ PostgreSQL
Устройства ──TCP 5223 (443)──▶ Apple APNs ◀──HTTP/2 443── backend (с сервера Ринго)
Устройства ──SMB 445 / HTTPS──▶ точка распространения пакетов
Сервер Ринго ──389 / 636──▶ LDAP (при интеграции с LDAP)
Администраторы ──HTTPS 443──▶ веб-интерфейс (рекомендуется открыть только для подсети администраторов)
Следующие пути должны быть доступны из всех сетей, где работают устройства, в том числе из интернета, если устройства используются за пределами офиса:
| Путь | Кто обращается | Последствия, если путь закрыт |
|---|---|---|
/mdm/checkin (PUT) |
Устройства: регистрация, передача push-токена, снятие с учёта. | Регистрация прерывается, push-токен не обновляется. |
/mdm/connect (PUT) |
Устройства: получение команд и передача результатов. | Команды и профили не доставляются. |
/scep |
Устройства: получение сертификата при регистрации. | Профиль регистрации не устанавливается. |
/mdm/enroll, /mdm/enroll/profile |
Устройства: скачивание и установка профиля регистрации. | Профиль не скачивается или не устанавливается. |
/enroll и всё под ним, включая /enroll/auth |
Пользователь: страница регистрации и вход на ней. | Страница «Привязать» не открывается или вход не выполняется. |
/socket.io/ (websocket) |
Агент. | Агент не подключается к серверу. |
/agent/ и всё под ним (bundle, manifest, checkin, connect, certificate, enroll) |
Агент: установка, обновление, регистрация. | Агент не устанавливается, не обновляется или не регистрируется. |
/api/v1/self-service и всё под ним |
Self Service. | Self Service не работает. |
/scep-proxy |
Только при включённом SCEP Proxy. | Сертификаты внешнего удостоверяющего центра не выдаются. |
Только для подсети администраторов открывайте / (веб-интерфейс) и остальные пути /api/v1/…. Частая ошибка: общий блок location / с ограничением allow/deny закрывает и пути устройств, если для них не созданы отдельные блоки location.
Требования: TLS 1.2 и 1.3, сертификат на домен Ринго, полная цепочка сертификатов.
echo | openssl s_client -connect <домен>:443 -servername <домен> -showcerts 2>/dev/null \
| grep -E '^ *[0-9] s:|^ +i:|Verify return code'
| Результат | Проблема | Решение |
|---|---|---|
Один сертификат (0 s:) |
Цепочка неполная: устройства и агенты не загружают промежуточный сертификат сами и не устанавливают соединение. | Укажите в ssl_certificate полную цепочку (fullchain): сначала сертификат сервера, затем промежуточный. |
В s: не ваш домен |
Прокси отдаёт сертификат по умолчанию: для вашего домена сертификата нет. | Для встроенного nginx-proxy проверьте переменные VIRTUAL_HOST и LETSENCRYPT_HOST и логи acme-companion. Для собственного nginx проверьте server_name. |
Verify return code: 10 |
Сертификат истёк. | Выпустите сертификат заново. Для Let's Encrypt проверьте автоматическое продление. |
Самоподписанный сертификат сразу у всех, по HTTP — 503 |
При встроенном nginx-proxy: backend остановлен, и прокси перестал обслуживать сайт. |
Выполните docker ps -a (см. Сервер → контейнеры). |
| Корневой сертификат «Russian Trusted Root CA» или другой корпоративный | Корень не входит в список доверенных на устройствах. | Установите корневой сертификат на устройства профилем. |
Обновляя сертификат, замените его на всех узлах: прокси, балансировщиках, CDN. Если на разных узлах разные сертификаты, проблема проявляется только на части устройств.
Минимальная конфигурация nginx для путей Ринго:
location /socket.io/ {
proxy_pass http://<backend>:5000/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
proxy_read_timeout 3600s; # иначе соединение агента разрывается по таймауту
proxy_send_timeout 3600s;
}
location /mdm {
proxy_pass http://<backend>:5000/mdm;
client_max_body_size 50m; # ответы устройств (списки ПО и сертификатов) бывают большими, значение с запасом
…
}
Полная конфигурация приведена в документации Ринго, раздел «Reverse Proxy».
| Симптом | Причина на прокси |
|---|---|
Почти все пути возвращают 503 или 502 |
Backend не запущен или proxy_pass указывает на неверный адрес. |
404 от nginx на путях устройств |
Для пути нет блока location. |
GET /mdm/... возвращает HTML веб-интерфейса |
Директива try_files … /index.html перехватывает пути API. |
Соединение websocket не переключается (код не 101) |
Нет заголовков Upgrade и Connection или до backend используется HTTP/1.0. |
| Агент отключается через одинаковые короткие интервалы | Таймаут бездействия прокси или балансировщика короче 25 с: сервер отправляет ping каждые 25 с. |
413 на /mdm/connect |
Ограничение client_max_body_size. |
WAF перед Ринго может быть причиной того, что регистрация, установка и удаление профилей не работают, хотя сервер исправен. Протокол MDM непривычен для WAF, при этом защищать эти пути с помощью WAF не требуется: запросы устройств подписаны сертификатом устройства.
Что блокирует WAF (ModSecurity с OWASP CRS и аналогичные решения):
PUT. Правило 911100 по умолчанию разрешает только GET, HEAD, POST и OPTIONS, поэтому MDM не работает целиком.application/x-apple-aspen-mdm-checkin, application/x-apple-aspen-mdm, application/pkcs7-signature. Правило 920420 отклоняет их как не разрешённые политикой.ProfileList, CertificateList, InstalledApplicationList могут превышать 128 КБ (значение SecRequestBodyNoFilesLimit по умолчанию): у тестового Mac с тремя сотнями программ ответ занимает около 200 КБ. Признак — код 413 или сообщение «Request body … exceeded».SecResponseBodyAccess On) может обрезать или заблокировать большой ответ с командой.Как подтвердить, что запросы блокирует WAF. В логе WAF или nginx за время проблемы есть запрос PUT /mdm/connect или PUT /mdm/checkin с кодом 403, 406 или 413 и идентификатором правила, а в логе backend этого запроса нет. Для окончательной проверки временно переведите WAF в режим SecRuleEngine DetectionOnly для /mdm/: если всё заработало, причина в WAF.
Решение. Исключите из WAF (или переведите в режим DetectionOnly) пути /mdm/checkin, /mdm/connect, /mdm/enroll/profile и /scep. Если полностью исключить их нельзя, разрешите метод PUT, добавьте типы содержимого Apple в список разрешённых, увеличьте лимиты размера запроса и ответа и отключите инспекцию ответов на этих путях.
Проверка без устройства. Отправьте запрос, похожий на настоящий check-in: с plist, методом PUT и типом содержимого Apple. UDID в запросе заведомо несуществующий, поэтому Ринго ничего не создаст:
Создайте файл checkin.plist с таким содержимым:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>MessageType</key><string>Authenticate</string>
<key>UDID</key><string>00000000-0000000000TEST</string>
</dict></plist>
Отправьте его на сервер из той же папки:
curl -s -X PUT -H 'Content-Type: application/x-apple-aspen-mdm-checkin' --data-binary @checkin.plist -w '\n%{http_code}\n' https://<домен>/mdm/checkin
Оценивайте тело ответа, а не только код. Ринго 3.0.5 отвечает так:
{"message":"Отсутствует устройство с udid '00000000-0000000000test'","error":"Forbidden","statusCode":403,…}
403
Это JSON от самого Ринго: запрос прошёл через WAF и прокси. Если вместо него пришла HTML-страница блокировки, код 403 или 406 без такого JSON либо соединение было сброшено, запрос блокирует WAF.
Лимиты размера запроса и ответа проверяйте по настройкам прокси и WAF (client_max_body_size, SecRequestBodyNoFilesLimit, SecResponseBodyLimit).
Push отправляет контейнер backend по HTTP/2 на api.push.apple.com:443. Порт 2197 Ринго не использует. Серверу нужен исходящий доступ к 17.0.0.0/8 по порту 443 без SSL-inspection.
curl -s --http2 -X POST https://api.push.apple.com/3/device/0 -w ' %{http_code}\n'
# ожидаемый ответ: {"reason":"MissingProviderToken"} 403
Если сервер выходит в интернет через прокси. Стандартные переменные HTTPS_PROXY и NO_PROXY backend не использует. Для обращений к Apple предназначена отдельная переменная APPLE_PROXY_URL: через указанный в ней прокси отправляются push (api.push.apple.com) и выполняется поиск приложений в App Store, а остальные соединения устанавливаются напрямую. Прокси должен поддерживать метод CONNECT к api.push.apple.com:443 и не расшифровывать TLS.
Переменную нужно передать именно контейнеру backend. Значения из .env не попадают в контейнер автоматически, поэтому добавьте переменную в раздел environment: сервиса backend в файле docker-compose.yml:
backend:
environment:
APPLE_PROXY_URL: ${APPLE_PROXY_URL}
# /etc/ringo/.env
APPLE_PROXY_URL=http://proxy.example.com:3128 # или http://логин:пароль@proxy:3128, или https://…
Затем выполните cd /etc/ringo && docker compose up -d. Ошибки прокси записываются в лог backend: Apple proxy CONNECT api.push.apple.com:443 failed: …, Apple proxy CONNECT … timed out after …ms, Apple proxy TLS connection to … failed.
Проверяйте соединение именно из контейнера, а не с хоста: у них могут быть разные настройки DNS и выхода в интернет. Сначала проверьте, что контейнер разрешает имя Apple:
docker exec roll-deploy-backend nslookup api.push.apple.com
В ответе должны быть адреса Apple: IPv4 из сети 17.0.0.0/8 и, возможно, IPv6. Затем проверьте, что контейнер может установить соединение:
docker exec roll-deploy-backend nc -zv -w 5 api.push.apple.com 443
Ожидаемый результат — api.push.apple.com (17.…:443) open. Если имя не разрешается, проверьте DNS сервера и Docker. Если соединение не устанавливается, исходящий трафик к Apple закрыт, и нужен APPLE_PROXY_URL. Проверка выполняется напрямую, без исходящего прокси.
Чтобы убедиться, что прокси на пути не расшифровывает TLS, выполните на сервере:
echo | openssl s_client -connect api.push.apple.com:443 -servername api.push.apple.com 2>/dev/null | grep '^issuer='
Издателем должна быть Apple. Если указан другой издатель, TLS расшифровывает прокси.
Если используются соответствующие функции, нужен также доступ к identity.apple.com (портал APNs-сертификатов, с компьютера администратора), mdmenrollment.apple.com (ADE) и vpp.itunes.apple.com (Apps and Books).
Из всех сетей устройств должны быть доступны TCP-порты 5223 и 443 к 17.0.0.0/8. Если порт 5223 закрыт, push работают только через порт 443 и только в Wi-Fi.
nc -vz -G 5 courier.push.apple.com 5223 # macOS
nc -vz -w 5 courier.push.apple.com 5223 # Linux
echo | openssl s_client -connect courier.push.apple.com:5223 2>/dev/null | grep '^issuer=' # издатель должен быть Apple
Для регистрации и работы устройств также нужны albert.apple.com (активация), captive.apple.com (проверка captive-портала), а также серверы OCSP и CRL Apple и DigiCert. SSL-inspection на адресах Apple нарушает работу устройств, поэтому исключите *.apple.com и 17.0.0.0/8 из инспекции. Полный список адресов и портов приведён в статье Apple support.apple.com/101555. Сертификаты всех адресов Apple должны быть выданы Apple или DigiCert; если издатель другой, TLS расшифровывает прокси.
Если имя сервера Ринго внутри сети и снаружи разрешается в разные адреса (split-horizon DNS):
dig +short <домен> # системный DNS
dig +short <домен> @77.88.8.8 # публичный DNS
Проверьте каждый полученный адрес отдельно, указав его явно:
curl -s -o /dev/null -w '%{http_code}\n' --resolve <домен>:443:<IP> https://<домен>/agent/manifest
echo | openssl s_client -connect <IP>:443 -servername <домен> 2>/dev/null | openssl x509 -noout -fingerprint -sha256 -enddate
Коды ответа и отпечатки сертификата на всех адресах должны совпадать.
Если всё работает, но с перерывами, в определённое время суток или только у части устройств, возможные причины такие:
| Причина | Признак | Проверка |
|---|---|---|
| DPI или ТСПУ | Соединения разрываются или передача данных останавливается, пакет агента не загружается целиком. | Загрузите пакет агента несколько раз (см. ниже) и повторите через другого провайдера. |
| MTU (потеря крупных пакетов) | TCP-соединение устанавливается, но большие ответы (цепочка сертификатов, профиль, пакет агента) не приходят. Часто встречается при VPN, GRE, PPPoE. | Ping с запретом фрагментации (см. ниже); настройка MSS clamping на туннеле. |
| Неисправный узел за балансировщиком или в DNS | Ошибки только у части устройств, разные сертификаты. | Проверьте каждый адрес отдельно через --resolve (см. DNS внутри сети и снаружи). |
| VPN в сети устройства | Работа зависит от того, включён ли VPN. | Повторите проверки с VPN и без него. |
| Таймауты прокси | Агент часто переподключается. | Частота записей Disconnected: <UDID> в логе backend (см. Связь агента с сервером → шаг 2). |
Проверка обрыва передачи (DPI). Пакет агента весит около 800 КБ и должен загружаться полностью при каждой попытке. Выполните команду три раза подряд:
curl -s -m 40 --speed-time 8 --speed-limit 1 -o /dev/null -w '%{http_code} %{size_download} байт\n' https://<домен>/agent/bundle
Ожидаемый результат — 200 и полный размер пакета (в 3.0.5 — 814 718 байт). Если загрузка каждый раз останавливается на одном и том же размере, передачу данных останавливает оборудование на пути.
Проверка MTU. Определите наибольший пакет, который проходит без фрагментации (1472 + 28 = 1500 байт):
ping -D -s 1472 -c 2 <домен> # macOS
ping -M do -s 1472 -c 2 <домен> # Linux
Если пакет не проходит, уменьшайте размер, пока он не пройдёт; найденное значение плюс 28 — это MTU маршрута. Если ICMP закрыт, признак проблемы с MTU — запрос curl к /agent/bundle сразу останавливается, а небольшие ответы приходят.
Наблюдение за периодическими сбоями. Повторяйте в сети устройств запрос, который выводит код ответа, IP-адрес ответившего узла и время ответа, например добавьте его в систему мониторинга с интервалом 10 секунд:
curl -s -o /dev/null -m 10 -w '%{http_code} %{remote_ip} %{time_total}s\n' https://<домен>/agent/manifest
Код 000 означает отсутствие ответа, 5xx — ошибку на сервере. По IP-адресу видно, приходят ли ошибки от одного и того же узла.
Обратитесь в техническую поддержку (см. Обращение в поддержку).
Проверено на Ринго 3.0.5, октябрь 2026. Тексты ошибок — Справочник ошибок, термины — Термины.