Система Ринго подразумевает использование встроенного веб-сервера, а также автоматический выпуск SSL-сертификатов Let's Encrypt.
Тем не менее, система предусматривает работу за уже существующим Reverse Proxy, который будет отвечать за терминацию SSL.
Прокси-сервер должен поддерживать TLS 1.2 и TLS 1.3.

Ниже перечислены все основные конечные точки (endpoints), которые необходимо проксировать через внешний веб-сервер.
Каждый из них обеспечивает корректную работу определённых компонентов системы.
| Эндпоинт | Назначение |
|---|---|
| /scep | Используется для взаимодействия с протоколом SCEP (Simple Certificate Enrollment Protocol). На этот адрес устройства отправляют запросы для получения сертификатов, необходимых для безопасного взаимодействия. |
| /mdm/connect | Конечная точка, на которую устройства устанавливают соединение с сервером для получения команд MDM (Mobile Device Management). |
| /mdm/checkin | Эндпоинт, куда устройства периодически отправляют информацию о своём состоянии, а также подтверждают выполнение команд MDM. |
| Эндпоинт | Назначение |
|---|---|
| /socket.io/ | Используется для поддержания постоянного websocket-соединения агента с сервером. Через этот канал обеспечивается обмен событиями и командами в реальном времени. |
| /agent/bundle | Позволяет скачать пакет агента (дистрибутив с исполняемыми файлами). |
| /agent/manifest | Файл манифеста агента. Содержит информацию о составе пакета и его версии, необходим для проверки актуальности установленного агента. |
| /agent/certificate | Получить сертификат идентификации агента устройства |
| /agent/checkin | |
| /agent/connect |
| Эндпоинт | Назначение |
|---|---|
| /mdm/enroll | Позволяет скачать MDM-профиль для регистрации устройства в системе. |
| /enroll | Веб-страница, с которой пользователь инициирует установку профиля. Служит удобным интерфейсом, перенаправляющим к /mdm/enroll. |
| /mdm/enroll/profile | Используется при установке профиля «по воздуху» (OTA, Over-The-Air). |
| /api/v1/auth | Конечная точка для выполнения аутентификации пользователей на странице регистрации устройства. |
| Эндпоинт | Назначение |
|---|---|
| /api/v1/self-service | Обеспечивает работу портала самообслуживания. Через этот эндпоинт Self Service обращается к серверу Ринго для выполнения запросов. |
| Эндпоинт | Назначение |
|---|---|
| /scep-proxy | Проксирует запросы между клиентами и внешним SCEP-сервером. Используется в случаях, когда невозможно обеспечить сетевую доступность конечных устройств до основного SCEP-сервера. |
Инструкция по настройке nginx для socket.io представлена на официальном сайте
Ниже представлена типовая конфигурация веб-сервера nginx, в рамках которой доступ к веб-интерфейсу Ринго предоставлен только для одной подсети —
172.10.20.0/24.
Все остальные конечные точки, необходимые для работы системы, доступны с любых IP-адресов.
server {
server_name mdm.mydomain.com;
location / {
proxy_pass http://172.10.20.225:5000/;
allow 172.10.20.0/24;
deny all;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /socket.io {
proxy_pass http://172.10.20.225: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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /mdm {
proxy_pass http://172.10.20.225:5000/mdm;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /scep {
proxy_pass http://172.10.20.225:5000/scep;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /enroll {
proxy_pass http://172.10.20.225:5000/enroll;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /agent {
proxy_pass http://172.10.20.225:5000/agent;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /api/v1/auth {
proxy_pass http://172.10.20.225:5000/api/v1/auth;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
location /api/v1/self-service {
proxy_pass http://172.10.20.225:5000/api/v1/self-service;
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-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_buffering off;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
listen 443 ssl;
ssl_certificate /etc/ssl/mdm.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/ssl/mdm.mydomain.com/privkey.pem;
include /etc/ssl/options-ssl-nginx.conf;
ssl_dhparam /etc/ssl/ssl-dhparams.pem;
}
server {
if ($host = mdm.mydomain.com) {
return 301 https://$host$request_uri;
}
listen 80;
server_name mdm.mydomain.com;
return 404;
}
Поскольку за работу с SSL в случае использования внешнего реверс-прокси будет отвечать он же, необходимо отредактировать файл docker-compose.yml перед развертыванием системы.
Ниже показаны строки, которые нужно удалить перед тем, как разворачивать систему:
nginx-proxy:
image: jwilder/nginx-proxy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- /apps/docker-articles/nginx/vhost.d:/etc/nginx/vhost.d
- /apps/docker-articles/nginx/certs:/etc/nginx/certs:ro
- /apps/docker-articles/nginx/html:/usr/share/nginx/html
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion:latest
restart: always
depends_on:
- nginx-proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /apps/docker-articles/nginx/vhost.d:/etc/nginx/vhost.d
- /apps/docker-articles/nginx/certs:/etc/nginx/certs:rw
- /apps/docker-articles/nginx/html:/usr/share/nginx/html
Обратите внимание, что в случае отказа от данных контейнеров, сервер будет слушать порт 5000.