Поддержка взаимодействия системы WNAM с маршрутизатором pfSense (http://www.pfsense.org) появилась, начиная с версии ПО WNAM 1.2.567. Маршрутизатор pfSense представляет собой основанный на кодовой базе ОС FreeBSD специализированный дистрибутив, позволяющий организовать на основе x86 архитектуры компьютера полноценный маршрутизатор, шлюз сети Интернет с большим набором возможностей и управлением через веб-интерфейс. Перед началом настойки взаимодействия сервера pfSense c системой WNAM необходимо настроить и отладить сам pfSense, в том числе настроить сервис DHCP, маршрутизацию, правила межсетевого экранирования и трансляцию адресов между локальной (где находятся любые точки доступа и абоненты сети Wi-Fi) и глобальной (внешней, Internet) сетью.

Поддерживается pfSense версий 2.2.х, с версией 2.3 могут быть проблемы.

При работе в качестве шлюза с авторизацией доступа pfSense использует встроенный компонент Captive Portal. Необходимо создать новый портал через меню "Services" →  "Captive Portal". Портал здесь называется "зоной".

Необходимо задать имя портала (зоны) и интерфейс, на котором он будет работать (это интерфейс LAN, на котором находятся Wi-Fi точки доступа и их абоненты). Далее, нажав на кнопку "е", необходимо установить параметры портала, как показано на рисунке.

В таблице перечислены параметры портала, которые необходимо заполнить.

ПараметрОписание
InterfacesВыбор LAN - имя интерфейса, на котором будет работать портал
Idle timeoutТайм-аут неактивности пользователя (сессия закончится, если не будет трафика в течение указанного количества минут)
Hard timeoutАбсолютный тайм-аут сессии пользователя в минутах. Может быть переопределен в настройках "Ограничения"
Pre-authentication redirect URL

Указать ссылку на сервер WNAM, в формате:

http://адрес_сервера:порт/cp/pfsense

Например,

http://10.200.0.2/cp/pfsense

Per-user bandwidth restriction

Установка значения ограничений скорости передачи для абонента (в кбит/с), либо просто включите параметр (Enable per-user bandwidth restriction), поля ограничений не заполняются. Также необходимо указать значение в меню WNAM ("Ограничения") глобально или для площадки

Authentication

RADIUS Authentication - RADIUS Protocol - PAP

Primary RADIUS server - IP addressIP-адрес сервера WNAM, например, 10.200.0.2
Primary RADIUS server - Shared secretПароль взаимодействия с RADIUS-сервером, должен совпадать с аналогичным параметром в файле /etc/freeradius/clients.conf на сервере WNAM
Accountingsend RADIUS accounting packets
Accounting updatesinterim update
RADIUS NAS IP attributeWAN, указать имя (и адрес) внешнего сетевого интерфейса
Session-TimeoutUse RADIUS Session-Timeout attributes
Typedefault
MAC address formatdefault
Portal page contents

Взять файл по ссылке: http://www.netams.com/files/wnam/misc/index-pfsense.php , переименовать в index.php и загрузить его в данном пункте меню настроек.

При помощи этого файла производится перенаправление перехваченной порталом pfSense HTTP-сессии абонента на сервер WNAM для целей авторизации

В файле, который определяет перенаправление на внешний портал авторизации (сервер WNAM), index.php, необходимо изменить идентификатор площадки (параметр "site-id"), указав номер площадки из конфигурации системы WNAM. В противном случае будет подставляться имя зоны (в примере - HomeK18). Также можно создавать зоны с именами (идентификаторами), численно равными номеру площадки из системы WNAM. Всё это требуется, если используется более чем одна зона на одном портале pfSense.

Необходимо также разрешить трафик в обход портала pfSense для еще неавторизованных клиентов. Как минимум, до DNS-сервера (в примере - до сервера Google 8.8.8.8) и до самого портала авторизации системы WNAM (в примере: 172.16.130.5).

Для учёта сведений по потокам трафика (на какие внешние ресурсы обращались абоненты) необходимо организовать сбор сведений по трафику и отправку из в сторону сервера WNAM по протоколу NetFlow. Для этого необходимо установить и настроить пакет softflowd (включен в набор штатных пакетов pfSense). Параметры настройки приведены на рисунке.

Необходимо указать интерфейс (LAN), IP-адрес сервера WNAM, порт коллектора (20002), протокол (5), тип трекинга (full), а также таймауты. Затем необходимо включить softflowd в меню "Status" → "Services".

Сбор статистики по объему трафика ведется по значениям счетчиков, получаемых в сообщениях RADIUS Accounting-Interim, а статистика по самому трафику (кто и какие ресурсы посещал) - по NetFlow.

Система WNAM устанавливает параметр отправки промежуточных сообщений аккаунтинга (счетчики трафика абонента) в значение, равное 5 минут (по умолчанию в pfSense - 1 минута).

Для определения имен устройств абонентов необходимо дополнительно включить механизм информирования сервера WNAM о присвоении IP-адреса устройствам абонентов, встроенным в pfSense DHCP-сервером. Для этого необходимо выполнить следующие действия:

  1. Настроить и проверить сам DHCP-сервер. Потребуется вручную вносить изменения в текстовый конфигурационный файл сервера, через Web-интерфейс донастраивать DHCP-сервер нельзя.
  2. Зайти в консоль (shell) pfSense и установить пакеты:
    1. pkg bootstrap;
    2. pkg install perl5;
    3. pkg install p5-IO-Socket-IP;
    4. pkg install joe.
  3. Создать файл-скрипт оповещения системы WNAM /usr/local/bin/joe /usr/local/bin/wnam-dhcpd-bridge.pl:


#!/usr/local/bin/perl

use constant WNAM_HOST => "172.16.130.5";

use IO::Socket::INET;

$| = 1;

my $sock = new IO::Socket::INET(PeerAddr => WNAM_HOST, PeerPort => 20001, Proto => 'tcp', Timeout => 0.5) or undef $sock;

if (defined $sock) {
if (defined $ARGV[0]){
my $type = $ARGV[0];
my $ip = $ARGV[1];
my $mac = uc $ARGV[2];
my $name = $ARGV[3];
if (defined $type and defined $ip and defined $mac) {
print $sock "DHCP type=$type ip=$ip mac=$mac name=$name\n";
}
}
}

4. Необходимо дать скрипту права на исполнение командой:

 chmod +x /usr/local/bin/wnam-dhcpd-bridge.pl

5. Необходимо отредактировать конфигурационный файл сервера DHCP: /usr/local/bin/joe /var/dhcpd/etc/dhcpd.conf и добавить в него строки: 

   on commit {
set clip = binary-to-ascii(10, 8, ".", leased-address);
set clhw = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
set clhost = pick-first-value(host-decl-name, option fqdn.hostname, option host-name, "");
execute("/usr/local/bin/wnam-dhcpd-bridge.pl", "commit", clip, clhw, clhost);
}

6. Последним шагом является перезапуск сервиса DHCP: "Services - DHCP Server".

После завершения настройки pfSence необходимо создать сервер доступа в конфигурации WNAM (раздел "Конфигурация" → "Сервера доступа"), указав соответствующий тип, и внешний (WAN) адрес pfSense. Пароль не нужен.

 
Если используются пересекающиеся IP-подсети, необходимо модифицировать под pfSense (первый раз и каждый раз после обновления) для включения возможности передачи в RADIUS-пакетах идентификатора площадки.

Допустим, площадка оказания услуги имеет номер 9. Необходимо зайти в интерфейс командной строки и установить редактор:

pkg add http://pkg.freebsd.org/freebsd:10:x86:64/release_3/All/nano-2.4.3.txz

Затем необходимо отредактировать файлы:

[2.3.2-RELEASE][admin@pfsense.k18.netams.com]/etc/inc: nano /usr/local/captiveportal/radius_authentication.inc

// Extra data to identify the client and nas
$rauth->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, addr);
$rauth->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
$rauth->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
$rauth->putVendorAttribute(14122, 1, "9");

// Send request
$result = $rauth->send();

и далее:
[2.3.2-RELEASE][admin@pfsense.k18.netams.com]/etc/inc: nano /usr/local/captiveportal/radius_accounting.inc
$racct->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, "addr");
$racct->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
$racct->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
$racct->putVendorAttribute(14122, 1, "9");

// Send request
$result = $racct->send();

 // Evaluation of the response


После сохранения при попытке авторизации в лог-файле RADIUS-сервера будут присутствовать строки вида:
rad_recv: Access-Request packet from host 172.16.130.4 port 40167, id=96, length=138
NAS-IP-Address = 172.16.130.4
NAS-Identifier = "pfsense"
User-Name = "4C:57:CA:2C:0F:4C"
User-Password = "password"
Service-Type = Login-User
NAS-Port-Type = Ethernet
NAS-Port = 2042
Framed-IP-Address = 172.16.70.48
Called-Station-Id = "172.16.130.4"
Calling-Station-Id = "4c:57:ca:2c:0f:4c"
WISPr-Location-ID = "9"
# Executing section authorize from file /etc/freeradius/sites-enabled/default
+group authorize {
++[preprocess] = ok
[pap] WARNING! No "known good" password found for the user. Authentication may fail because of this.
++[pap] = noop
++[chap] = noop
rlm_perl: WNAM Q: AUTH NAS-Port-Type=Ethernet Called-Station-Id=172.16.130.4 NAS-IP-Address=172.16.130.4 Calling-Station-Id=4c:57:ca:2c:0f:4c Framed-IP-Address=172.16.70.48 NAS-Identifier=pfsense User-Name=4C:57:CA:2C:0F:4C User-Password=password Service-Type=Login-User WISPr-Location-ID=9 NAS-Port=2042
rlm_perl: RECV: IO::Socket::INET=GLOB(0x1456770)
rlm_perl: WNAM A: OK Acct-Interim-Interval=300 Session-Timeout=300 (48)
rlm_perl: authorize reply: .OK.
rlm_perl: Added pair NAS-Port-Type = Ethernet
rlm_perl: Added pair Called-Station-Id = 172.16.130.4
rlm_perl: Added pair NAS-IP-Address = 172.16.130.4
rlm_perl: Added pair Calling-Station-Id = 4c:57:ca:2c:0f:4c
rlm_perl: Added pair Framed-IP-Address = 172.16.70.48
rlm_perl: Added pair NAS-Identifier = pfsense
rlm_perl: Added pair User-Name = 4C:57:CA:2C:0F:4C
rlm_perl: Added pair User-Password = password
rlm_perl: Added pair Service-Type = Login-User
rlm_perl: Added pair WISPr-Location-ID = 9
rlm_perl: Added pair NAS-Port = 2042
rlm_perl: Added pair Acct-Interim-Interval = 300
rlm_perl: Added pair Session-Timeout = 300
rlm_perl: Added pair Cleartext-Password = password
rlm_perl: Added pair Auth-Type = PAP
++[perl] = ok
+} # group authorize = ok
Found Auth-Type = PAP
# Executing group from file /etc/freeradius/sites-enabled/default
+group PAP {
[pap] login attempt with password "password"
[pap] Using clear text password "password"
[pap] User authenticated successfully
++[pap] = ok
+} # group PAP = ok
WARNING: Empty post-auth section. Using default return values.
# Executing section post-auth from file /etc/freeradius/sites-enabled/default
Sending Access-Accept of id 96 to 172.16.130.4 port 40167
Acct-Interim-Interval += 300
Session-Timeout += 300
Finished request 36.
Going to the next request
Waking up in 4.9 seconds.

rad_recv: Accounting-Request packet from host 172.16.130.4 port 64326, id=19, length=159
NAS-IP-Address = 172.16.130.4
NAS-Identifier = "pfsense"
User-Name = "4C:57:CA:2C:0F:4C"
Acct-Status-Type = Start
Acct-Authentic = RADIUS
NAS-IP-Address = 172.16.130.4
NAS-Identifier = "pfsense"
NAS-Port-Type = Ethernet
NAS-Port = 2042
Acct-Session-Id = "214606a2575e53cd"
Framed-IP-Address = 172.16.70.48
Called-Station-Id = "172.16.130.4"
Calling-Station-Id = "4c:57:ca:2c:0f:4c"
WISPr-Location-ID = "9"
# Executing section preacct from file /etc/freeradius/sites-enabled/default
+group preacct {
++[preprocess] = ok
[acct_unique] Hashing 'NAS-Port = 2042,NAS-Identifier = "pfsense",NAS-IP-Address = 172.16.130.4,Acct-Session-Id = "214606a2575e53cd",User-Name = "4C:57:CA:2C:0F:4C"'
[acct_unique] Acct-Unique-Session-ID = "5e89ff48449fd085".
++[acct_unique] = ok
+} # group preacct = ok
# Executing section accounting from file /etc/freeradius/sites-enabled/default
+group accounting {
[detail] expand: %{Packet-Src-IP-Address} -> 172.16.130.4
[detail] expand: /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d -> /var/log/freeradius/radacct/172.16.130.4/detail-20170209
[detail] /var/log/freeradius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d expands to /var/log/freeradius/radacct/172.16.130.4/detail-20170209
[detail] expand: %t -> Thu Feb 9 19:51:29 2017
++[detail] = ok
[radutmp] expand: /var/log/freeradius/radutmp -> /var/log/freeradius/radutmp
[radutmp] expand: %{User-Name} -> 4C:57:CA:2C:0F:4C
++[radutmp] = ok
rlm_perl: WNAM Q: ACCT NAS-Port-Type=Ethernet Called-Station-Id=172.16.130.4 Acct-Session-Id=214606a2575e53cd Acct-Status-Type=Start NAS-IP-Address=172.16.130.4 Calling-Station-Id=4c:57:ca:2c:0f:4c Framed-IP-Address=172.16.70.48 NAS-Identifier=pfsense Acct-Authentic=RADIUS User-Name=4C:57:CA:2C:0F:4C WISPr-Location-ID=9 NAS-Port=2042 Acct-Unique-Session-Id=5e89ff48449fd085
rlm_perl: RECV: IO::Socket::INET=GLOB(0x1456770)
rlm_perl: WNAM A: OK (2)
rlm_perl: Added pair NAS-Port-Type = Ethernet
rlm_perl: Added pair Called-Station-Id = 172.16.130.4
rlm_perl: Added pair Acct-Session-Id = 214606a2575e53cd
rlm_perl: Added pair Acct-Status-Type = Start
rlm_perl: Added pair NAS-IP-Address = 172.16.130.4
rlm_perl: Added pair NAS-IP-Address = 172.16.130.4
rlm_perl: Added pair Calling-Station-Id = 4c:57:ca:2c:0f:4c
rlm_perl: Added pair Framed-IP-Address = 172.16.70.48
rlm_perl: Added pair NAS-Identifier = pfsense
rlm_perl: Added pair NAS-Identifier = pfsense
rlm_perl: Added pair Acct-Authentic = RADIUS
rlm_perl: Added pair User-Name = 4C:57:CA:2C:0F:4C
rlm_perl: Added pair WISPr-Location-ID = 9
rlm_perl: Added pair NAS-Port = 2042
rlm_perl: Added pair Acct-Unique-Session-Id = 5e89ff48449fd085
++[perl] = ok
[attr_filter.accounting_response] expand: %{User-Name} -> 4C:57:CA:2C:0F:4C
attr_filter: Matched entry DEFAULT at line 12
++[attr_filter.accounting_response] = updated
+} # group accounting = updated
Sending Accounting-Response of id 19 to 172.16.130.4 port 64326
Finished request 37.
Cleaning up request 37 ID 19 with timestamp +1486
Going to the next request
Waking up in 4.9 seconds.
Cleaning up request 36 ID 96 with timestamp +1486
Ready to process requests.