====== Делаем закрытую сеть Wi-Fi с авторизацией по МАС-адресу на основе двух точек TP-Link TL-WR842ND. ====== FIXME **Цель:** организовать закрытую сеть WiFi cо списком доступа по MAC-адресу и централизованным управлением этим списком на точках доступа TP-Link TL-WR842ND. Решаемые задачи: - Выбор методов авторизации и аутентификации с учетом ограничений используемого оборудования. - Выполнение настройки выбранного метода. Требуемый уровень безопасности допускает организацию доступа к беспроводной сети на основе списка разрешенных MAC-адресов. В тоже время есть потребность ограничить любого желающего от доступа к сети. Хотя с другой стороны, любой желающий, просканировав эфир, может определить MAC-адреса разрешенных пользователей, и подключиться к сети скопировав полученный MAC на свой беспроводной интерфейс. Это противоречие и предстоит разрешить в работе: ограничить возможность доступа к сети «любому желающему» наиболее простыми методами с возможностью централизованного управления доступом (без надобности вносить изменения на каждой точке доступа в отдельности). ====== Введение ====== Для знакомства с теорией безопасности ''Wi-Fi'', то неплохой обзор есть на Хабре: [[http://habrahabr.ru/post/150179/|WPA2-Enterprise, или правильный подход к безопасности Wi-Fi сети]] Добавим то, что автор при сравнении ''WPA2 Personal'' и ''WPA2 Enterprise'' основным отличием считает использование индивидуального ключа на каждого пользователя в ''WPA2 Enterprise''. А нам интересен ''WPA2 Enterprise'' для централизованного управления клиентами, а именно ведения списка ''MAC''-адресов. ''FreeRADIUS'' из коробки уже настроен на многие типы авторизации, конфиг достаточно большой и разбит на отдельные файлы. Понять что от чего зависит сходу достаточно непросто. Вот перевод статейки которая приблизительно описывает, чем занимается радиус сервер, чтобы разрешить или запретить доступ к сети. ===== RADIUSPicking Auth-TypeAuthenticating ===== [[http://wiki.freeradius.org|Официальная WiKi FreeRADIUS]] настоятельно рекомендует новичкам прочитать эту страничку [[http://wiki.freeradius.org/guide/Concepts| How things work in RADIUSPicking an Auth-TypeAuthenticating a userInsufficient information]]. :!: Вот мой вольный перевод этой статьи, за достоверность не ручаюсь. И на всякий случай синхронизирую термины: * Клиент в данном контексте ( с точки зрения ''RADIUS''-сервера) - это точка доступа. * Пользователь (supplicant) - тот, кто хочет получить доступ в сеть используя точку доступа. * Авторизация - с точки зрения настроек ''RADIUS'' (как я это понимаю), проверка наличия необходимых данных о пользователе для осуществления аутентификации. Хотя в широком смысле - процесс определения прав, предоставляемых пользователю. * Аутентификация - процесс проверки пользователя, то есть является ли пользователь тем, кем о себе заявляет на этапе авторизации. ---- Большинство проблем с конфигурацией связаны с непониманием концепции ''FreeRADIUS''. Редактирование конфигурационных файлов и перебор возможных опций не поможет понять концепцию. Ни вы, ни радиус не знает и не решает, что клиент вам пришлет в запросе. Ответственность за то, что содержится в запросе лежит 100% на клиенте. Радиус сервер смотрит на запрос и говорит: Хмм... Могу ли я справится с этим запросом? Ответ на этот вопрос зависит от того, какие типы аутентификации вы включили, что сервер может найти в базе данных, и что содержится в запросе. Сервер начинает опрашивать модули этапа авторизации (в конфиге есть отдельная секция ''authorize {}''): Модуль Unix, можешь ли ты обработать это? Модуль Pap, можешь ли ты обработать это? Модуль Mschap, можешь ли ты обработать это? В какой-то момент один из модулей скажет: Да, я вижу в запросе нечто, что могу распознать. И я могу что-нибудь сделать! Модули делают это на основании просмотра ключевых атрибутов пришедших в запросе, таких как ''MS-CHAP-Challenge'' (для ''MS-CHAP''), или ''CHAP-Challenge'' (для ''CHAP''), or EAP-Message (для ''EAP''). Или же на основании предположения, что надо бы добавить что-то в каждый запрос. Если модуль думает, что у него есть шанс чтобы ещё и аутентифицировать пользователя, он скажет: Я не могу аутентифицировать этого пользователя сейчас ( Я просто говорю, чтобы авторизовать его) Но мой приятель в секции Authenticate может! Эй, добавьте Auth-Type для меня! Если модуль ничего не распознаёт, или знает, что нет необходимости что-то искать, то он просто ничего не делает. В конце авторизации, сервер проверит добавлен ли Auth-Type к запросу. Если нет, то немедленно отклонит запрос. Давайте предположим, что клиент отправил запрос с атрибутом User-Password, и модуль pap включен в секции ''autorize {}''. Тогда pap модуль установит Auth-Type = pap. Таким образом, сервер снова обратится к модулю pap, но уже на стадии аутентификации ( она также имеет свою секцию в конфиге ''authenticate {}''), pap ответит: Я вижу User-Password, который вводил пользователь. Это замечательно, но мне нужно его с чем-то сравнить. Ах! Другой модуль добавил «правильный» пароль для этого пользователя еще на стадии авторизации! Итак, затем идет сравнение локального заранее известного правильного пароля с тем, который ввел пользователь (пришел в запросе). Это то, как работает аутентификация. «правильный» пароль (заранее известный правильный пароль) был добавлен другим модулем. Например, модуль pap просто выполняет PAP аутентификацию и ничего больше. Преимущества такого подхода в том, что «правильный» пароль может быть добавлен в запрос из текстового файла ''users'', ''SQL'', ''LDAP'', ''/etc/passwd'', внешней программы и т.д. и т.п. в очень широких пределах. Например, если подключен модуль ''LDAP'' в секции ''authorize {}'', и сервер обрабатывает запрос, то если модуль найдет у себя запись с паролем (где-нибудь в каталоге [[ldap:ldap|LDAP]]), то он добавит этот пароль в запрос, чтобы другой модуль на этапе аутентификации мог использовать его. Что, если клиент отправит ''MSCHAP'' запрос? Что будет с этим запросом делать радиус-сервер? В этом случае, модуль mschap ищет в запросе атрибут ''MS-CHAP'' на этапе авторизации и когда находит устанавливает атрибут Auth-Type на себя (mschap), но уже для этапа аутентификации. Модуль базы данных (например, такой как LDAP, выше) получает информацию о «правильном» пароле и добавляет её в запрос. Затем модуль mschap вызывается уже для процесса аутентификации. Он просматривает запрос в поисках «правильного» пароля либо в виде текста, либо в виде NT-HASH (почему? Смотрите таблицу протоколов http://deployingradius.com/documents/protocols/compatibility.html ). Если ни один требуемый вид пароля не будет предоставлен хранилищем данных, то mschap скажет: Извините, я не могу аутентифицировать пользователя, потому что не имею достаточно информации, мне нужно проверить MSCHAP. Но сервер уже исчерпал варианты, его единственный вариант был mschap, так как это то, что клиент послал в запросе. Mschap модуль не смог ничего сделать, потому что ему не предоставили «правильный» пароль. Таким образом сервер за неимением вариантов запрос отклоняет. MSCHAP данные могли быть корректными, но у сервера не было способа убедиться в этом. Поэтому он ответил отказом. ===== Выводы ===== * FreeRADIUS организован по модульному принципу. Для того чтобы ''FreeRADIUS'' имел поддержку того или иного протокола, нужно подключить/отключить модуль в конфигурации. Многие, если не все модули имеют свою секцию конфигурации в общем конфиге. * Поступивший запрос проходит процедуру авторизации, для настройки есть отдельная секция в конфигурационном файле ''authorize {}''. Запрос обрабатывается попорядку перечисленными в секции модулями, модули пытаются распознать атрибуты и в случае успеха, авторизуют пользователя, указанного в запросе. По сути это означает, что в запрос добавляется атрибут Auth-Type, где указывается каким методом (модулем) производить аутентификацию. На этом же этапе модули реализующие хранилище данных ищут в своих базах данные, на указанного в запросе пользователя и также добавляют их к запросу. Если в процессе авторизации ''Auth-Type'' не установлен, то запрос откланяется. Иначе запрос переходит на этап аутентификации. * Методы аутентификации настраиваются в секции authenticate {}. Тут запрос поступает в модуль, который задан в атрибуте Auth-Type. На основании данных вставленных в запрос из модуля-хранилища еще на предыдущем этапе происходит сравнение атрибутов пришедших от клиента с атрибутами из хранилища. На основании этого сравнения уже принимается решение о разрешении или отклонении доступа, либо об уточнении параметров у клиента. * Вот такая концепция у радиус-сервера, в данном случае до безобразия упрощенная. ====== 1. Обоснование ====== На имеющихся беспроводных маршрутизаторах TP-Link TL-WR842ND с заводской прошивкой у нас есть возможность использовать следующие типы защиты: WPA2–PSK, WPA2–Enterprise. Остальные варианты не рассматривались из-за их неактуальности: открытая сеть не соответствует поставленной цели; WEP – давно скомпрометирован; WPA-PSK/Enterprise – есть же WPA2 c более строгим подходом к шифрации. WPA2-PSK – использует Pre-shared key, который в общем случае устраивал бы, но так как было желание управлять допущенными к сети MAC-адресами пользователей централизованно, а не на каждой точке в отдельности, доставляет некоторое неудобство. WPA2-Enterprise – использует RADIUS-сервер для авторизации/аутентификации; учет пользователей (accounting) не поддерживается точкой доступа TP-Link TL-WR842ND. Отправляет в запросе к RADIUS MAC-адрес пользователя – следовательно можно вести список разрешенных MAC на RADIUS-сервере. WR842ND не умеет подставлять MAC-адрес вместо имени пользователя и пароля (такая возможность есть, например, в RouterOS от Mikrotik), поэтому придется заводить учетные данные (пользователь/пароль) либо на каждого пользователя можно с привязкой к MACy, либо одну общую учетку, о которой будут осведомлены все заинтересованные пользователи, а список MAC-адресов будет вестись отдельно. Так как централизованно управлять списком доступа на основании MAC-адресов позволяет RADIUS-сервер, то выбор защиты Wi-Fi сети пал на WPA2-Enterprise. WPA2-Enterprise поддерживает ряд методов аутентификации EAP. Для Window актуальны EAP-TLS и EAP-PEAPv0. EAP-TLS – поможет избавить пользователя от введения логина и пароля, но здесь встанет другая задача по разворачиванию инфраструктуры открытых ключей и распределению сертификатов. Причем встанет проблема установки сертификатов на мобильных устройствах. Хоть данный метод самый надёжный, но из-за сложности развёртывания и сопровождения для наших нужд он отпадает. EAP-PEAPv0 с MS-CHAPv2 – от пользователя требуется доверие к точке доступа/серверу и знание связки логин/пароль. Доверие к точке доступа/серверу достигается проверкой предъявляемого сервером сертификата, либо отключением этой проверки. Суть метода состоит в создании защищённого туннеля внутри которого осуществляется аутентификация пользователя по методу MS-CHAPv2. Простое развёртывание и сопровождение, особенно если слепо доверять точке доступа/серверу. Но страдает безопасность от «активных» злоумышленников. Метод EAP-PEAPv0 с MS-CHAPv2 существенно проще в реализации, чем EAP-TLS и позволит организовать закрытую сеть, тем самым «любому желающему» будет гораздо сложнее, нежели просто определить разрешенный MAC-адрес, если конечно у него не будет альтернативного метода получения доступа к учетным данным. Реализация метода EAP-PEAPv0 с MS-CHAPv2 во FreeRADIUS позволяет выдавать пользователю индивидуальную связку логин/пароль и привязывать их к MAC-адресу его оборудования. Хотя для наших целей это было признано нецелесообразным из-за дополнительной нагрузки на администраторов сети по сопровождению пользователей. Поэтому будет общий логин/пароль на всех, так как некоторые wi-fi клиенты не дают возможности оставлять данные поля пустыми. Итог: беспроводной маршрутизатор TP-Link TL-WR842ND будет работать в режиме точки доступа с методом безопасности WPA2-Enterprise, который предполагает использование RADIUS-сервера. RADIUS-сервер на базе FreeRADIUS будет реализовывать список доступа на основе MAC-адресов и производить аутентификацию пользователей по методу EAP-PEAPv0 с MS-CHAPv2. При данном методе, пользователю необходимо доверять точеке доступа/серверу (или проверять сертификат для установки доверия) и знать учетные данные (логин/пароль) для прохождения MS-CHAPv2 аутентификации. ====== 2. Реализация ====== Демон FreeRADIUSa после установки сразу же стартует, то есть после выполнения команды ''apt-get install freeradius'' мы имеем на выходе запущенный RADIUS-сервер. Официальная документация рекомендует вносить как можно меньше изменений в исходную конфигурацию, ибо она продумана для многих типичных задач RADIUS-сервера. FreeRADIUS «из коробки» уже умеет работать с WPA2-Enterprise, в том числе и с EAP-PEAPv0 c внутритуннельной аутентификацией MS-CHAPv2. Поэтому настройка FreeRADIUS заключается в том, чтобы создать собственный сертификат сервера, завести клиентов (точки доступа) , завести учетные данные для MS-CHAPv2 и добавить возможность фильтрации запросов по MAC-адресами из разрешенного списка. Следует отметить, что приведенные команды и фрагменты конфигурации тестировались на Debian 7.5 c FreeRADIUS 2.1.12+dfsg-1.2 ===== 2.1 Создание production-сертификатов ===== Так как большинство методов корпоративного WPA2 требуют наличия сертификата и закрытого ключа как минимум на сервере, то придется его создать. Чтобы создать самоподписанный сертификат нам нужен сертификат и закрытый ключ собственного удостоверяющего центра, которые тоже придется создать. Инструменты для создания сертификатов нужных freeradius у Debian лежат по пути /usr/share/doc/freeradius/examples/certs. Содержимое этого каталога следует скопировать в /etc/freeradius/certs. Необходимы файлы: * Makefile * ca.cnf * server.cnf * xpextensions, А также можно скопировать README, в котором расписано что и зачем нужно и как этим пользоваться, поэтому дальше пойдут необходимые команды с краткими пояснениями, за более подробной инфой в README. Для работы скриптов понадобится openssl и make. Создаем файл с параметрами Диффи-Хеллмана, если он вдруг отсутствует в каталоге /etc/freeradius/certs: # make dh Результат работы: файл dh Создаём корневой сертификат или **сертификат удостоверяющего центра**. Если до этого уже были какие-то сертификаты (обычно тестовые), то удаляем: # rm -f *.pem *.der *.csr *.crt *.key *.p12 serial* index.txt* Редактируем под себя файл ''ca.cnf''. Следует обратить внимание на ''default_md = md5'' (лучше поставить sha1), ''default_days = 365'' ( возможно через год не захочется генерировать новый сертификат, тогда лучше ставить побольше), ''input_password/output_password'' и нужно отредактировать под себя всю секцию ''[certificate_authority]''. Далее выполняем: # make ca.pem # make ca.der Результаты работы: ''ca.pem'', ''ca.key'' и ''ca.der'' – сертификат удостоверяющего центра, его закрытый ключ и сертификат в формате понятном для Windows соответсвенно. **Создание серверного сертификата**: Редактируем под себя файл ''server.cnf''. Следует обратить внимание на ''default_md = md5'' (лучше поставить sha1), ''default_days = 365'' ( возможно через год не захочется генерировать новый сертификат, тогда лучше ставить побольше), ''input_password/output_password'' и нужно отредактировать под себя всю секцию ''[server]''. Важно чтобы значение ''commonName'' отличалась от соответствующего сертификата удостоверяющего центра. Далее выполняем: # make index.txt # make serial # make server.pem Результат работы: помимо прочих файлы ''server.pem'' и ''server.key'' – сертификат и закрытый ключ сервера. В конфигурации пути к сертификатам сгенерированным в папке /etc/freeradius/certs прописаны по умолчанию. Если был изменён пароль на закрытый ключ сервера (''output_password''), то его придется указать в конфиге. А также нужно закомментировать путь к скрипту создания временных сертификатов. Это делается в файле /etc/freeradius/eap.conf в следующей секциии: eap { ... tls { ... private_key_password=пароль ... # make_cert_command = "${certdir}/bootstrap" ... } ... } ===== 2.2 Описываем RADIUS-клиентов (точки доступа) ===== Добавляем в файл ''/etc/freeradius/clietns.conf'' следующее: client TL-WR842ND_1 { ipaddr = 192.168.0.2 secret = secret1 } client TL-WR842ND_2 { ipaddr = 192.168.0.3 secret = secret2 } ===== 2.3 Заводим учетные данные для аутентификации по логину и паролю ===== В файл ''/etc/freeradius/users'' добавляем первую строку следующего содержания: user Cleartext-Password := "pass" ===== 2.4 Добавляем список доступа на основе MAC-адресов ===== (по мотивам [[http://wiki.freeradius.org/guide/Mac%20Auth]]) Конфигурация FreeRADIUS не поддерживает списка MAC-адресов из коробки. Хотя MAC-адрес можно указать как дополнительный атрибут проверки в файле ''/etc/freeradius/users'', например: user Cleartext-Password := "pass", Calling-Station-Id == "1a-2b-3c-4d-5e-6f" Для запроса с именем пользователя ''user'' будет проверяться пароль и сравниваться атрибут ''Calling-Station-Id''. Чтобы это работало в случае ЕAP-PEAP следует в файле ''/etc/freeradius/eap.conf'' установить параметр ''сopy_request_to_tunnel = yes'' в секции приведённой ниже: eap { ... peap { ... сopy_request_to_tunnel = yes ... } ... } Точка доступа в запросе шлет параметр ''Calling-Station-Id = ''“MAC-адрес", причем формат представления MAC-адреса может быть различным на разных точках доступа. Чтобы избежать проблем из-за различного представления MAC-адреса, следует их приводить к одному виду. Для этого в фйле ''/etc/freeradius/policy.conf'' имеется уже готовая процедура - r''ewrite.calling_station_id''. Чтобы ей воспользоваться её название нужно вставить в начало секции ''authorize {}'' после объявления ''preprocess'' (если он есть) в файлах ''/etc/freeradius/site-available/default'' и ''/etc/freeradius/site-available/inner-tunnel'' следующим образом: authorize { preprocess rewrite.calling_station_id ... } Процедура нормализует формат MAC-адреса в атрибуте ''Callin-Station-Id'' из запроса, пришедшего на сервер, к формату ''xx-xx-xx-xx-xx-xx'' - нижний регистр и все через "минус". Поэтому в файле ''/etc/freeradius/user'' следует придерживаться данного формата. В принципе уже можно делать список доступа для фильтрации по MAC. \\ **Вариант1.**\\ Достаточно в файл ''users'' в самое его начало добавлять нужных пользователей с параметром ''Calling-Station-Id'', если учетные данные нужны одинаковые, то можно их просто повторить, например: user Cleartext-Password := "pass", Calling-Station-Id == "1a-2b-3c-4d-5e-6f" user Cleartext-Password := "pass", Calling-Station-Id == "aa-bb-cc-dd-ee-ff" user Cleartext-Password := "pass", Calling-Station-Id == "11-22-33-44-55-66" Тем самым на одну пару логин/пароль вешаем три различных MAC-адреса.\\ **Вариант2.**\\ Можно пойти другим путём и создать для списка разрешенных MAC-адресов отдельный файл. Для этого создаем в каталоге ''/etc/freeradius/'' файл ''authorized_macs'' и объявляем его в модуле ''files''. Для этого вставляем в конец файла ''/etc/freeradius/modules/files'' следующий кусок конфига: #MAC Auth files authorized_macs { key = "%{Calling-Station-ID}" usersfile = ${confdir}/authorized_macs compat = no } Чтобы проверка MAC-адресов из файла ''/etc/freeradius/authorized_macs'' выполнялась, нужно в файл ''/etc/freeradius/sites-available/default'' в секцию ''authorize {}'' после объявления ''rewrite.calling_station_id'' вставить прокомментированные строки: authorize { preprocess rewrite.calling_station_id # # Здесь инициируем поиск по файлу authorized_macs authorized_macs # # А здесь отвергаем запрос, если поиск завершился неудачей if (!ok) { reject } } Теперь файл ''authorized_macs'' заполняем разрешенными для авторизации MAC-адресами. Каждый MAC на новой строке. Следует учитывать, что формат строго следующий: ''xx-xx-xx-xx-xx-xx'' , где x-либо цифра, либо буквы от a до f в нижнем регистре. Например: 1a-2b-3c-4d-5e-6f aa-bb-cc-dd-ee-ff 11-22-33-44-55-66 Следует отметить, что атрибут ''Calling-Station-Id'' указанный в файле users для определённой пары логин/пароль также будет действовать, но его проверка будет осуществляться на этапе, который проходит позднее. Так что если поступит запрос со значением ''Calling-Station-Id'', не указанном в файле authorized_macs, то этот запрос сразу отклонится, вне зависимости, что указано в файле users. **Итог:** выше описаны необходимые измения в конфигурации по-умолчанию, чтобы получить требуемый функционал от freeradius. Еще нужно настроить точки доступа, куда нужно вписать IP адрес RADIUS-сервера и секретную фразу из секций ''client {}''. Также в конфигурации описано много лишних методов аутентификации и модулей дополнительной обработки, которые можно удалить/закомментировать без ущерба функционалу. При выбранном типе аутентификации у FreeRADIUS нет возможности выдавать клиентам IP адреса и прочие сетевые настройки, это должен делать отдельный DHCP-сервер. ====== Советы и замечания ====== :!: При изменении файлов конфигурации, в том числе файлов ''users'' и ''authorized_macs'' требуется принудительное перечитывание конфига сигналом ''SIGHUP'': # kill -HUP `cat /var/run/freeradius/freeradius.pid` При изменениях в конфиге ''radiusd.conf'' лучше демон перезагрузить: service freeradius restart \\ Чтобы проверить конфигурацию следует запускать демон в режиме отладки: # freeradius –X При таком запуске можно увидеть как freeradius распарсил конфиг и увидеть как он обрабатывает запросы. Очень помогает при отыскании различных проблем или при объяснении неожиданного поведения.\\ \\ В комплекте идет полезная утилитка ''radtest'' – простой RADIUS-клиент. С ней можно проводить некоторые простые тесты для проверки конфигурации. Возможный пример использования (тестирование внутритуннельной аутентификации по порту 18120): # radtest -t mschap -x user pass localhost:18120 4321 testing123 Sending Access-Request of id 230 to 127.0.0.1 port 18120 User-Name = "user" NAS-IP-Address = 192.168.0.80 NAS-Port = 4321 Message-Authenticator = 0x00000000000000000000000000000000 MS-CHAP-Challenge = 0xaf147766f1965e97 MS-CHAP-Response = 0x00010000000000000000000000000000000000000000000000000fc1329e665dda81c87b76830a2344ae2f5388db6473a2f3 rad_recv: Access-Accept packet from host 127.0.0.1 port 18120, id=230, length=84 MS-CHAP-MPPE-Keys = 0x37653a880f5e2682eacb842922c8d34c1239e1a550a16fee0000000000000000 MS-MPPE-Encryption-Policy = 0x00000001 MS-MPPE-Encryption-Types = 0x00000006 \\ Чтобы в логах отображалась информация о попытках аутентификации следует включить следующие параметры в ''radiusd.conf'': auth = yes auth_badpass = yes auth_goodpass = yes {{tag>Linux Wi-Fi old}}