Базовая конфигурация FreeRADIUS для eduroam

В качестве примера приведена конфигурация при аутентификации при помощи LDAP, обработки собственных realm и локальной Wi-Fi-точки

/etc/freeradius/clients.conf
# Верхнеуровневый RADIUS-сервер
client FLR-1 {
    ipaddr            = 85.142.29.235
    secret            = secretPasswordFromUpstream
    shortname         = FLR-1
    nas_type          = other
    virtual_server    = eduroam
}

# Локальный RADIUS-сервер
client localhost {
    ipaddr            = 127.0.0.1
    proto             = *
    secret            = secretPasswordForLocalhost
}

# Wi-Fi точка на территории организации
client camp-roof-1 {
    ipaddr            = 192.168.192.168
    netmask           = 32
    secret            = secretPasswordForWiFi
    shortname         = roof-1
    virtual_server    = eduroam
}

/etc/freeradius/proxy.conf
proxy server {
    default_fallback = no
    retry_delay = 2
}

home_server localhost {
    ipaddr                  = 127.0.0.1
    port                    = 1812
    secret                  = secretPasswordForLocalhost
    status_check            = status-server
}

home_server FLR-1 {
    ipaddr                  = 85.142.29.235
    port                    = 1812
    secret                  = secretPasswordFromUpstream
    status_check            = status-server
}

home_server_pool EDUROAM {
    type                    = fail-over
    home_server             = FLR-1
}

# Realm-ы, которые обслуживает локальный RADIUS-сервер
realm institution.ru {
    nostrip
}

realm dep1.institution.ru {
    nostrip
}

realm dep2.institution.ru { 
    nostrip 
} 
# Запросы на аутентификацию с realm, не обслуживаемым локальным RADIUS-сервером, отправляются верхнеуровневому RADIUS-серверу
realm "~.+$" {
    pool                    = EDUROAM
    nostrip
}

/etc/freeradius/sites-enabled/default
server eduroam {
    listen {
        type = "auth"
        ipaddr = *
        port = 0
    }
    listen {
        type = "acct"
        ipaddr = *
        port = 0
    }
    authorize {
        filter_username
        auth_log
        suffix
        preprocess
        if ("%{client:shortname}" != "FLR-1") {
            update request {
               Operator-Name := "institution1.ru"
            }
        }
        eap
        ldap # механизм сверки учетных записей (sql, unix passwd, files и др.)
        pap  # нормализация хэшированных паролей
    }
    authenticate {
        eap
    }
    preacct {
        suffix
    }
    accounting {
        radutmp
    }
    post-auth {
        reply_log
        myLog
        Post-Auth-Type REJECT {
            reply_log
            myLog
        }
    }
    pre-proxy {
        pre_proxy_log
        if("%{Packet-Type}" != "Accounting-Request") {
            attr_filter.pre-proxy
        }
    }
    post-proxy {
        post_proxy_log
        attr_filter.post-proxy
        }
}

/etc/freeradius/inner-tunnel
server inner-tunnel {
    authorize {
        auth_log
        preprocess
        eap {
            ok = return
        }
        ldap
        mschap
        pap
    }
    authenticate {
        Auth-Type PAP {
            pap
        }
        Auth-Type MS-CHAP {
            mschap
        }
        eap
    }
    post-auth {
        reply_log
        Post-Auth-Type REJECT {
            reply_log
        }
    }
}

/etc/freeradius/mods-enabled/eap
eap {
    default_eap_type = peap
    timer_expire     = 60
    ignore_unknown_eap_types = no
    cisco_accounting_username_bug = no
    max_sessions = ${max_requests}
    gtc{
        auth_type = "PAP"
    }
    tls {
        cipher_server_preference = no
        ecdh_curve = "prime256v1"
        certdir = ${confdir}/certs
        cadir = ${confdir}/certs
        private_key_file = /etc/certs/priv.key
        certificate_file = /etc/certs/cert.pem
        dh_file = ${certdir}/dh
        random_file = /dev/urandom
        fragment_size = 1024
        include_length = yes
        check_crl = no
        cipher_list = "DEFAULT"
    }
    ttls {
        default_eap_type = gtc
        copy_request_to_tunnel = yes
        use_tunneled_reply = yes
        virtual_server = "inner-tunnel"
    }
    peap {
        default_eap_type = gtc 
        copy_request_to_tunnel = yes
        use_tunneled_reply = yes
        virtual_server = "inner-tunnel"
    }
    mschapv2 {
        default_eap_type = mschapv2
        copy_request_to_tunnel = yes
        use_tunneled_reply = yes
        virtual_server = "inner-tunnel"
    }
}

/etc/freeradius/mods-enabled/f_ticks
linelog f_ticks {
       filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/f-ticks-%Y%m%d.log
       format = ""
       reference = "f_ticks.%{%{reply:Packet-Type}:-format}"
       f_ticks {
              Access-Accept = "F-TICKS/eduroam/1.0#REALM=%{Realm}#VISCOUNTRY=RU#VISINST=%{Operator-Name}#CSI=%{Calling-Station-Id}#RESULT=OK#"
              Access-Reject = "F-TICKS/eduroam/1.0#REALM=%{Realm}#VISCOUNTRY=RU#VISINST=%{Operator-Name}#CSI=%{Calling-Station-Id}#RESULT=FAIL#"
       }
}

linelog myLog {
    filename = ${radacctdir}/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/myLog-%Y%m%d.log
    format = ""
    reference = "f_ticks.%{%{reply:Packet-Type}:-format}"
    f_ticks {
        Access-Accept = "REALM=%{Realm} CallingSI=%{Calling-Station-Id} CalledID=%{%{Called-Station-Id}:-Unknown Access Point} NASIP=%{NAS-IP-Address} USER=%{User-Name}  RESULT=OK"
        Access-Reject = "REALM=%{Realm} CallingSI=%{Calling-Station-Id} CalledID=%{%{Called-Station-Id}:-Unknown Access Point} NASIP=%{NAS-IP-Address} USER=%{User-Name}  RESULT=FAIL"
    }
}

/etc/freeradius/mods-enabled/ldap
ldap {
    server = "127.0.0.1"
    identity = "cn=SuperAdmin,dc=example,dc=com"
    password = "SuperPassword"
    base_dn = "o=company,dc=example,dc=com"

    tls{
        start_tls = yes
        tls_mode = yes
        tls_require_cert        = "allow"
        ldap_connections_number = 15
    }

    update {
        # Явное указание на хранение пароля в виде хеша в атрибуте userPassword
        control:Password-With-Header    += 'userPassword'
    }
    user {
        base_dn = "o=company,dc=example,dc=com"
        filter = "(login=%{User-Name})"
    }
    group {
        base_dn = "${..base_dn}"
        filter = "(objectClass=ruEduOrg)"
    }
    profile {
    }
    client {
        base_dn = "${..base_dn}"
        filter = '(objectClass=ruEduOrgPerson)'
    }
    accounting {
        reference = "%{tolower:type.%{Acct-Status-Type}}"
        type {
            start {
                update {
                    description := "Online at %S"
                }
            }
            interim-update {
                update {
                    description := "Last seen at %S"
                }
            }
            stop {
                update {
                    description := "Offline at %S"
                }
            }
        }
    }
    post-auth {
        update {
            description := "Authenticated at %S"
        }
    }
    options {
        chase_referrals = yes
        rebind = yes
        timeout = 10
        timelimit = 3
        net_timeout = 1
        idle = 60
        probes = 3
        interval = 3
        ldap_debug = 0x0028
    }
    pool {
        start = 16
        min = 4
        max = ${thread[pool].max_servers}
        spare = 9
        uses = 0
        lifetime = 0
        idle_timeout = 10
    }
}

Краткий FAQ на основании вопросов технических специалистов

1. При старте RADIUS-сервер выдает следующее предупреждение:

      TLS certificate verification: Error, self signed certificate

RADIUS-сервер предупреждает о самоподписанном сертификате, что можно проигнорировать.

2. Непонятно, каким образом происходит синхронизация баз LDAP с серверами других организаций?

Никакая синхронизация баз не выполняется: у каждой организации функционирует свой RADIUS-сервер и свое хранилище учетных данных. Сотруднику ИТ-службой организации выдается учетная запись вида user@institution.tld (обычно tld – домен верхнего уровня) и пароль. На территории кампуса разворачивается Wi-Fi сеть с SSID eduroam.

Гости, приезжающие из других организаций-участниц проекта (или сотрудники, направляющиеся в другие организации), могут инициировать подключение к SSID eduroam, при этом локальный RADIUS-сервер у себя их realm (institution.tld) не обнаружит и направит запрос на аутентификацию верхнеуровневому RADIUS-серверу, откуда он уже будет переправлен RADIUS-серверу организации гостя.

Схема и описание работы иерархии RADIUS-серверов »

3. Каким образом настраивается Wi-Fi точка?

Единая инструкция по настройке Wi-Fi точек отсутствует, но имеется документация по разным точкам от GEANT. В целом, для настройки можно посоветовать в директории RADIUS-сервера в файле clients.conf прописать следующее:

      client WiFi-AP-1 {
        ipaddr = 192.168.192.168 # адрес Wi-Fi точки
        netmask = 32 # необязательно
        secret = SuperSecretPassword
        shortname = roof-1 # короткое имя, для лог-файла
        virtual_server = eduroam # описанный в конфигурации виртуальный сервер
      }

На Wi-Fi точке выполнить следующие действия:

- прописать Wi-Fi SSID eduroam (маленькими буквами!!!)
- перейти в раздел AAA | Security | Radius | Authentication | 802.1X (у каждого вендора свое наименование)
- создать новое подключение к RADIUS-серверу с выбором authentication 802.1X
- указать IP-адрес RADIUS-сервера и порт (1812 - для сервера аутентификации и 1813 - для сервера аккаунтинга)
- указать SuperSecretPassword для RADIUS-сервера (из конфигурационного файла)

Иными словами:

- настроить Wi-Fi точку в качестве клиента на RADIUS-сервере, указать пароль для возможности их взаимодействия друг с другом
- настроить на Wi-Fi точке SSID eduroam и указать для него следующие основные настройки:
      Encryption: WPA2-AES (Enterprise)
      Authentication: 802.1x (RADIUS protocol)
      RADIUS Authentication server: IP-адрес локального сервера аутентификации
      RADIUS Authentication port: 1812
      RADIUS Accounting server: IP-адрес локального сервера аккаунтинга
      RADIUS Accounting port: 1813
      RADIUS Shared secret: ключ из конфигурационного файла клиента

Важным условием является выполнение в сети синхронизации времени (например, с использованием NTP-серверов ВНИИФТРИ: ntp1.vniiftri.ru, ntp2.vniiftri.ru).

4. При попытке использования утилиты для проверки доступности/работы/снятия счетчиков RADIUS-сервера подключения не происходит, информация не выводится и т.д.

Вероятно, выбранная утилита пытается выполнить radclient-запрос, а сервер настроен на использование EAP (можно попробовать задействовать утилиту  eapool-test из пакета wpa_supplicant).

Для реализации radclient в ОС Linux можно сделать следующее. Создать файл my-status в директории /usr/local/raddb/sites-enabled (или в ином месте его размещения):

      server status {
        listen {
          type = status
          ipaddr = 127.0.0.1
          port = 18121
        }
        client admin {
          ipaddr = 127.0.0.1
          secret = SuperPassword
        }
        authorize {
          ok
            Auth-Type Status-Server {
            ok
          }
        }
      }

Убедиться, что в файле radiusd.conf присутствует строка:

status_server = yes

Для проверки можно использовать команду:

echo "Message-Authenticator = 0x00, FreeRADIUS-Statistics-Type = 1, Response-Packet-Type = Access-Accept" | radclient -x localhost:18121 status SuperPassword

Если проверка выполняется удаленно, нужно поменять значение ipaddr или добавить в конфигурационный файл еще одного “клиента”:

      client localhost {
        ipaddr = 127.0.0.1
        proto = *
        secret = SuperPassword
      }
      client adminCheck {
        ipaddr = 1.2.3.0/25
        proto = *
        secret = SuperPasswordForNetwork
      }
      client checkFromAnywhere {
        ipaddr = 0.0.0.0/0 
        proto = *
        secret = SuperPasswordForAnybody
      }

После изменения конфигурации выполнить команды:

      /usr/local/etc/rc.d/radius stop
      radiusd -X

Если ошибок нет, запустить RADIUS-сервер командой:

      /usr/local/etc/rc.d/radius start

5. Пароли пользователей хранятся в зашифрованном виде. Нужно ли модифицировать их для RADIUS-сервера или все необходимое сделает модуль PAP?

Все необходимые действия должен выполнить модуль PAP, но в некоторых случаях (для нешифрованных и очень длинных паролей) могут возникнуть проблемы, например:

- пользователь с паролем 123 пытается подключится к eduroam
- пароль учетной записи пользователя хранится в виде хэша md5
- устройство пользователя направляет серверу аутентификации пароль 123
- сервер аутентификации обращается к хранилищу учетных записей и сверяет принятый пароль от пользователя с паролем в хранилище
- модуль PAP сервера аутентификации забирает пароль из хранилища
- в хранилище пароль записан (например) в таком виде:
     {md5}djksabhdjkbfsfds
       или (для ssha)
     {ssha}jdklsabjfkbldsfl
- модуль PAP видит, что строка начинается с обозначение хэширования {md5}, берет присланный пользовательским устройством пароль, получает с него хэш в нужном виде (md5 | ssha | bf и др.) и сверяет уже хэши

Разработчики RADIUS-сервера рекомендуют везде хранить пароли в открытом виде, но, как представляется, проще и лучше хранить хэши.