Резервный сервер RADIUS MySQL

В настоящее время я создаю тестовую установку для приложения RADIUS, использующего FreeRADIUS V.3.xx в сочетании с MySQL. Вся установка должна быть избыточной. Все серверы работают на виртуальных машинах под управлением openSUSE 13.1.

Моя проблема в том, что я не могу найти правильную конфигурацию для резервных серверов MySQL. У кого-нибудь есть опыт в этом?

Что я делал до сих пор, так это следил за соответствующей частью официальной вики freeradius... пытался придумать варианты, используя группу, детализацию, прямое манипулирование сокетом rlm_sql_mysql... все, что я мог придумать... но безуспешно. В настоящее время он вернулся к «статусу вики».

То есть:

Я удалил ссылку на sql из .../mods-enabled/, поскольку это приводило к сбою резервных серверов даже при создании экземпляра...

Файл: .../radius.conf

Раздел: модули {...} Добавлены записи:

sql sql1{ ...#config...}
sql sql2{ ...#config...}

Раздел: instanceate {...} Добавлена ​​запись:

redundant redundant_sql {
      sql1
      sql2
      handled
    }

А затем добавил redundant_sql в файл: .../sites-available/default (связан с сайтами с поддержкой)

Разделы: авторизация {...} и пост-аутентификация{...} (учет мне не нужен)

Вот некоторые из выводов отладки:

Создание экземпляра (и sql1, и sql2 должны быть доступны для запуска сервера RADIUS... что дерьмово, но не является текущей проблемой):

    radiusd: #### Instantiating modules ####
 instantiate {
 }
 modules {
  # Loaded module rlm_sql
  # Instantiating module "sql1" from file /etc/raddb/radiusd.conf
  sql sql1 {
    driver = "rlm_sql_mysql"
    server = "**IP sql1**"
    port = "3306"
    login = "radius"
    password = <<< secret >>>
    radius_db = "radius"
    read_groups = yes
    read_clients = no
    delete_stale_sessions = yes
    sql_user_name = "%{User-Name}"
    default_user_profile = ""
    client_query = "SELECT id, nasname, shortname, type, secret, server FROM nas"
    authorize_check_query = "SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id"
    authorize_reply_query = "SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id"
    authorize_group_check_query = "SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = '%{Sql-Group}' ORDER BY id"
    authorize_group_reply_query = "SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = '%{Sql-Group}' ORDER BY id"
    group_membership_query = "SELECT groupname FROM radusergroup WHERE username = BINARY '%{SQL-User-Name}' ORDER BY priority"
    simul_count_query = ""
    simul_verify_query = "SELECT radacctid, acctsessionid, username, nasipaddress, nasportid, framedipaddress, callingstationid, framedprotocol FROM radacct WHERE username = '%{SQL-User-Name}' AND acctstoptime IS NULL"
    safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"
  }
rlm_sql (sql1): Creating new attribute sql1-SQL-Group
rlm_sql (sql1): Registering sql_groupcmp for sql1-SQL-Group
   accounting {
    reference = "%{tolower:type.%{Acct-Status-Type}.query}"
   }
   post-auth {
    reference = ".query"
   }
   mysql {
    tls {
    }
   }
rlm_sql (sql1): Driver rlm_sql_mysql (module rlm_sql_mysql) loaded and linked
rlm_sql (sql1): Attempting to connect to database "radius"
rlm_sql (sql1): Initialising connection pool
   pool {
    start = 5
    min = 4
    max = 32
    spare = 3
    uses = 0
    lifetime = 0
    cleanup_interval = 30
    idle_timeout = 60
    retry_delay = 1
    spread = no
   }
rlm_sql (sql1): Opening additional connection (0)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql1): Opening additional connection (1)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql1): Opening additional connection (2)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql1): Opening additional connection (3)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql1): Opening additional connection (4)
rlm_sql_mysql: Starting connect to MySQL server
  # Instantiating module "sql2" from file /etc/raddb/radiusd.conf
  sql sql2 {
    driver = "rlm_sql_mysql"
    server = "**IP sql2**"
    port = "3306"
    login = "radius"
    password = <<< secret >>>
    radius_db = "radius"
    read_groups = yes
    read_clients = no
    delete_stale_sessions = yes
    sql_user_name = "%{User-Name}"
    default_user_profile = ""
    client_query = "SELECT id, nasname, shortname, type, secret, server FROM nas"
    authorize_check_query = "SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id"
    authorize_reply_query = "SELECT id, username, attribute, value, op FROM radreply WHERE username = '%{SQL-User-Name}' ORDER BY id"
    authorize_group_check_query = "SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = '%{Sql-Group}' ORDER BY id"
    authorize_group_reply_query = "SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = '%{Sql-Group}' ORDER BY id"
    group_membership_query = "SELECT groupname FROM radusergroup WHERE username = BINARY '%{SQL-User-Name}' ORDER BY priority"
    simul_count_query = ""
    simul_verify_query = "SELECT radacctid, acctsessionid, username, nasipaddress, nasportid, framedipaddress, callingstationid, framedprotocol FROM radacct WHERE username = '%{SQL-User-Name}' AND acctstoptime IS NULL"
    safe_characters = "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"
  }
rlm_sql (sql2): Creating new attribute sql2-SQL-Group
rlm_sql (sql2): Registering sql_groupcmp for sql2-SQL-Group
   accounting {
    reference = "%{tolower:type.%{Acct-Status-Type}.query}"
   }
   post-auth {
    reference = ".query"
   }
   mysql {
    tls {
    }
   }
rlm_sql (sql2): Driver rlm_sql_mysql (module rlm_sql_mysql) loaded and linked
rlm_sql (sql2): Attempting to connect to database "radius"
rlm_sql (sql2): Initialising connection pool
   pool {
    start = 5
    min = 4
    max = 32
    spare = 3
    uses = 0
    lifetime = 0
    cleanup_interval = 30
    idle_timeout = 60
    retry_delay = 1
    spread = no
   }
rlm_sql (sql2): Opening additional connection (0)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql2): Opening additional connection (1)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql2): Opening additional connection (2)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql2): Opening additional connection (3)
rlm_sql_mysql: Starting connect to MySQL server
rlm_sql (sql2): Opening additional connection (4)
rlm_sql_mysql: Starting connect to MySQL server

После остановки sql1 и отправки запроса происходит следующее:

...#irrelevant stuff
Received Access-Request Id 36 from **IP switch**:8345 to **IP RADIUS**:1812 length 128
        User-Name = '**mac-address**'
        User-Password = '**mac-address**'
        NAS-IP-Address = **IP switch**
        NAS-Port = 3
        NAS-Port-Id = 'Port 3'
        NAS-Port-Type = Ethernet
        NAS-Identifier = '**nas name**'
        Service-Type = Call-Check
        Framed-MTU = 1500
        Called-Station-Id = '**mac-address**'
        Calling-Station-Id = '**mac-address**'
    (1) # Executing section authorize from file /etc/raddb/sites-enabled/default
    (1)   authorize {
    (1)   [preprocess] = ok
    (1)     update request {
    (1) EXPAND %{tolower:%{1}%{2}%{3}%{4}%{5}%{6}}
    (1)    --> **mac-address**
    (1)     Calling-Station-Id := '"**mac-address**"'
    (1)     User-Name := '&Calling-Station-Id -> '**mac-address**''
    (1)     User-Password := '&Calling-Station-Id -> '**mac-address**''
    (1)     } # update request = noop
    (1)     [updated] = updated
    (1)    } # if (Calling-Station-Id =~ **Syntax check**  = updated
    (1)     ... skipping else for request 1: Preceding "if" was taken
    (1)   } # rewrite_calling_station_id rewrite_calling_station_id = updated
    (1) detail : EXPAND /var/log/radius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d
    (1) detail :    --> /var/log/radius/radacct/**IP switch**/detail-20151019
    (1) detail : /var/log/radius/radacct/%{%{Packet-Src-IP-Address}:-%{Packet-Src-IPv6-Address}}/detail-%Y%m%d expands to /var/log/radius/radacct/**IP switch**/detail-20151019
    (1) detail : EXPAND %t
    (1) detail :    --> Mon Oct 19 15:03:18 2015
    (1)   [detail] = ok
    (1)   redundant redundant_sql {
    (1) sql1 : EXPAND %{User-Name}
    (1) sql1 :    --> **mac-address**
    (1) sql1 : SQL-User-Name set to '**mac-address**'
    rlm_sql (sql1): Reserved connection (4)
    (1) sql1 : EXPAND SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id
    (1) sql1 :    --> SELECT id, username, attribute, value, op FROM radcheck WHERE username = '**mac-address**' ORDER BY id
    rlm_sql (sql1): Executing query: 'SELECT id, username, attribute, value, op FROM radcheck WHERE username = '**mac-address**' ORDER BY id'
    rlm_sql_mysql: MYSQL check_error: 2006, returning RLM_SQL_RECONNECT
    rlm_sql (sql1): Reconnecting (4)
    rlm_sql_mysql: Starting connect to MySQL server
    rlm_sql_mysql: Couldn't connect socket to MySQL server radius@**IP sql1**:radius
    rlm_sql_mysql: Mysql error 'Can't connect to MySQL server on '**IP sql1**' (111 "Connection refused")'
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql (sql1): Reserved connection (3)
    rlm_sql (sql1): Executing query: 'SELECT id, username, attribute, value, op FROM radcheck WHERE username = '**mac-address**' ORDER BY id'
    rlm_sql_mysql: MYSQL check_error: 2006, returning RLM_SQL_RECONNECT
    rlm_sql (sql1): Reconnecting (3)
    rlm_sql_mysql: Starting connect to MySQL server
    rlm_sql_mysql: Couldn't connect socket to MySQL server radius@**IP sql1**:radius
    rlm_sql_mysql: Mysql error 'Can't connect to MySQL server on '**IP sql1**' (111 "Connection refused")'
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql (sql1): Reserved connection (2)
    rlm_sql (sql1): Executing query: 'SELECT id, username, attribute, value, op FROM radcheck WHERE username = '**mac-address**' ORDER BY id'
    rlm_sql_mysql: MYSQL check_error: 2006, returning RLM_SQL_RECONNECT
    rlm_sql (sql1): Reconnecting (2)
    rlm_sql_mysql: Starting connect to MySQL server
    rlm_sql_mysql: Couldn't connect socket to MySQL server radius@**IP sql1**:radius
    rlm_sql_mysql: Mysql error 'Can't connect to MySQL server on '**IP sql1**' (111 "Connection refused")'
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql (sql1): Reserved connection (1)
    rlm_sql (sql1): Executing query: 'SELECT id, username, attribute, value, op FROM radcheck WHERE username = '**mac-address**' ORDER BY id'
    rlm_sql_mysql: MYSQL check_error: 2006, returning RLM_SQL_RECONNECT
    rlm_sql (sql1): Reconnecting (1)
    rlm_sql_mysql: Starting connect to MySQL server
    rlm_sql_mysql: Couldn't connect socket to MySQL server radius@**IP sql1**:radius
    rlm_sql_mysql: Mysql error 'Can't connect to MySQL server on '**IP sql1**' (111 "Connection refused")'
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql_mysql: Socket destructor called, closing socket
    rlm_sql (sql1): Failed to reconnect (1), no free connections are available
    rlm_sql (sql1): Executing query: 'SELECT id, username, attribute, value, op FROM radcheck WHERE username = '**mac-address**' ORDER BY id'
    Segmentation fault

После разрушения последнего соединения с sql1 я ожидаю, что «избыточный» сработает и свяжется с sql2 ... но вместо этого RADIUS прерывается.

Я знаю, что я только ** IP и Mac, но все остальное будет правильно сброшено в любом случае, если этот проект закончит «стадию тестовой настройки».

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

Большое спасибо, если вы хотя бы дочитали до сюда!


person Felix Joel    schedule 19.10.2015    source источник
comment
Это вывод gdb. Сервер RADIUS был запущен с обоими работающими серверами sql. После завершения инициализации (готовность к обработке) sql1 был остановлен --> Сбой на (0). Текущая настройка избыточности по-прежнему такая, как описано выше (эксперименты с lb на самом деле не сработали для меня). @Arran Cudbard-Bell: Я надеюсь, что это обратная трасса, которую вы имели в виду.. ‹pre› ‹code›   -  person Felix Joel    schedule 28.10.2015
comment
# 0 0x00007ffff4ab4b46 в ?? () из /usr/lib64/freeradius/rlm_sql_mysql.so #1 0x00007ffff4ab4bff в ?? () из /usr/lib64/freeradius/rlm_sql_mysql.so #2 0x00007ffff4cbc71e в rlm_sql_select_query () из /usr/lib64/freeradius/rlm_sql.so #3 0x00007ffff4cbc8e2 в sql_getvpdata () из /usr/lib64/freeradius/rlm_sql.so 4 0x00007ffff4cbbb65 в ?? () из /usr/lib64/freeradius/rlm_sql.so #5 0x0000555555577eea в ?? () #6 0x00005555555577880 в ?? () #7 0x0000555555577a79 в ?? () #8 0x00005555555577880 в ?? () #9 0x0000555555577a79 в ?? () #10 0x0000555555578bcd в modcall ()   -  person Felix Joel    schedule 28.10.2015
comment
#11 0x000055555557629f в indexed_modcall() #12 0x0000555555567c9a в rad_authenticate() #13 0x00005555555584e67 в ?? () #14 0x00005555555819d6 в ?? () #15 0x00005555555836ec в request_receive () #16 0x0000555555571e0c в ?? () #17 0x0000555555581ed1 в ?? () #18 0x00007ffff79a5b8d в fr_event_loop () from /usr/lib64/freeradius/libfreeradius-radius.so #19 0x0000555555566e86 в main ()   -  person Felix Joel    schedule 28.10.2015


Ответы (2)


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

Для gdb вы должны быть в состоянии сделать:

gdb --args <path to radiusd> -X

run
bt

Обратная трассировка покажет, где проблема. У меня была быстрая попытка воспроизвести его в ветке v3.1.x, и я не смог, но это может быть потому, что ошибка требует, чтобы соединения были открыты заранее, чтобы вызвать дефект.

person Arran Cudbard-Bell    schedule 20.10.2015
comment
Спасибо, я попробую это. Я экспериментировал с комбинацией избыточности с балансировкой нагрузки в древовидной структуре, которая, кажется, работает в нескольких случаях. Если ничего не поможет, мне придется написать маленького демона, работающего на серверах Rad, который берет на себя избыточность... Однако было бы стыдно использовать обходной путь. - person Felix Joel; 22.10.2015
comment
Если вы отправите обратную трассировку, мы, вероятно, сможем это исправить :) - person Arran Cudbard-Bell; 25.10.2015
comment
Спасибо, меня некоторое время не было в офисе... Сейчас пытаюсь :D gdb продолжает возвращать ошибку Python... и, поскольку я не знаком с gdb, он работает медленно. Хотя я на нем. - person Felix Joel; 28.10.2015

Прежде всего, спасибо за помощь Аррану Кадбарду-Беллу!

Для всех, кто столкнулся с той же проблемой; используя новейший tar-архив (Версия 3.0.10: tar.bz2 (подпись PGP)) и создавая на его основе исправления, которые решают проблему избыточности.

Также обратите внимание, что запись в вики не полная. Если необходимо использовать более одного экземпляра sql, необходимо дополнительно выполнить следующее:

  • Если вы ранее использовали один экземпляр sql, удалите программную ссылку sql из raddb/mods-enabled/
  • При настройке модулей sql1 и sql2 напишите: group_attribute = "${.:instance}-SQL-Group" перед $INCLUDE ${modconfdir}/${.:name}/main/ ${dialect}/queries.conf", так как стандартная конфигурация выдаст ошибки, если вы этого не сделаете.

Хотя это задокументировано в самих конфигурационных файлах, в вики об этом не упоминается.

--Спасибо @ всем и закрыто--

person Felix Joel    schedule 06.11.2015