[Из песочницы] WiFi Enterprise. FreeRadius + FreeIPA + Ubiquiti

2wtmtwbdgzq2u6yp-ujvywpl4rw.jpeg

Уже были описаны некоторые примеры организации корпоративного WiFi. Здесь я распишу как реализовал подобное решение и проблемы с которыми пришлось столкнуться при подключении на разных устройствах. Будем использовать уже имеющейся LDAP с заведенными пользователями, поднимем FreeRadius и настроим WPA2-Enterprise на контроллере Ubnt. Вроде все просто. Посмотрим…

Немного о методах EAP


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

Из википедии:

EAP — фреймворк аутентификации, который часто используется в беспроводных сетях и соединениях точка-точка. Формат был впервые описан в RFC 3748 и обновлён в RFC 5247.
EAP используется для выбора метода аутентификации, передачи ключей и обработки этих ключей подключаемыми модулями называемыми методами EAP. Существует множество методов EAP, как определенных вместе с самим EAP, так и выпущенных отдельными производителями. EAP не определяет канальный уровень, он только определяет формат сообщений. Каждый протокол использующий EAP имеет собственный протокол инкапсуляции сообщений EAP.


Сами методы:

  • LEAP — проприетарный протокол, разработан CISCO. Найдены уязвимости. В настоящее время не рекомендуется использовать
  • EAP-TLS — хорошо поддерживаемый среди вендоров беспроводных соединений. Является безопасным протоколом, поскольку является преемником SSL стандартов. Настройка клиентской достаточно сложна. Нужен клиентский сертификат помимо пароля. Поддерживается во многих системах
  • EAP-TTLS — широко поддерживается во многих системах, предлагает хорошую безопасность, используя PKI сертификаты только на сервере аутентификации
  • EAP-MD5 — другой открытый стандарт. Предлагает минимальную безопасность. Уязвим, не поддерживает взаимную аутентификацию и генерацию ключей
  • EAP-IKEv2 — основан на Internet Key Exchange Protocol version 2. Обеспечивает взаимную аутентификацию и установление сеансового ключа между клиентом и сервером
  • PEAP — совместное решение CISCO, Microsoft и RSA Security как открытый стандарт. Широко доступен в продуктах, обеспечивает очень хорошую безопасность. Схож с EAP-TTLS, требуя только сертификат на серверной стороне
  • PEAPv0/EAP-MSCHAPv2 — после EAP-TLS, это второй широко используемый стандарт в мире. Используется клиент-серверная взаимосвязь в Microsoft, Cisco, Apple, Linux
  • PEAPv1/EAP-GTC — создан Cisco как альтернатива PEAPv0/EAP-MSCHAPv2. Не защищает аутентификационные данные в любом случае. Не поддерживаются в Windows OS
  • EAP-FAST — метод, разработанный Cisco для исправления недостатков LEAP. Использует Protected Access Credential (PAC). Полностью не доработан


Из всего этого разнообразия, выбор все таки не велик. От метода аутентификации требовалось: хорошая безопасность, поддержка на всех устройствах (Windows 10, macOS, Linux, Android, iOS) и, собственно, чем проще, тем лучше. Поэтому выбор пал на EAP-TTLS в связке с протоколом PAP.
Возможно возникнет вопрос — Зачем же использовать PAP? ведь он передает пароли в открытом виде?

Да, все верно. Общение между FreeRadius и FreeIPA будет проходить именно в так. В режиме дебага можно отследить как отправляются username и password. Да и пусть отправляются, только у вас есть доступ к серверу FreeRadius.

Подробнее о работе EAP-TTLS можно почитать тут

FreeRADIUS


FreeRadius будем поднимать на CentOS 7.6. Здесь ничего сложного, ставим обычным способом.

yum install freeradius freeradius-utils freeradius-ldap -y


Из пакетов ставится версия 3.0.13. Последнюю можно взять на https://freeradius.org/

После этого FreeRadius уже работает. Можно в /etc/raddb/users расскоментировать строчку

steve   Cleartext-Password := "testing"


Запустить в сервер в режиме дебага

freeradius -X


И делаем тестовое подключение с localhost

radtest steve testing 127.0.0.1 1812 testing123


Получили ответ Received Access-Accept Id 115 from 127.0.0.1:1812 to 127.0.0.1:56081 length 20, значит все хорошо. Идем дальше.

Подключаем модуль ldap.

ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap


И сразу его изменим. Нам нужно, чтобы FreeRadius мог обращаться к FreeIPA

mods-enabled/ldap
ldap {
server="ldap://ldap.server.com"
port=636
start_tls=yes
identity="uid=admin,cn=users,dc=server,dc=com"
password=**********
base_dn="cn=users,dc=server,dc=com"
set_auth_type=yes
...
user {
base_dn="${..base_dn}"
filter="(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
}
...


Перезапускаем radius-сервер и проверяем синхронизацию пользователей LDAP:

radtest user_ldap password_ldap localhost 1812 testing123


Редактируем eap в mods-enabled/eap
Здесь добавим два экземпляра eap. Они будут отличаться только сертификатами и ключами. Чуть ниже объясню, почему именно так

mods-enabled/eap
eap eap-client {                                                                                                                                                                                                                           default_eap_type = ttls                                                                                                                                                                                                                 timer_expire = 60                                                                                                                                                                                                                       ignore_unknown_eap_types = no                                                                                                                                                                                                          cisco_accounting_username_bug = no                                                                                                                                                                                                      max_sessions = ${max_requests}
           tls-config tls-common {
           private_key_file = ${certdir}/fisrt.key
           certificate_file = ${certdir}/first.crt
           dh_file = ${certdir}/dh
           ca_path = ${cadir}
           cipher_list = "HIGH"
           cipher_server_preference = no
           ecdh_curve = "prime256v1"
           check_crl = no
           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                 
           ttls {
           tls = tls-common
           default_eap_type = md5
           copy_request_to_tunnel = no
           use_tunneled_reply = yes
           virtual_server = "inner-tunnel"
           }
}
eap eap-guest {
default_eap_type = ttls                                                                                                                                                                                                                 timer_expire = 60                                                                                                                                                                                                                       ignore_unknown_eap_types = no                                                                                                                                                                                                          cisco_accounting_username_bug = no                                                                                                                                                                                                      max_sessions = ${max_requests}
           tls-config tls-common {
           private_key_passwotd=blablabla
           private_key_file = ${certdir}/server.key
           certificate_file = ${certdir}/server.crt
           dh_file = ${certdir}/dh
           ca_path = ${cadir}
           cipher_list = "HIGH"
           cipher_server_preference = no
           ecdh_curve = "prime256v1"
           check_crl = no
           }
                                                                                                                                                                                                                                                                                                                                                                                                                                                 
           ttls {
           tls = tls-common
           default_eap_type = md5
           copy_request_to_tunnel = no
           use_tunneled_reply = yes
           virtual_server = "inner-tunnel"
           }
}


Далее редактируем site-enabled/default. Интересуют разделы authorize и authenticate.

site-enabled/default
authorize {
  filter_username
  preprocess
  if (&User-Name == "guest") {
   eap-guest {
       ok = return
   }
  }
  elsif (&User-Name == "client") {
    eap-client {
       ok = return 
    }
  }
  else {
    eap-guest {
       ok = return
    }
  }
  ldap
  if ((ok || updated) && User-Password) {
    update {
        control:Auth-Type := ldap
    }
  }
  expiration
  logintime
  pap
  }

authenticate {
  Auth-Type LDAP {
    ldap
  }
  Auth-Type eap-guest {
    eap-guest
  }
  Auth-Type eap-client {
    eap-client
  }
  pap
}


В секции authorize убираем все модули, которые нам не нужны. Оставляем только ldap. Добавляем проверку клиента по username. Именно для этого мы добавляли выше два экземпляра eap.

Multi EAP

Дело в том, что подключая некоторые устройства мы будем использовать системные сертификаты и указывать домен. У нас есть сертификат и ключ от доверенного центра сертификации. Лично по моему мнению такая процедура подключения проще, чем кидать на каждое устройство самоподписанный сертификат. Но и без самоподписанных сертификатов все же не получилось уйти. Samsung девайсы и Android =< 6 версии не умеют использовать системные сертификаты. Поэтому для них создаем отдельный экземпляр eap-guest с самоподписанными сертификатами. Для всех других устройств будем использовать eap-client c доверенным сертификатом. User-Name определяется по полю Anonymous при подключении устройства. Разрешено использовать только 3 значения: Guest, Client и пустое поле. Остальное все отбрасывается. Это настраиватся в политиках. Пример приведу чуть позже


Отредактируем секции authorize и authenticate в site-enabled/inner-tunnel

site-enabled/inner-tunnel
authorize {
  filter_username
  filter_inner_identity
  update control {
   &Proxy-To-Realm := LOCAL
  }
  ldap
  if ((ok || updated) && User-Password) {
    update {
        control:Auth-Type := ldap
    }
  }
  expiration
  digest
  logintime
  pap
  }

authenticate {
  Auth-Type eap-guest {
    eap-guest
  }
  Auth-Type eap-client {
    eap-client
  }
  Auth-Type PAP {
    pap
  }
  ldap
}


Далее нужно прописать в политиках, какие имена можно использовать для анонимного входа. Редактируем policy.d/filter.

Нужно найти строчки похожие на это:

if (&outer.request:User-Name !~ /^(anon|@)/) {
  update request {
    Module-Failure-Message = "User-Name is not anonymized"
  }
  reject
}


И ниже в elsif добавить нужные значения:

elsif (&outer.request:User-Name !~ /^(guest|client|@)/) {
  update request {
    Module-Failure-Message = "User-Name is not anonymized"
  }
  reject
}


Теперь нам нужно переместиться в директорию certs. Сюда нужно положить ключ и сертификат от доверенного центра сертификации, который у нас уже есть и нужно сгенерировать самоподписанные сертификаты для eap-guest.

Изменяем параметры в файле ca.cnf.

ca.cnf

...
default_days = 3650
default_md = sha256
...
input_password = blablabla
output_password = blablabla
...
countryName = RU
stateOrProvinceNmae = State
localityNmae = City
organizationName = NONAME
emailAddress = admin@admin.ru
commonName = "CA FreeRadius"


Такие же значения прописываем в файле server.cnf. Меняем только
commonName:

server.cnf

...
default_days = 3650
default_md = sha256
...
input_password = blablabla
output_password = blablabla
...
countryName = RU
stateOrProvinceNmae = State
localityNmae = City
organizationName = NONAME
emailAddress = admin@admin.ru
commonName = "Server Certificate FreeRadius"


Создаем:

make


Готово. Полученные server.crt и server.key у нас уже прописаны выше в eap-guest.

И последнее, добавим наши точки доступа в файл client.conf. У меня их 7. Чтобы не добавлять каждую точку отдельно, пропишем только сеть в котороый они находятся (у меня точки доступа находятся в отдельном VLAN).

client APs {
ipaddr = 192.168.100.0/24
password = password_AP
}


Контроллер Ubiquiti


На контроллере поднимаем отдельную сеть. Пусть будет 192.168.2.0/24
Идем в настройки → профиль. Cоздаем новый:

n4mj_shukldt1eogoqnpphaal3e.png

Прописываем адрес и порт radius-сервера и пароль, который прописывали в файле clients.conf:

6x8ekm2bbnrzghk0rv5qbdggnam.png

Создаем новое имя беспроводной сети. В качестве метода аутентификации выбираем WPA-EAP (Enterprise) и указываем созданный radius-профиль:

5iku9n_j-r3fqsxvppyekim8aqi.png

Все сохраняем, применяем и идем дальше.

Настройка клиентов


Начнем с самого сложного!

Windows 10


Сложность сводится к тому, что Windows пока еще не умеет подключаться к корпоративному WiFi по домену. Поэтому приходится вручную закидывать наш сертификат в хранилище доверенных сертификатов. Здесь можно использовать как самоподписанный так и от центра сертификации. Я буду использовать второй.

Далее нужно создать новое подключение. Для этого идем в параметры сети и Интернет → Центр управления сетями и общим доступом → Создание и настройка нового подключения или сети:

7d9eixr7yfn94zmiv56f1kqpm_o.png

-ziydpjwwwqxkgisvkxmj4kpfse.png

jghdw32jkf-d-9gxs71ca2o-q9y.png

Вручную прописываем имя сети и меняем тип безопасности. После нажимаем на изменить параметры подключения и во владке Безопасность выбираем проверку подлинности сети — EAP-TTLS.

gqtgx6svylvh5sqmxrcjmovj-10.png

kn7la8fhk6a2fh8vkjtwvsji1gu.png

y1tlgv2-xbwqn-lcupnyiwpxz3s.png

Заходим в параметры, прописываем конфиденциальность аутентификации — client. В качестве доверенного центра сертификации выбираем добавленный нами сертификат, ставим галочку «Не выдавать пользователю приглашение, если не удается авторизовать сервер» и метод проверки подлинности выбираем — незашифрованный пароль (PAP).

5xww3jjmvmf1rhkdxcqvoxh0l18.png

Далее заходим в дополнительные параметры, ставим галочку на «Укажите режим проверки подлинности». Выбираем пункт «Проверка подлинности пользователя» и нажимаем на сохранить учетные данные. Здесь надо будет ввести username_ldap и password_ldap

e5lvxualbxusv6ksq1iqwhiodyi.png

omhetcqvchjagt5mcqjo_e5hq0m.png

2pniocysbjtvvzgoa5yqw5ahl_g.png

Все сохраняем, применяем, закрываем. Можно подключаться к новой сети.

Linux


Я проверял на Ubuntu 18.04, 18.10, Fedora 29, 30.

Для начала, скачиваем себе сертификат. Я не нашел в Linux, есть ли возможность использовать системные сертификаты и есть ли там вообще такое хранилище.

Будем подключаться по домену. Поэтому нужен сертификат удостоверяющего центра, у которого был приобретен наш сертификат.

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

_bbvksnhgramkno1xteuugeiicu.png

anonymous — client
domain — домен, на который выпущен сертификат

Android


non-Samsung


C 7 версии при подключении WiFi можно использовать системные сертификаты, указав только домен:

ftmaclvd6hgnr6l61f1ntqx4pho.png

domain — домен, на который выпущен сертификат
anonymous — client

Samsung


Как уже писал выше, Samsung-устройства не умеют использовать системные сертификаты при подключении WiFi, и у них нет возможности подключаться по домену. Поэтому надо вручную добавить корневой сертификат центра сертификации (ca.pem, берем на Radius сервере). Вот здесь будет использовать самоподписанный.

Скачиваем сертификат себе на устройство и устанавливаем его.

Установка сертификата
jwvnp6k3hcvgr_-sxahbjjfwuma.png

vw-u2crpfqhzv2hewbw4fvcm0k8.png

fnn-i6gkkzzt6w9hxjpv5fgo_sk.png

xkpc-2wufsgnckjexjhmiv79avy.png

При этом, надо будет установить рисунок разблокировки экрана, пин-код или пароль, если он еще не установлен:

_waapxwklsloxwpvo3oe8mrdwek.png

v6nxk1ts6ej-j8sffb1kpqfx9ae.png

Я показал сложный вариант установки сертификата. На большинстве устройств достаточно просто нажать на скаченный сертификат.


Когда сертификат установлен, можно переходить к подключению:

rr9lvx4jov8ohepj-hetehl4g1s.png

сертификат — указываем тот, который устанавливали
анонимный пользователь — guest

macOS


Яблочные устройства из коробки могут подключаться только к EAP-TLS, но все равно нужно закидывать им сертификат. Чтобы указать другой метод подключения, нужно воспользоваться Apple Configurator 2. Соответственно нужно предварительно скачать его на мак, создать новый профиль и добавить все необходимые настройки WiFi.

Apple Configurator
tgmjzi_qpkrel011yzj5q5h23qs.png

dwdddlobqibczjpygjt1f-cnbp8.png

Здесь указываем имя своей сети
Security Type — WPA2 Enterprise
Accepted EAP Types — TTLS
User Name и Password — оставляем пустыми
Inner Authentication — PAP
Outer Identity — client

Вкладка Trust. Здесь указываем наш домен

Все. Профиль можно сохранять, подписывать и распространять на устройства


После того, как профиль готов, его нужно скачать на мак и установить. В процессе установки нужно будет указать usernmae_ldap и password_ldap пользователя:

_zum7mpbqlszgaq5d9cm6k7-why.png

hbiqigx3cy7zdklsbnx22zmb0e4.png

u4tb-8v3jbt9t5gs9zz9tplbnt0.png

iOS


Процесс аналогичен macOS. Нужно использовать профиль (можно прям такой же как для macOS. Как создавать профиль в Apple Configurator, смотреть выше).

Скачиваем профиль, устанавливаем, вводим учетные данные, подключаемся:

pigx3mjskrdwyuk07xs0m6zh-v4.png

y9hk6gm7k5jkdrvms-stzkdmu9s.png

iexta-krrvub6rrozdvmk7adh_s.png

ejoowjqmtjojl31jmau1z3np7mi.png

pws4enrdkqc97p009eglr3wpiy0.png

zjz_5f7hqthgj52z_nnigigrcm4.png

На этом все. Мы настроили Radius сервер, синхронизировали его с FreeIPA и указали точкам доступа Ubiquiti использовать WPA2-EAP.

Возможные вопросы


В: как передавать профиль/сертификат сотруднику?

О: Все сертификаты/профили я храню на фтп с доступом через веб. Поднял гостевую сеть с ограничением по скорости и доступом только в интернет, за исключением фтп.
Аутентификация держится 2 дня, после чего сбрасывается и клиент остается без интернета. Т.о. когда сотрудник хочет подключиться к WiFi, сначало он подключается к гостевой сети, заходит на фтп, скачивает нужный ему сертификат или профиль, устанавливает их, и после может подключаться к корпоративной сети.

В: почему не использовать схему с MSCHAPv2? она же более безопасная!

О: во-первых, такая схема хорошо работает на NPS (Windows Network Policy System), в нашей реализации необходимо дополнительно настраивать LDAP (FreeIpa) и хранить хэши паролей на сервере. Доп. настройки делать не желательно, т.к. это может привести к различным проблемам сихронизации УЗ. Во-вторых, хеш представляет собой MD4, так что это не особо повышает безопасность

В: можно ли авторизовывать устройтсва по mac-адресам?

О: НЕТ, это не безопасно, злоумышленник может подменить мак-адреса, и тем более авторизация по мак-адресам не поддерживается на многих устройствах

В: зачем вообще все эти сертификаты использовать? можно же и без них подключаться

О: сертификаты используются, чтобы авторизовать сервер. Т.е. устройство при подключении проверяет тот ли это сервер, которому можно доверять или нет. Если тот, то аутентификация проходит дальше, если нет, соединение закрывается. Можно подключаться без сертификатов, но если злоумышленик или сосед поднимет у себя дома radius-сервер и точку доступа с таким же именем как у нас, он сможет легко перехватить учетные данные пользователя (не забываем, что они передаются в открытом виде). А когда используется сертификат, враг увидит у себя в логах только наши вымышленные User-Name — guest или client и ошибку типа — Unknown CA Certificate

еще немного про macOS

Обычно на macOS переустановка системы делается через интернет. В режиме восстановления мак надо подключить к WiFi, и здесь не сработает ни наш корпоративный WiFi, ни гостевая сеть. Лично я поднял еще одну сеть, обычную по WPA2-PSK, скрытую, только для технических операций. Либо еще можно заранее сделать загрузочную флешку с системой. Но если мак после 2015 года, надо будет еще найдит адаптер для это флешки)

© Habrahabr.ru