Каталог Поиск 0 Сравнить 0 Закладки 0 Корзина Войти
Каталог
105082, Москва, ул. Фридриха Энгельса, 75с21, БЦ Бауманский ИТКОЛ
Пн - Пт: с 09-00 до 18-00 Сб: с 10-00 до 18-00 Вс: выходной
Страницы: 1 2 След.
RSS
Unifi Controller за nginx-прокси – Server.log LocalHost, UniFi Network
 
Привет! Я пытаюсь настроить Unifi Controller за обратным прокси nginx, чтобы nginx управлял SSL-сертификатами Let's Encrypt. Используя примеры конфигураций из разных постов, мне удалось всё запустить, и оно работает. Но в файле server.log и в логах контроллера входы пользователей отображаются с LocalHost вместо реального IP. Есть ли какие-то особые настройки в Unifi или nginx, о которых стоит знать?

Вот моя конфигурация:

server {
   listen 80 default_server;
   include /etc/nginx/snippets/letsencryptauth.conf;
   ssl_dhparam /etc/ssl/certs/dhparam.pem;
   root /var/www/html;
   server_name xxxxx.xxxxx.xxxxx;
   location /inform {
       proxy_pass http://localhost:8080/inform;
       include /etc/nginx/proxy_params;
   }
   location / {
       return 301 https://localhost$request_uri;
   }
}

server {
   listen 443 ssl http2;
   server_name xxxxx.xxxxx.xxxxx;

   ssl on;
   ssl_certificate /etc/letsencrypt/live/xxxxx.xxxxx.xxxxx/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/xxxxx.xxxxx.xxxxx/privkey.pem;
   ssl_trusted_certificate /etc/nginx/ssl/default/unifi.pem;
   ssl_dhparam /etc/ssl/certs/dhparam.pem;

   ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
   ssl_prefer_server_ciphers on;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_session_cache shared:SSL:10m;
   ssl_session_timeout 5m;
   add_header Strict-Transport-Security "max-age=31536000" always;

   server_tokens off;

   proxy_ssl_verify off;
   proxy_ssl_session_reuse on;
   proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   proxy_cache off;
   proxy_store off;

   location /wss {
       proxy_pass https://localhost:8443/wss;
       proxy_redirect off;
       proxy_buffering off;
       proxy_set_header Host $http_host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
       proxy_ssl_verify off;
   }

   location / {
       proxy_pass https://127.0.0.1:8443;
       proxy_set_header Host $host;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_intercept_errors on;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   }
}

И вот пример вывода из server.log:

[2017-08-07 20:52:50,222] <webapi-157> INFO api - [api] Failed admin login for aa from 127.0.0.1
[2017-08-07 20:52:50,814] <webapi-157> INFO api - [api] api.err.Invalid: /api/login

Я также пробовал аналогично настроить apache — результат тот же. Буду благодарен за помощь. Спасибо!
 
Кто-нибудь ещё, может быть @UI-TomS, может ответить на это?
 
Прочитав все сообщения, я не видел, чтобы кто-то научил Unifi Controller учитывать заголовки X-Forwarded-For или X-Real-IP. Я уже спрашивал UI об этой функции в связанном топике, но там речь шла про Unifi Network Management System Software (UNMS), а не про Unifi Controller. Поэтому, @UI-Radek, не мог бы ты узнать, поддерживает ли текущая версия Unifi Controller обработку HTTP proxy-заголовков для server.log? Если да, подскажи, пожалуйста, название заголовка. Спасибо!
 
server {
   listen              443 ssl;
   server_name         unifi-jkt.my.site;

   ssl_certificate     /root/SSL/commercial.crt;
   ssl_certificate_key /root/SSL/commercial.key;
   ssl_session_cache  builtin:1000  shared:SSL:10m;
   ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
   ssl_prefer_server_ciphers on;    client_max_body_size 0;

   location ~(/|/wss|/manage|/login|/status|/templates|/src|/services|/directives|/api) {
       proxy_pass https://172.16.0.2:8443;
       proxy_set_header Authorization "";
       proxy_pass_request_headers on;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       #proxy_set_header X-Forwarded-Host $server_name;
       proxy_set_header X-Forwarded-Host $remote_addr;
       #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-For $remote_addr;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Forwarded-Ssl on;
       proxy_http_version 1.1;
       proxy_buffering off;
       proxy_redirect off;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
       auth_basic "Restricted";
       #auth_basic_user_file /etc/nginx/.htpasswd; #Basic auth
   }
}
#/etc/nginx/sites-enabled/default

server_tokens off;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";

server {
   listen 80;
   server_name wifi.domainname.com;
   return 301 https://wifi.domainname.com$request_uri;
   error_log /var/log/unifi/nginx.log;
}

server {
   listen 443 ssl default_server http2;
   server_name wifi.domainname.com;
   ssl_dhparam /etc/ssl/certs/dhparam.pem;
   ssl_certificate /etc/letsencrypt/live/wifi.domainname.com/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/wifi.domainname.com/privkey.pem;
   ssl_session_cache shared:SSL:10m;
   ssl_session_timeout 10m;
   keepalive_timeout 300;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_prefer_server_ciphers on;
   ssl_stapling on;
   ssl_ciphers  ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM$;
   add_header Strict-Transport-Security max-age=31536000;
   add_header X-Frame-Options DENY;
   error_log /var/log/unifi/nginx.log;
   client_max_body_size 8M;
   proxy_cache off;
   proxy_store off;

   location / {
       include /etc/nginx/proxy_params;
       proxy_pass https://127.0.0.1:8443$request_uri;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
   }
}
Это + то, что ниже (чтобы исправить ошибку 400), сработало отлично для UDM.
proxy_set_header Authorization "";
 
@manol0 Просто чтобы уточнить, это решает проблему у автора поста? Ты видишь правильные IP-адреса входа в журнале событий UniFi Controller? Или по-прежнему каждый раз отображается IP-адрес реверс-прокси?
 
Мой nginx теперь работает без нареканий. Ниже мой конфиг. Обратите внимание, что в докер-контейнере у меня были проблемы с localhost IP 127.0.0.1, поэтому я использовал IP из своей локальной сети.

my unifi.conf

upstream unifi {  
   server 10.0.55.5:10443;  
}

server {  
   server_name unifi.example.com;  
   include /etc/nginx/conf.d/http.include;  
}

server {  
   server_name unifi.example.com;  
   ssl_certificate /etc/nginx/certs/unifi.example.com.crt;  
   ssl_certificate_key /etc/nginx/certs/unifi.example.com.key;  
   ssl_trusted_certificate /etc/nginx/certs/unifi.example.com.chain.pem;  
   ssl_dhparam /etc/nginx/certs/example.com.dhparam.pem;  
   include /etc/nginx/conf.d/ssl.include;  
   location / {  
       proxy_pass https://unifi;  
   }  
}

my ssl.include:

# SSL Include  
listen 443 ssl http2;  
access_log /var/log/nginx/access.log vhost;  
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;  
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';  
ssl_prefer_server_ciphers on;  
ssl_session_timeout 5m;  
ssl_session_cache shared:SSL:50m;  
ssl_session_tickets off;  
ssl_stapling on;  
ssl_stapling_verify on;  
add_header Strict-Transport-Security "max-age=31536000" always;  
include /etc/nginx/vhost.d/default;  
resolver 10.0.55.7 8.8.8.8 valid=10s;
 
@Munkinasack, твоя конфигурация поддерживает передачу информ (8080) через Nginx? В последней выложенной тобой конфигурации я не заметил ничего, что бы обрабатывало http-трафик на 8080, но я точно не эксперт по Nginx.
 
Да, мой контроллер находится на том же сервере, так что менять IP не пришлось. Основные изменения касались subdomain.domain.com, нескольких опций SSL, которые я уже настроил через include, и пути к файлам lets encrypt.
 
Я всё ещё не могу запустить это в своей среде, я уже заменил 127.0.0.1 на IP моего контроллера proxy_pass https://127.0.0.1:8443$request_uri; Что ещё ты менял? Твой контроллер на том же сервере, что и nginx?
 
Не стесняйтесь использовать и менять по своему усмотрению. Спасибо, Адриан! Именно так я и сделал. После очевидных корректировок, чтобы подстроить под свою систему, всё заработало как по маслу.
 
Я попробовал вашу конфигурацию, но она выдает следующую ошибку. К слову, мой сервер nginx и контроллер unifi находятся на разных хостах.
 
Возможно, слишком много возни с заголовками? Здесь полно примеров конфигураций nginx, можно поискать. Например, вот моя (на дроплете Digital Ocean). Используйте и меняйте под себя. #/etc/nginx/sites-enabled/default

server_tokens off;  
add_header X-Frame-Options SAMEORIGIN;  
add_header X-XSS-Protection "1; mode=block";

server {  
listen 80;  
server_name wifi.domainname.com;  
return 301 https://wifi.domainname.com$request_uri;  
error_log /var/log/unifi/nginx.log;  
}

server {  
listen 443 ssl default_server http2;  
server_name wifi.domainname.com;  
ssl_dhparam /etc/ssl/certs/dhparam.pem;  
ssl_certificate /etc/letsencrypt/live/wifi.domainname.com/fullchain.pem;  
ssl_certificate_key /etc/letsencrypt/live/wifi.domainname.com/privkey.pem;  
ssl_session_cache shared:SSL:10m;  
ssl_session_timeout 10m;  
keepalive_timeout 300;  
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  
ssl_prefer_server_ciphers on;  
ssl_stapling on;  
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM;  
add_header Strict-Transport-Security max-age=31536000;  
add_header X-Frame-Options DENY;  
error_log /var/log/unifi/nginx.log;  
client_max_body_size 8M;  
proxy_cache off;  
proxy_store off;

location / {  
include /etc/nginx/proxy_params;  
proxy_pass https://127.0.0.1:8443$request_uri;  
proxy_set_header Upgrade $http_upgrade;  
proxy_set_header Connection "upgrade";  
}  
}

С этим вы получите оценку A+ на SSLabs тоже...
 
Привет, я новичок в ubiquity/unifi. Я уже успешно настроил обратный прокси с nginx с такой конфигурацией:

server {
   listen              443 ssl;
   server_name         unifi-jkt.my.site;

   ssl_certificate     /root/SSL/commercial.crt;
   ssl_certificate_key /root/SSL/commercial.key;
   ssl_session_cache  builtin:1000  shared:SSL:10m;
   ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
   ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
   ssl_prefer_server_ciphers on;
   client_max_body_size 0;

   location ~(/|/wss|/manage|/login|/status|/templates|/src|/services|/directives|/api) {
       proxy_pass https://172.16.0.2:8443;
       proxy_set_header Authorization "";
       proxy_pass_request_headers on;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       #proxy_set_header X-Forwarded-Host $server_name;
       proxy_set_header X-Forwarded-Host $remote_addr;
       #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       proxy_set_header X-Forwarded-For $remote_addr;
       proxy_set_header X-Forwarded-Proto $scheme;
       proxy_set_header X-Forwarded-Ssl on;
       proxy_http_version 1.1;
       proxy_buffering off;
       proxy_redirect off;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
       auth_basic "Restricted";
       #auth_basic_user_file /etc/nginx/.htpasswd; #Basic auth
   }
}

Все работает, но я не могу получить реальный IP клиента при входе — кажется, что все запросы идут от самого nginx.
 
Извиняюсь за поздний ответ. Дополнительные loopback IP-адреса нужны только для сервисов, которые слушают напрямую на локальном интерфейсе. В случае с контейнерами в bridge-сети это может и не понадобиться. Лично я запускаю свой unifi controller и haproxy в Docker с host-сетью и не особенно изучал варианты перехода на что-то другое. Вот что я бы попробовал: запустить unifi controller в контейнере с bridged-сетью. Думаю, это означает Layer 3 adoption. Не включайте встроенную пересылку Docker для порта веб-интерфейса (по умолчанию 8443), мы будем использовать haproxy для этого. Запустите haproxy в режиме host-сети. Обходного пути, насколько я знаю, нет. Контейнеру потребуются дополнительные права: NET_ADMIN и NET_RAW. Если хотите слушать привилегированный порт, также понадобится NET_BIND_SERVICE. Лично я использую стандартный Docker-контейнер haproxy, так как маршруты firewall’а настраиваю отдельно, но если нужен универсальный вариант, попробуйте tombull/haproxy. Настройте haproxy с IP-адресом контейнера в роли backend-сервера в прозрачном режиме. Далее нужно перенаправить ответные пакеты проксируемого трафика обратно на haproxy, а не давать системе отправлять их напрямую клиенту. Есть два способа: первый — отлавливать трафик через netfilter с помощью tproxy и socket match. Это стандартный путь, но для этого нужен kernel-модуль xt_socket. Если этот модуль не доступен, придется использовать другой признак проксируемого соединения. Например, можно сопоставлять IP-адрес контейнера контроллера и порт 8443 как источник, а затем ставить метку (fwmark) таким пакетам через PREROUTING. При этом нужно настроить ip rule и route для маршрутизации помеченных пакетов обратно на localhost. Этот способ сработает, если unifi controller не использует порт 8443 для исходящего трафика, а только для ответов на запросы. Надеюсь, это поможет. Ещё раз — я не тестировал этот вариант, так как сам использую host-сеть с трюком на loopback.
 
@And4713

Понимаю вашу мысль. Спасибо за объяснение. Я уже настроил fail2ban для сканирования логов nginx, кажется, это работает. Тем не менее, хотелось бы видеть эти записи в разделе События.

@voidpointer

Насколько я понимаю, сделать их доступными по другому пути нельзя. Похоже, что в данный момент UniFi Controller не умеет обрабатывать такие запросы. Надеюсь, что в ближайшем будущем Ubiquiti сделает UniFi Controller более дружелюбным к обратным прокси!
 
Нет ли решения этой задачи с использованием пути вместо поддомена? Я хочу получить доступ к контроллеру unifi через https://domain.com/unifi, а не через https://unifi.domain.com. Как мне это настроить?
 
@NetWorkB

Сейчас дело обстоит именно так, потому что с точки зрения контроллера все подключения фактически идут от прокси. На данный момент, насколько я знаю, контроллер не поддерживает ни один из вариантов заголовка X-Forwarded или что-то вроде PROXY-протокола, которое позволило бы ему увидеть, откуда реально приходит соединение. Насколько я слышал, никто пока не смог обмануть или изменить внутренний веб-сервер контроллера, чтобы он принимал такие данные. Если не произойдет ничего подобного, придется ждать официальной поддержки. (Или использовать только что опубликованное решение на haproxy, чтобы подделать информацию для контроллера.) Чтобы, например, fail2ban продолжал работать эффективно, можно настроить его на сканирование логов прокси на предмет сбоев вместо логов unifi, там будет настоящая информация об IP.

@mathieuh

Я прочитал статью, но все еще не уверен: если я использую LXD-контейнеры и мосты для таких прокси-штучек, нужно ли мне заморачиваться с дополнительными лупбэками и маршрутными правилами? Поскольку мост может быть выделен только под прокси, мне интересно, как правильно настроить подделку источника в режиме TCP.
 
Мне удалось запустить nginx с решением от @raathm. Всё работает, и ошибки WebSocket исчезли, спасибо, что поделились! Но у меня по-прежнему не отображается правильный IP-адрес в разделе События и в server.log. Это только у меня такое, или у вас тоже?
 
Лично я решил эту проблему с помощью HAProxy в прозрачном режиме. По моему мнению, nginx — не самый подходящий инструмент для этой задачи. Он слишком сильно работает на уровне HTTP-соединения. HAProxy же предназначен для обратного проксирования соединений. Чтобы правильно отображать IP-адреса в логах контроллера Unifi, я использовал функцию прозрачного режима в HAProxy, которая фактически подделывает источник соединения, подставляя оригинальный IP клиента. При этом нужны некоторые сетевые настройки на хосте, где запущен прокси — это может быть локальный компьютер или шлюз сети.

Я вообще настраиваю обычный сертификат в контроллере Unifi и просто перенаправляю соединение на уровне TCP в HAProxy, опираясь на SNI инспекцию. Прозрачное проксирование также можно делать, завершая SSL-соединение в HAProxy и обрабатывая трафик на уровне HTTP, но поскольку контроллер Unifi игнорирует заголовки Forwarded, это почти бессмысленно, если только нужно логировать HTTP-трафик на прокси.

Ниже пример того, что нужно для запуска HAProxy в прозрачном режиме на том же хосте, где работает контроллер Unifi. Более подробно я описал в статье, как использовать HAProxy для прозрачного маршрутизации веб-сервисов.

Команды:  
# Разрешить использование IP_TRANSPARENT для привязки к не локальным адресам  
sysctl -w net.ipv4.ip_nonlocal_bind=1  
# Добавить новый диапазон адресов назначения для обработки прозрачного трафика  
ip addr add 192.168.127.1/24 dev lo scope host  
# Маршрутизировать ответные пакеты прозрачного трафика обратно в локальные прозрачные сокеты  
ip rule add from 192.168.127.0/24 lookup 100  
ip route add local 0.0.0.0/0 dev lo table 1  

haproxy.cfg:  
listen https-server  
 bind ipv4@:443  
 mode tcp  
 
 tcp-request inspect-delay 10s  
 tcp-request content accept if req.ssl_hello_type 1  
 tcp-request content reject if WAIT_END  
 
 use-server unifi-tls if req.ssl_sni -i unifi.example.com  
 server unifi-tls 192.168.127.1:8443 source 192.168.127.1 usesrc clientip weight 0
 
Метод @raathm сработал у меня. Больше никаких ошибок WebSocket Connection Error. Вот что у меня было:

server {
   listen 443 ssl;

   server_name unifi.*;

   include /config/nginx/ssl.conf;

   client_max_body_size 0;

   location / {
       include /config/nginx/proxy.conf;
       resolver 127.0.0.11 valid=30s;
       set $upstream_unifi unifi;
       proxy_pass https://$upstream_unifi:8443;
   }
   
   location /wss {

       include /config/nginx/proxy.conf;
       resolver 127.0.0.11 valid=30s;
       set $upstream_unifi unifi;
       proxy_pass https://$upstream_unifi:8443;
       proxy_redirect off;
       proxy_buffering off;
       proxy_set_header Host $host;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
       proxy_ssl_verify off;
   }

}

А вот что у меня теперь (рабочая настройка):

server {
   listen 443 ssl;

   server_name unifi.*;

   include /config/nginx/ssl.conf;

   client_max_body_size 0;

   location / {
       include /config/nginx/proxy.conf;
       resolver 127.0.0.11 valid=30s;
       set $upstream_unifi unifi;
       proxy_pass https://$upstream_unifi:8443;

       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "Upgrade";
   }
}

Гораздо проще! Спасибо, Raathm!
Страницы: 1 2 След.
Читают тему (гостей: 1)