Уже были описаны некоторые примеры организации корпоративного 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оздаем новый:



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



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



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

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


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

Windows 10


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

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







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







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



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







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

Linux


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

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

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

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



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

Android


non-Samsung


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



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

Samsung


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

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

Установка сертификата








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





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

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



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

macOS


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

Apple Configurator




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


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

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

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







iOS


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

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













На этом все. Мы настроили 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 года, надо будет еще найдит адаптер для это флешки)

Комментарии (6)


  1. yurybx
    11.08.2019 15:53

    Скажите, а безопасна ли схема, при которой рабочие станции-члены домена подключаются к wifi-сети, авторизуясь с проверкой подлинности компьютера (сертификаты не используется)? Осуществляется ли при этом авторизация сервера?


    1. i_gerasimov Автор
      11.08.2019 22:56

      если у Вас используется схема EAP-TTLS, и в домене рабочие станции получают сертификат сервера, то все отлично. Если проверка сервера не осуществляется, то все плохо. Как у Вас организована проверка подлинности компьютера на Radius-сервере?


      1. yurybx
        12.08.2019 15:36

        У нас используется EAP в качестве проверки подлинности сети, и при этом галка «подтверждать удостоверение сервера с помощью проверки сертификата» — снята. Спасибо за Вашу статью, теперь я знаю, что наша беспроводная сеть уязвима, и мне будет чем заняться в ближайшее время!


  1. e_fail
    12.08.2019 16:14

    Спасибо, добрый человек! Творчески переосмыслив мануал, я наконец-то смог подключить свой ноут с Win10 к корпоративному вайфаю. До этого приходилось использовать тезеринг через смарт с андроидом — там всё из коробки работает, без плясок с бубном.


  1. dragoangel
    13.08.2019 10:35

    Как по мне PEAP куда проще. Ленивые юзеры и с ним умудряются жаловаться на неудобства, что говорить когда даже технически подкованного специалиста задолбает к этому подключаться?
    Кула то идти за клиент сертификатом который один на всех и попробуй его отозвать потом… Если у вас Windows среда с DC — поднимите прямо на DC серверах NPSы и сможете не только по человечески безопасную авторизацию проходить но и выдавать VLAN на основе принадлежности User к OU или Group. И машины простаивать не будут и надёжность будет. В догонку Unifi умеет обнаруживать и отсылать алерты об EvilAP по почте. Зачем все усложнять


    1. i_gerasimov Автор
      14.08.2019 12:24

      Согласен, только если есть DC)
      Сертификат нужен не клиентский, а сертификат сервера. Например, если сотрудник берет с собой ноут домой, чтобы он никоем образом не смог подключиться к подменной точке. А отзывать сертификат не надо, блокировка делается в LDAP
      И я не упоминал о подменных точках доступа в поле зрения Unifi) Понятно, что контроллер будет алерты слать и заблокирует видимость этой точки. Речь идет о носимых устройствах вне офиса.