Jump to content
Калькуляторы

Настройка UniFi

Предлагаю обсудить решение хотспота на UniFi.

У меня решение почти рабочее, но есть несколько вопросов.

 

Дла начала исходные данные.

Для контроллера хотспота использую сервер под управлением FreeBSD 8.2 x64.

Контроллер устанавливается простым копированием архива (но вначале нужно поставить java-машину), под него дописан небольшой стартер unifi.sh (запускающий через nohup ява-аплет).

У меня на сервере есть определенная специфика, связанная с тем, что сетевых интерфейса на нем два, а сервисов несколько и на всех не хватает, поэтому использую сабинтерфейсы.

В конфиге я эти следы уберу, но могу что-то пропустить; если в конфиге будет что-то странное, то это скорее всего я забыл поправить.

 

Используемое ПО:

1. Контроллер UniFi в виде java-аплета

2. Пакетный фильтр pf (входит в состав FreeBSD)

3. Прокси-сервер Squid (/usr/ports/www/squid)

4. DHCP-сервер (/usr/ports/net/isc-dhcp42-server)

5. DNS-сервер (/usr/ports/dns/dnsmasq)

6. Web-сервер (/usr/ports/www/apache22)

 

На сервере три сетевых интерфейса:

em0 - публичный интерфейс, интернет-подключение

em1 - приватный интерфейс, локальная сеть

em2 - интерфейс хотспота

 

Схема подключения:

В интерфейс em0 включается аплинк (шнур провайдера).

Интерфейс em1 подключается в коммутатор локальной/офисной сети.

Интерфейс em2 подключается в отдельный коммутатор хотспота, в этот коммутатор также подключаются точки доступа UniFi.

 

Адресный план:

1.2.3.4/30 — публичный IP (на интерфейсе em0)

192.168.1.1/24 — приватный IP (на интерфейсе em1)

10.10.0.250/16 — приватный IP (на интерфейсе em2)

 

Вначале настраиваем UniFi.

Создаем сеть, определяем ее как guest.

Включаем guest portal, выбираем нужный режим, указываем IP-адрес портала 10.10.0.250 (чтобы из нескольких интерфейсов брался правильный), указываем разрешенные IP-адреса.

У меня используется режим external и самописный скрипт авторизации, но его публиковать я не буду.

Можно использовать встроенный портал (режим hotspot), либо указать внешний портал и использовать заготовку портала авторизации, которая идет в дистрибутиве. При использовании внешнего портала можно указать имя hotspot, тогда абонентов будут пересылать на доменное имя.

 

Затем настраиваем веб-сервер и страницу авторизации.

У каждого это будет по своему. Лично я использовал Apache+PHP.

 

Затем настраиваем DHCP-сервер для клиентов хотспота:

 

 

/usr/local/etc/dhcpd.conf

server-identifier HOTSPOT-DHCP;
ddns-update-style none;
log-facility local7;
#authoritative;
allow unknown-clients;
deny duplicates;
option domain-name "hotspot";
option domain-name-servers 10.10.0.250;
option space ubnt;
option ubnt.unifi-address code 1 = ip-address;


# Network infrastructure equipments
class "network" {
 match if binary-to-ascii(16,8,":",substring(hardware,1,3)) = "dc:9f:db"
       ;
}

# Ubiquiti equipment
class "ubnt" {
 match if substring (option vendor-class-identifier,0,4) = "ubnt";
 option vendor-class-identifier "ubnt";
 vendor-option-space ubnt;
}

# Demo, presentation, VIPs
class "client" { match hardware; }
subclass "client" 1:00:00:00:00:00:00;

# Restricted devices, notebooks, computers
class "restricted" {
 log (info, (binary-to-ascii(16,8,":",substring(hardware,1,6))));
}

subnet 10.10.0.0 netmask 255.255.0.0 {
 #range 10.10.255.1 10.10.255.200;
 default-lease-time 3600;
 option routers 10.10.0.250;
 pool {
   allow members of "network";
   deny members of "client";
   deny members of "restricted";
   #deny unknown-clients;
   range 10.10.1.1 10.10.1.200;
   range 10.10.2.1 10.10.2.200;
   range 10.10.3.1 10.10.3.200;
   range 10.10.4.1 10.10.4.200;
   range 10.10.5.1 10.10.5.200;
   range 10.10.6.1 10.10.6.200;
   range 10.10.7.1 10.10.7.200;
   range 10.10.8.1 10.10.8.200;
   range 10.10.9.1 10.10.9.200;
   max-lease-time 86400;
   option ubnt.unifi-address 10.10.0.250;
 }
 pool {
   deny members of "network";
   allow members of "client";
   deny members of "restricted";
   range 10.10.200.1 10.10.200.200;
   max-lease-time 3600;
 }
 pool {
   deny members of "network";
   deny members of "client";
   allow members of "restricted";
   range 10.10.255.1 10.10.255.200;
   default-lease-time 300;
   max-lease-time 600;
 }
 pool {
   deny members of "network";
   deny members of "client";
   deny members of "restricted";
   range 10.10.100.1 10.10.199.255;
   max-lease-time 3600;
 }
}

host ap-001 { hardware ethernet dc:9f:db:3e:7b:96; fixed-address 10.10.10.1; }
...

 

 

Такая схема предполагает раздачу IP-адресов 10.10.1-10.1-200 для точек доступа и 10.10.100-199.1-255 для клиентов. 10.10.200.1-200 зарезервировано для псевдостатики, 10.10.255.1-200 для черного списка.

 

Затем настраиваем DNS-сервер.

Я использовал dnsmasq, потому что у меня уже есть DNS-сервер (BIND9) и мне нужно было просто форвардить запросы, переопределяя некоторые записи.

Конфигурация:

 

 

/usr/local/etc/dnsmasq.conf

interface=em2
no-dhcp-interface=em1
filterwin2k
resolv-file=/etc/resolv.conf
domain=hotspot
address=/hotspot/10.10.0.250
address=/unifi/10.10.0.250
log-queries

 

 

В принципе, dnsmasq мог бы выполнять и роль DHCP-сервера. Но это я обнаружил уже потом и не стал разбираться.

Так что в моей конфигурации dhcp-сервер не используется. DNS-запросы форвардятся на основной DNS-сервер, за исключением записей hotspot и unifi, которые прописаны вручную.

Запись hotspot нужна для того, чтобы абонентов можно было переадресовывать на портал авторизации с красивым именем http://hotspot/guest. Запись unifi указана по причине того, что на точках доступа inform-url=http://unifi:8080. Лично у меня, кстати, в этом месте наблюдается странный глюк: если зайти на точку по ssh и просмотреть информацию о точке, то иногда там указан хост unifi, а иногда IP-адрес локальной сети (интерфейс em1, IP-адрес 192.168.1.1). Пока не понял почему.

 

Затем настраиваем прокси-сервер.

В принципе, контроллер UniFi сам управляет скоростью и доступом, поэтому можно обойтись без прокси и NATить всех клиентов.

Но с прокси-сервером возможностей больше.

Конфигурация (только та часть, что относится к прозрачному режиму работы):

 

 

/usr/local/etc/squid/squid.conf

...
acl IP_LOCAL       src 127.0.0.1/32
acl IP_LOCAL       src 10.10.0.250/32
acl IP_NETWORK     src 10.10.0.0/24
acl IP_NETWORK     src 10.10.1.0-10.10.9.255/32
acl IP_NETWORK     src 10.10.10.0/24
acl IP_CLIENTS     src 10.10.200.0/24
acl IP_USERS       src 10.10.100.0-10.10.199.255/32
acl IP_RESTRICTED  src 10.10.255.0/24
acl ACL_BLOCKED    arp 11:12:13:14:15:16

acl PORT_WEB port 80
acl PORT_WEB port 443
acl PORT_WEB port 8080
acl PORT_WEB port 8443
acl PORT_WEB port 1025-65535
acl PORT_SSL port 443

acl METHOD_CONNECT method CONNECT
acl METHOD_ALLOW method GET
acl METHOD_ALLOW method POST
acl METHOD_ALLOW method HEAD

deny_info    http://hotspot/errors/restricted.html IP_RESTRICTED
deny_info    http://hotspot/errors/blocked.html IP_BLOCKED
deny_info    ERR_ACCESS_DENIED all

http_access  deny   ACL_BLOCKED
http_access  deny   !PORT_WEB
http_access  allow  METHOD_CONNECT PORT_SSL
http_access  deny   METHOD_CONNECT !PORT_SSL
http_access  deny   !METHOD_ALLOW
http_access  deny   IP_RESTRICTED
http_access  allow  IP_LOCAL
http_access  allow  IP_CLIENTS
http_access  allow  IP_USERS
http_access  deny   all

http_port 10.10.0.250:8080
http_port 10.10.0.250:3128 intercept

 

 

Прокси на порту 8080 используется для отладки. В рабочей конфигурации его лучше убрать, оставить только 3128.

 

У меня используется прозрачный прокси для HTTP и NAT для HTTPS (т.к. нормально проксировать SSL нельзя).

 

Затем настраиваем NAT для HTTPS и остальные правила файрвола.

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

 

 

/etc/pf.conf

########################################
### Macros

# Interfaces
if_ext = "em0"
if_int = "em1
if_wifi = "em2"
if_loop = "lo0"

# Ports
port_ext = "{ 80 }"
port_int = "{ 80 }"
port_adm = "{ 22 3306 }"
port_uni = "{ 8081 8080 8443 }"
port_www = "{ 80 8080 }"

# Services
svc_net_tcp = "{ 80 }"
svc_net_udp = "{ 53 }"
svc_nat_tcp = "{ 443 }"

# Other
icmp_allow = "{ 0 3 8 }"


########################################
### Tables

table <locals>  { 192.168.1.0/24 }
table <wifi>    { 10.10.10.0/24 10.10.1.0/24 10.10.2.0/24 10.10.3.0/24 10.10.4.0/24 10.10.5.0/24 10.10.6.0/24 10.10.7.0/24 10.10.8.0/24 10.10.9.0/24 }
table <hotspot> { 10.10.100.0/24 10.10.101.0/24 10.10.102.0/24 ... 10.10.200.0/24 }


########################################
### Options

set block-policy return
set loginterface none
set skip on $if_loop
set timeout { frag 30, tcp.established 3600 }
set state-policy if-bound


########################################
### Normalize

scrub in all


########################################
### Queues


########################################
### Translations & Redirections

# NAT for WiFi-clients (HTTPS)
no nat on $if_ext from $if_wifi:0 to any
nat pass on $if_ext inet proto tcp from <hotspot> to any port $svc_nat_tcp -> $if_ext:0

# TProxy for WiFi-clients (HTTP)
rdr pass on $if_wifi inet proto tcp from <hotspot> to !$if_wifi port $port_www -> $if_wifi port 3128

########################################
### Filters

# Defaults
block all
antispoof log quick for { $if_int $if_ext }

# System-wide settings
pass in on $if_int inet proto tcp from <locals> to $if_int port ssh )
pass in  inet proto icmp all icmp-type $icmp_allow keep state
pass out inet proto icmp all icmp-type $icmp_allow keep state
pass out quick on $if_int inet proto { tcp udp } from $if_int   to <locals> port $port_adm
pass in  quick on $if_int inet proto { tcp udp } from <locals>  to $if_int  port $port_adm
pass out on $if_int to any
pass out on $if_ext to any

# Hotspot DHCP
pass quick on $if_wifi inet proto tcp from any port 67:68 to any port 67:68 keep state flags S/SA
pass quick on $if_wifi inet proto udp from any port 67:68 to any port 67:68 keep state

# Hotspot MGMT
pass out quick on $if_wifi to $if_wifi:network
pass in  on $if_wifi inet proto tcp from <wifi> to $if_wifi port $port_uni
pass in  on $if_wifi inet proto tcp from $if_wifi:network to $if_wifi port $svc_net_tcp
pass in  on $if_wifi inet proto udp from $if_wifi:network to $if_wifi port $svc_net_udp

# Network intranet/internet services
pass in on $if_int inet proto tcp to $if_int port $port_int
pass in on $if_ext inet proto tcp to $if_ext port $port_ext

 

 

 

Правда, у меня эта конфигурация не работает :)

Работает если добавить в правила строчку

pass quick on $if_wifi

Share this post


Link to post
Share on other sites

Теперь вопросы.

У меня почему-то не работает указанная выше конфигурация.

Если добавить такое правило:

pass log quick on $if_wifi

тогда работает. В логах при этом следующее:

17:37:49.197722 rule 59/0(match): pass in on em2: 10.10.10.1.4141 > 192.168.1.1.8080:  tcp 40 [bad hdr length 0 - too short, < 20]

И мне тут непонятно, почему точка доступа обращается на 192.168.1.1, а не на 10.10.0.250?

Если на точку доступа зайти по SSH, то по команде info я тоже вижу, что inform-url указывает почему-то на IP-адрес 192.168.1.1.

Share this post


Link to post
Share on other sites

Вот две команды, выполненные на точке с интервалом в секунд 10:

BZ.v2.4.4# info

Model:       PicoStation M2
Version:     2.4.4.2061
MAC Address: dc:9f:db:3e:7c:27
IP Address:  10.10.10.4
Uptime:      812 seconds

Status:      Server Reject (http://unifi:8080/inform)
BZ.v2.4.4# info

Model:       PicoStation M2
Version:     2.4.4.2061
MAC Address: dc:9f:db:3e:7c:27
IP Address:  10.10.10.4
Uptime:      836 seconds

Status:      Unreachable (http://10.1.128.10:8080/inform)

Share this post


Link to post
Share on other sites

Еще вопрос.

Если в rdr я указываю pass, то прокси-сервер работает.

Но если я указываю pass в nat, то это не помогает.

В логах pflog при этом следующее:

17:43:45.391443 rule 0/0(match): block in on vlan900: 10.10.106.169.37595 > 74.125.143.94.443:  tcp 40 [bad hdr length 0 - too short, < 20]
17:43:49.377010 rule 0/0(match): block in on vlan900: 10.10.106.169.37596 > 74.125.143.94.443:  tcp 40 [bad hdr length 0 - too short, < 20]
17:43:55.027271 rule 0/0(match): block in on vlan900: 10.10.106.169.37597 > 74.125.143.94.443:  tcp 40 [bad hdr length 0 - too short, < 20]

 

10.10.106.169 - это подключенный к хотспоту клиент (смартфон на андроиде).

74.125.143.94 - это гугл, который я пробовал открыть на смартфоне (безуспешно).

 

Что за bad hdr length 0?

Вот лог с дампом:

17:49:28.714846 rule 0/0(match): block in on vlan900: 10.10.106.169.37614 > 74.125.143.94.443:  tcp 40 [bad hdr length 0 - too short, < 20]
       0x0000:  3d02 0100 766c 616e 3930 3000 0000 0000  =...vlan900.....
       0x0010:  0000 0000 0000 0000 0000 0000 0000 0000  ................
       0x0020:  0000 0000 0000 0000 ffff ffff ffff ffff  ................
       0x0030:  a086 0100 0000 0000 c30c 0000 0100 0000  ................
       0x0040:  4500 003c d95e 4000 4006 12cf 0a0a 6aa9  E..<.^@.@.....j.
       0x0050:  4a7d 8f5e 92ee 01bb 4af7 5b61 0000 0000  J}.^....J.[a....

Но если в правилах написать pass quick all, тогда NAT работает нормально.

Share this post


Link to post
Share on other sites

У вас есть SE100 с помощью которого можно было бы реализовать то же самое, но интереснее (CoA etc), IMHO.

Share this post


Link to post
Share on other sites

Если имеется ввиду авторизация в сети по радиусу, то я это пробовал, не подходит по ряду причин (сложности в вводе учетных данных на разных клиентах).

Поэтому я остаеовился на открытой сети и web-портале для авторизации.

Share this post


Link to post
Share on other sites

Юзер авторизуется на портале, а в инет его выпускает SE.

Share this post


Link to post
Share on other sites

По прежнему не понял.

Как SE будет знать, авторизован пользователь или нет?

В UniFi это отслеживает контроллер.

В случае с SE нужно будет в портале делать радиус-сервер.

Share this post


Link to post
Share on other sites

Вешаем на юзера НТТР редирект на портал, а когда он там авторизуется снимаем редирект и выпускаем в инет. Этакий хитрый CLIPS получается.

Share this post


Link to post
Share on other sites

Но если я указываю pass в nat, то это не помогает.

Похоже nat pass неправильно работает на трех интерфейсах.

Сделал так, теперь все работает — HTTP проксирует, HTTPS натит.

...
no nat on $if_ext from $if_wifi:0 to any
nat on $if_ext inet proto tcp from <hotspot> to any port $svc_nat_tcp -> $if_ext:0
...
pass out on $if_wifi inet proto tcp from <hotspot> to any port $svc_nat_tcp
pass in  on $if_wifi inet proto tcp from <hotspot> to !$if_wifi port $svc_nat_tcp

 

Вешаем на юзера НТТР редирект на портал, а когда он там авторизуется снимаем редирект и выпускаем в инет.

Снимаем — в смысле, скрипт авторизации подключается к SE и снимает редирект (CoA или еще как)?

Как-то сложновато это, контроллер UniFi проще и надежнее.

К тому же, у меня SE терминирует PPPoE без контекстов (в контексте local), я не смогу отличить нормальных абонентов от хотспота.

Share this post


Link to post
Share on other sites

"Снимаем" = шлем СоА.

Что мешает поднять тестовый контекст и там попробовать? У меня в одном контексте РРРоЕ в продакшене с живыми юзерами и есть пара тестовых контекстов.

Share this post


Link to post
Share on other sites

"Снимаем" = шлем СоА.

Понятно.

UniFi удобнее для потребителя.

Пользователь может отключиться от хотспота, подключиться (например в другом месте) и продолжить работать, если активированный PIN-код продолжает действовать.

А SE при отключении пользователя разорвет сессию и при подключении в новом месте вновь нужно будет проходить авторизацию.

Share this post


Link to post
Share on other sites

Что есть "отключение" при использовании подобного варианта CLIPS? Почему SE должен разорвать сессию?

Смое интересное то, что все о чем я писал выше циской продвигается как один из стандартных вариантов использования ISG.

Share this post


Link to post
Share on other sites

Нужно будет попробовать.

Но пока мне не ясно, как будут обслуживаться клиенты.

Либо это будет коммутируемое соединение и при отключении будет сбрасываться сессия.

Либо это будет CLIPS и тогда абонента нужно заводить заранее, что для хотспота не подходит.

Share this post


Link to post
Share on other sites

Понятно, спасибо. Попробую такое организовать.

Но тем не менее мне кажется, что для хотспота UniFi более оптимален.

Share this post


Link to post
Share on other sites

UniFi - он сам по себе, он вам точки обслуживает, а вот доступ в интернеты лучше возложить на что-то более для этого подходящее, IMHO.

Ладно SE, возьмите для примера тот же микротик - там хотспот замечательно с радиусом умеет общаться.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this