FreeRadius Notes
Это просто сборник ссылок и заметок
- https://shop.nag.ru/article/ericsson-smartedge-freeradius-billing
- https://code.google.com/archive/p/cakebilling/wikis/ConfiguringFreeRadius.wiki
Минимальный рабочий конфиг
Тут чертовски важен порядок модулей - если переставить местами pap/files то получится что pap не сможет получить пароль
sites-enabled/default
server default { listen { type = auth ipv4addr = * port = 1812 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipv4addr = * port = 1813 type = acct } instantiate { exec expr expiration } authorize { files pap } authenticate { Auth-Type PAP { pap } } } # end of SERVER
Клиенты clients.conf
client localhost { ipaddr = 127.0.0.1 proto = * secret = secret require_message_authenticator = no limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } }
Модуль PAP mods-enabled/pap
pap { # normalise = yes auto_header = no }
Модуль files
mods-enabled/files
files { moddir = ${modconfdir}/${.:instance} #key = "%{%{Stripped-User-Name}:-%{User-Name}}" filename = ${moddir}/authorize usersfile = ${moddir}/authorize # acctusersfile = ${moddir}/accounting }
mods-config/files/authorize
bob Cleartext-Password := "hello" Reply-Message := "Hello, %{User-Name}"
Проверка работы минимальной конфигурации
- Для проверки использую команду
radtest bob hello localhost 0 secret
bob
- имя пользователя, атрибутUser-Name
hello
- пароль, который будет передан в атрибутеUser-Password
localhost
- адрес куда отправить запрос0
- номер (виртуального) порта,NAS-Port
secret
- radius shared secret, который указан в настройках сервера и клиента
По сути тут логика такая
- "Пришел" пользователь
User-Name = "bob"
User-Password = "hello"
- Его проверили по файлу (модуль
files
ищет пользователя в файле, имя файла определено конфигурацией модуля) и находит, о чем говорит записьfiles: users: Matched entry bob at line 4
- Далее для модулей вызываных ниже по конфигу будут доступны атрибуты которые добавил модуль
files
а именно:
bob Cleartext-Password := "hello" Reply-Message := "Hello, %{User-Name}"
- При этом модуль
files
по сути не делает проверок - он только сопоставляет запрос, и по ключу который определен в конфигурации (key = "%{%{Stripped-User-Name}:-%{User-Name}}"
) находит (или не находит) атрибуты.
Запись в логах вида:
[files] = ok
Означает что такой пользователь существует, НО не означает что он успешно авторизован.
- Далее модуль PAP осуществляет проверку пароля. Важно то, что пароль в описании пользователя должен содержаться в атрибутах "known good", в нашем случае -
Cleartext-Password
- Собственно на этом все.
Fri Jul 14 18:07:17 2023 : Debug: (0) Received Access-Request Id 51 from 127.0.0.1:54599 to 127.0.0.1:1812 length 73 Fri Jul 14 18:07:17 2023 : Debug: (0) User-Name = "bob" Fri Jul 14 18:07:17 2023 : Debug: (0) User-Password = "hello" Fri Jul 14 18:07:17 2023 : Debug: (0) NAS-IP-Address = 10.90.1.213 Fri Jul 14 18:07:17 2023 : Debug: (0) NAS-Port = 0 Fri Jul 14 18:07:17 2023 : Debug: (0) Message-Authenticator = 0xa051e8612e62faaa98baa723ceb98219 Fri Jul 14 18:07:17 2023 : Debug: (0) session-state: No State attribute Fri Jul 14 18:07:17 2023 : Debug: (0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default Fri Jul 14 18:07:17 2023 : Debug: (0) authorize { Fri Jul 14 18:07:17 2023 : Debug: (0) modsingle[authorize]: calling files (rlm_files) Fri Jul 14 18:07:17 2023 : Debug: (0) files: users: Matched entry bob at line 4 Fri Jul 14 18:07:17 2023 : Debug: (0) files: ::: FROM 1 TO 0 MAX 1 Fri Jul 14 18:07:17 2023 : Debug: (0) files: ::: Examining Reply-Message Fri Jul 14 18:07:17 2023 : Debug: Hello, %{User-Name} Fri Jul 14 18:07:17 2023 : Debug: Parsed xlat tree: Fri Jul 14 18:07:17 2023 : Debug: literal --> Hello, Fri Jul 14 18:07:17 2023 : Debug: attribute --> User-Name Fri Jul 14 18:07:17 2023 : Debug: (0) files: EXPAND Hello, %{User-Name} Fri Jul 14 18:07:17 2023 : Debug: (0) files: --> Hello, bob Fri Jul 14 18:07:17 2023 : Debug: (0) files: ::: APPENDING Reply-Message FROM 0 TO 0 Fri Jul 14 18:07:17 2023 : Debug: (0) files: ::: TO in 0 out 0 Fri Jul 14 18:07:17 2023 : Debug: (0) modsingle[authorize]: returned from files (rlm_files) Fri Jul 14 18:07:17 2023 : Debug: (0) [files] = ok Fri Jul 14 18:07:17 2023 : Debug: (0) modsingle[authorize]: calling pap (rlm_pap) Fri Jul 14 18:07:17 2023 : Debug: (0) modsingle[authorize]: returned from pap (rlm_pap) Fri Jul 14 18:07:17 2023 : Debug: (0) [pap] = updated Fri Jul 14 18:07:17 2023 : Debug: (0) } # authorize = updated Fri Jul 14 18:07:17 2023 : Debug: (0) Found Auth-Type = PAP Fri Jul 14 18:07:17 2023 : Debug: (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default Fri Jul 14 18:07:17 2023 : Debug: (0) Auth-Type PAP { Fri Jul 14 18:07:17 2023 : Debug: (0) modsingle[authenticate]: calling pap (rlm_pap) Fri Jul 14 18:07:17 2023 : Debug: (0) pap: Login attempt with password "hello" (5) Fri Jul 14 18:07:17 2023 : Debug: (0) pap: Comparing with "known good" Cleartext-Password "hello" (5) Fri Jul 14 18:07:17 2023 : Debug: (0) pap: User authenticated successfully Fri Jul 14 18:07:17 2023 : Debug: (0) modsingle[authenticate]: returned from pap (rlm_pap) Fri Jul 14 18:07:17 2023 : Debug: (0) [pap] = ok Fri Jul 14 18:07:17 2023 : Debug: (0) } # Auth-Type PAP = ok Fri Jul 14 18:07:17 2023 : ERROR: (0) Cannot proxy packets unless 'proxy_requests = yes' Fri Jul 14 18:07:17 2023 : Debug: (0) Empty post-auth section in virtual server "default". Using default return values. Fri Jul 14 18:07:17 2023 : Auth: (0) Login OK: [bob/hello] (from client localhost port 0) Fri Jul 14 18:07:17 2023 : Debug: (0) Sent Access-Accept Id 51 from 127.0.0.1:1812 to 127.0.0.1:54599 length 32 Fri Jul 14 18:07:17 2023 : Debug: (0) Reply-Message = "Hello, bob" Fri Jul 14 18:07:17 2023 : Debug: (0) Finished request Fri Jul 14 18:07:17 2023 : Debug: Waking up in 4.9 seconds.
Ошибочная конфигурация
Если переставить модули местами и вместо
authorize { files pap }
Написать модули в обратном порядке
authorize { pap files }
То на момент проверки пароля модулем PAP, атрибут Cleartext-Password
еще не будет доступен о чем и будет сказано в логах:
Sat Jul 15 12:49:59 2023 : WARNING: (0) pap: No "known good" password found for the user. Not setting Auth-Type Sat Jul 15 12:49:59 2023 : WARNING: (0) pap: Authentication will fail unless a "known good" password is available ... Sat Jul 15 12:49:59 2023 : WARNING: (0) No module configured to handle comparisons with &control:Cleartext-Password Sat Jul 15 12:49:59 2023 : WARNING: (0) Add pap or chap to the authorize { ... } and authenticate { ... } sections of this virtual server to handle this "known good" password type Sat Jul 15 12:49:59 2023 : ERROR: (0) No Auth-Type found: rejecting the user via Post-Auth-Type = Reject
Не смотря на то что модуль files
говорит что "все хорошо" авторизация не работает.
Sat Jul 15 12:49:59 2023 : Debug: (0) [files] = ok
How the users file works
For the answer below, pairs is referring to Attribute Value Pairs (AVPs), that is, a tuple consisting of an attribute an operator and a value.
Существуют три списка атрибутов (точнее пар атрибут - значение ) There are three lists of attribute(s) (pairs) that are accessible from the users file. Они привязаны к конкретному запросу/ответу к серверу, и не доступны из других запросов/ответов These are bound to the request the server is currently processing, and they don't persist across multiple request/response rounds.
request
- содержит список атрибут-значение которые получены в запросе от NAScontrol
- изначально это пустой список, который определяет как и какие модули будут обрабатывать запрос. Этот список заполняется содулями (например files или python) или с помощьюulang
reply
- содержит список атрибутов которые будут отправлены назад на NAS
The users file module determines the list it's going to use for inserting/searching, by where the pair is listed in the entry, and the operator.
The first line of the entry contains check pairs that must match in order for the entry to be used. The first line also contains control pairs, those you want to be inserted into the control list if all the check pairs match.
Note: It doesn't matter which order the pairs are listed in. control pairs will not be inserted unless all the check pairs evaluate to true.
check and control pairs are distinguished by the operator used.
- If an assignment operator is used i.e. ':=' or '=' then the pair will be treated as a control pair.
- If an equality operator such as '>', '<', '==', '>=', '<=', '=~' is used, the pair will be treated as a check pair.
Описание операторов
Operator | Пример | Использование в check (users и тому подобное), или в условиях unlang |
Использование в reply (users и тому подобное), или в блоках unlang update |
---|---|---|---|
=
|
|
|
|
:= |
lameuser Auth-Type := Reject Reply-Message = "Your account has been disabled." |
Всегда совпадает при проверках, и добавляет в |
Для атрибутов в ответе ( |
== | Операция сравнения для check атрибутов, успешна если совпадает атрибут присутствует и его значение совпадает с указанным.
| ||
+= | Текст ячейки | ||
!= | Текст ячейки | ||
> | Текст ячейки | ||
>= | Текст ячейки | ||
< | Текст ячейки | ||
<= | Текст ячейки | ||
!~ | Текст ячейки | ||
=* | Текст ячейки | ||
!* | Текст ячейки
|
Subsequent lines in the same entry contain only reply pairs. If all check pairs match, reply pairs will be inserted into the reply list.
Cleartext-Password
Cleartext-Password
is strictly a control pair. It should not be present in any of the other lists.
Cleartext-Password
is one of a set of attributes, which should contain the 'reference' (or 'known good') password, that is, the local copy of the users password. An example of another pair in this set is SSHA-Password
- this contains a salted SHA hash of the users password.
The reference password pairs are searched for (in the control list) by modules capable of with authenticating users using the User-Password
pair. In this case that module is 'rlm_pap'.
User-Password
User-Password
is strictly a request pair. It should not be present in any of the other lists.
User-Password
is included in the request from the NAS. It contains the plaintext version of the password the user provided to the NAS.
In order to authenticate a user, a module needs to compare the contents of User-Password with a control pair like Cleartext-Password
.
In a users file entry when setting reference passwords you'll see entries like:
my_username Cleartext-Password := "known_good_password"
That is, if the username matches the value on the left (my_username), then insert the control pair Cleartext-Password with the value "known_good_password".
To answer the first question the reason why:
shad Cleartext-Password == "test"
Does not work, it is because you are telling the files module to search in the request list, for a pair which does not exist in the request list, and should never exist in the request list.
You might now be thinking oh, i'll use User-Password == "test" instead, and it'll work. Unfortunately it won't. If the password matches then the entry will match, but the user will still be rejected, see below for why.
Auth-Type
Auth-Type
is strictly a control pair. It should not be present in any of the other lists.
There are three main sections in the server for dealing with requests 'authorize', 'authenticate', 'post-auth'.
authorize
authorize
is the information gathering section.
This is where database lookups are done to authorise the user, and to retrieve reference passwords.
It's also where Auth-Type is determined, that is, the type of authentication we want to perform for the user.
authenticate
Authenticate
is where a specific module is called to perform authentication. The module is determined by Auth-Type.
Post-Auth
is mainly for logging, and applying further policies, the modules run in Post-Auth are determined by the response returned from the module run in Authenticate.
The modules in authorize examine the request, and if they think they can authenticate the user, and Auth-Type is not set, they set it to themselves. For example the rlm_pap module will set Auth-Type = 'pap' if it finds the User-Password in the request.
If no Auth-Type
is set the request will be rejected.
So to answer your second question, you're forcing pap authentication, which is wrong, you should let rlm_pap set the Auth-Type by listing pap after the files module in the authorize section.
When rlm_pap runs in authenticate, it looks for a member of the set of 'reference' passwords described above, and if it can't find one, it rejects the request, this is what's happening above.
There's also a 'magic' Auth-Type
, Accept
, which skips the authenticate section completely and just accepts the user. If you want the used to do cleartext password comparison without rlm_pap, you can use:
shad Auth-Type := Accept, User-Password == "test"