Каталог Поиск 0 Сравнить 0 Закладки 0 Корзина Войти
Каталог
105082, Москва, ул. Фридриха Энгельса, 75с21, БЦ Бауманский ИТКОЛ
Пн - Пт: с 09-00 до 18-00 Сб: с 10-00 до 18-00 Вс: выходной
Страницы: 1
RSS
Гостевой Captive Portal через обратный прокси Nginx?, UniFi Network
 
Всем привет! Мой Unifi контроллер работает за обратным прокси Nginx, и всё отлично (ниже добавлю конфиг сайта nginx для тех, кому интересно). Контроллер доступен по адресу unifi.url.com, nginx у меня обрабатывает HTTPS/SSL, и жизнь прекрасна. Но вот с гостевым captive portal всё оказалось не так просто. Есть ли способ сделать гостевую переадресацию без указания порта? Чтобы прокси сам управлял портом. То есть вместо того, чтобы отправлять пользователей на http://guest.url.com:8880 или https://guest.url.com:8843, хочу, чтобы их редиректило просто на http(s)://guest.url.com.

Инфраструктура такова:  
10.0.1.18 — мой обратный прокси Nginx.  
10.0.1.3 — сервер с установленным Unifi Controller.

В DNS прописаны записи, которые направляют guest.url.com и unifi.url.com на 10.0.1.18, чтобы nginx мог проксировать оба сайта. Для страницы Unifi контроллера всё работает отлично, а вот с гостевым captive portal — нет.

Поведение гостевой переадресации при использовании простого пароля таково, что пользователей отправляют на url.com:8880 (или :8843, если в config.properties включён HTTPS). Проблема в том, что пользователей направляет на мой Nginx-прокси (guest.url.com), что и нужно, но указанный порт — не 443, а 8880/8843. Вот красивый чистый URL с портом 443, который позволил бы nginx корректно проксировать запрос. А так как nginx не слушает на 8880 или 8843, запрос просто отбрасывается.

Буду признателен за помощь, чтобы настроить поведение так, как мне нужно.

Ниже мой конфиг nginx для unifi.url.com, который также заставляет использовать HTTPS:

server {  
 listen 80;  
 server_name unifi.url.com;  
 return 302 https://unifi.url.com$request_uri;  
}

server {  
 listen 443;  
 server_name unifi.url.com;  

 ssl_certificate /config/keys/url_com.pem;  
 ssl_certificate_key /config/keys/url_com.key;  
 ssl on;  
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  
 ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC4-SHA';  
 ssl_prefer_server_ciphers on;  
 ssl_dhparam /config/keys/dhparams.pem;  

 add_header X-Frame-Options SAMEORIGIN;  
 add_header X-XSS-Protection "1; mode=block";  
 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains";  

 location / {  
   proxy_pass https://10.0.1.3:8443/;  
 }  
}
 
Я пытаюсь настроить nginx, чтобы использовать мои сертификаты для SSL. У меня больше 10 сервисов, которые работают через nginx. Вместо того, чтобы обновлять сертификаты в 10 разных местах, я делаю это только в одном. К тому же, так не приходится открывать кучу портов в файрволе, ведь большинство моих настроек приходят только на 443 или 80. Единственная причина, почему я спрашиваю — не могу заставить работать гостевой портал и пытаюсь понять, где может быть проблема, как её исправить или есть ли альтернативы.
 
Извините, но если вы задаёте этот вопрос, скорее всего, вы вообще не понимаете, зачем пытаетесь настроить nginx как прокси для вашего контроллера...
 
Если nginx и контроллер unifi работают на одной машине, может ли nginx слушать порт, который уже используется unifi?
 
До недавнего времени у меня постоянно появлялась ошибка websocket, но после использования приведённой ниже конфигурации она больше не возникает. Именно добавление выделенной жирным части в разделе default location помогло решить мою проблему.

##Unifi Server##

server {
   listen [::]:80;
   listen 80;
   listen [::]:443 ssl;
   listen 443 ssl;
   server_name unifi.domain.com;

   ssl_session_timeout 30m;
   ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
   ssl_certificate cert.pem;
   ssl_certificate_key private.key;
   ssl_session_cache shared:SSL:10m;
   if ($scheme = http) {
       return 301 https://$server_name$request_uri;
   }
   location / {
       proxy_pass https://192.168.1.10:8443;

       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";

       proxy_hide_header X-Powered-By;
       proxy_set_header Range $http_range;
       proxy_set_header If-Range $http_if_range;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header Host $host;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }
}

Теперь мне нужно придумать, как заставить работать гостевой портал и перенаправление hostname через NGINX.
 
После того как я все обдумал за ночь, настроил на роутере перенаправление порта с 8843 на порт 443 хоста с nginx (и это может быть любой порт, не обязательно 443 на nginx, например, 8844, если вы хотите использовать 443 для unifi proxy). Так получается лучше, чем изначально, потому что теперь мне не нужна разделённая DNS для публичного и приватного адресов, чтобы letsencrypt работал с этой схемой.

Для тех, кто наткнётся на этот пост, именно такую конфигурацию с nginx я использую, чтобы проксировать трафик к unifi. У меня порты 80, 443 и 8843 публично на роутере переадресованы на nginx-прокси. В конфигурации unifi в разрешённых ограничениях предавторизации указан guest.mydomain.com (публичный IP роутера), а также настроен редирект с использованием hostnames.

Надеюсь, это поможет другим, кто оказался в похожей ситуации.
 
Я понимаю, что поднимаю уже мертвую тему, но у меня проблемы с настройкой обратного прокси nginx для unifi на той же машине. Со стороны nginx/обратного прокси всё работает нормально. Я могу открыть https://guest.mydomain.com/guest/s/default/#/ и вижу страницу с ваучером, но когда подключается ноутбук, точка доступа перенаправляет его на https://guest.mydomain.com:8843, который недоступен. Есть ли способ заставить unifi перенаправлять на 443 порт вместо 8843? Иначе, наверное, придётся перенести unifi на другой сервер за nginx.

Моя конфигурация:

server {
 listen [::]:80;
 listen 80;
 listen 443 ssl;
 listen [::]:443 ssl;

 server_name guest.mydomain.com;

 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;

 # SSL сертификаты
 ssl_certificate "/etc/letsencrypt/live/guest.mydomain.com/fullchain.pem";
 ssl_certificate_key "/etc/letsencrypt/live/guest.mydomain.com/privkey.pem";
 ssl_dhparam /etc/nginx/dhparam.pem;

 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 #ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

 ssl_session_cache shared:SSL:1m;
 ssl_session_timeout 10m;
 ssl_ciphers HIGH:!aNULL:!MD5;
 ssl_prefer_server_ciphers on;

 add_header Strict-Transport-Security "max-age=31536000;
 #includeSubDomains" always;

 if ($scheme = http) {
   return 301 https://$server_name$request_uri;
 }

 location / {
   proxy_pass https://127.0.0.1:8843;
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";

   proxy_hide_header X-Powered-By;
   proxy_set_header Range $http_range;
   proxy_set_header If-Range $http_if_range;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header Host $host;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }

 location /ws/ {
   proxy_pass http://127.0.0.1:8843/ws/;
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";
 }

 location ^~ /.well-known/acme-challenge/ {
   default_type "text/plain";
   root /var/www/letsencrypt;
 }
}
 
Попробуйте воспользоваться динамическим DNS-сервисом. Если у вас есть домен, возможно, ваш хостинг уже предлагает такую функцию, но есть и бесплатные варианты, например, http://www.noip.com/free. Затем замените ваш IP-адрес в списке предварительной авторизации на адрес DDNS.
 
Наконец-то кое-куда продвинулся. Мне пришлось добавить внешний IP-адрес моего провайдера в список предварительной авторизации. Но у меня динамический IP, так что каждый раз, когда он меняется, приходится вручную обновлять этот список.
 
Да, я использую Lets Encrypt для своих сертификатов. Контроллер работает на Windows, и я не нашёл проще способа обновлять сертификаты. Раньше я обновлял keystore, но делать это каждые 90 дней было настоящей головной болью, да и обновлять все остальные сертификаты для других сервисов тоже неудобно. Считаю, что проще, когда nginx обновляет сертификаты в одном месте для всех моих сервисов.

Так что теоретически я могу сделать правило в файрволе, чтобы внешний порт 8843 пересылался на внутренний порт 443 моего nginx-сервера, который затем перенаправляет на порт 8843 внутри сети.

Проблема в том, что мой гостевой портал перенаправляется на hostname — guest.mydomain.com, но когда я подключаюсь к гостевой Wi-Fi, портал не загружается, и я пытаюсь понять, почему.
 
Ах, на самом деле настроить сертификаты Letsencrypt с вашим контроллером и автоматически их обновлять довольно просто. И самое главное — это бесплатно... А чтобы ответить на ваш вопрос, нет, два процесса не могут слушать один и тот же TCP-порт на одном и том же интерфейсе.
 
Я всё ещё работаю над ошибкой websocket. Возможно, я уберу приведённый ниже раздел, так как он не повлиял на ситуацию. Зато он решил проблему с моим UniFi NVR.

location /ws/ {
   proxy_pass http://cloudkey.example.local:8443/ws/;
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "upgrade";
}
 
Большое спасибо, @Bauer3139.

С уважением, Дэвид.
 
Вот, пожалуйста.

server {
listen 80;
server_name example.url.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl;
server_name example.url.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;

location / {
proxy_pass https://cloudkey.example.local:8443/;
include /etc/nginx/proxy_params;
}

location /ws/ {
proxy_pass http://cloudkey.example.local:8443/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

server {
listen 8080;
server_name example.url.com;

location / {
proxy_pass http://cloudkey.example.local:8080/;
include /etc/nginx/proxy_params;
}

location /ws/ {
proxy_pass http://cloudkey.example.local:8080/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

server {
listen 8443 ssl;
server_name example.url.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;

location / {
proxy_pass https://cloudkey.example.local:8443/;
include /etc/nginx/proxy_params;
}

location /ws/ {
proxy_pass http://cloudkey.example.local:8443/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

server {
listen 8880;
server_name example.url.com;

location / {
proxy_pass http://cloudkey.example.local:8880/;
include /etc/nginx/proxy_params;
}

location /ws/ {
proxy_pass http://cloudkey.example.local:8880/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

server {
listen 8843 ssl;
server_name example.url.com;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;

location / {
proxy_pass https://cloudkey.example.local:8843/;
include /etc/nginx/proxy_params;
}

location /ws/ {
proxy_pass http://cloudkey.example.local:8843/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
 
Да, постараюсь скоро выложить свой проект. Единственная другая важная часть — настроить Nginx с LetsEncrypt. Бесплатные и надёжные SSL-сертификаты — это просто отлично. Сейчас он обслуживает мой контроллер UniFi, UniFi NVR и мой локальный сервер.
 
@Bauer3139

Не мог бы ты поделиться (на GitHub или здесь) кодом, который у тебя есть, чтобы другие участники сообщества тоже могли им воспользоваться? Мне это тоже интересно для одного проекта. Спасибо вам обоим за то, что нашли время поработать над этим. Спасибо, DStahl.
 
Один вопрос по вашей конфигурации: возникают ли у вас ошибки websocket при первом входе в систему или при переключении между сайтами в контроллере unifi?
 
Я только что настроил это у себя с гостевым порталом. Мой NGINX отвечает на все порты UniFi. У меня указан порт 8880, и прокси-сервер тоже открыт на этот порт. Да, в URL указан порт 8880, но меня это не смущает. Всё, что я собираюсь менять — это сам URL вместо стандартного для UniFi. Ещё пришлось подправить правила фаервола на Edge-роутере и предавторизованные подсети, чтобы гости могли хотя бы добраться до nginx-сервера. Обычно весь этот подсет блокируется в гостевой сети.
Страницы: 1
Читают тему (гостей: 1)