Архив рубрики: Linux

Наработки и статьи по работе с Linux

FreeRadius и аутентификация через внешний скрипт

Например можно реализовать вот так:

authorize{
    update control { 
        Auth-Type := `/usr/bin/php -f /etc/raddb/yourscript.php '%{User-Name}' '%{User-Password}'`
    }

В этом случае, PHP должен только проверить логин&пароль и ответить либо Accept либо Reject.

Добавляем модуль python для FreeRadius3

Случилось так, что стандартными средствами FreeRadius авторизации ну никак не «разрулить» те условия, которые необходимы. Решение: включим/поставим модуль python для FreeRadius и будем использовать его для авторизации и выдачи абонентам сетевых настроек.

Далее пути указаны для Ubuntu.

1) Сделаем симлинк (читай включим модуль) для модуля pyhton в папке

ln -s /etc/freeradius/3.0/mods-available/python /etc/freeradius/3.0/mods-enabled

2) В файле настроек пропишем путь для файла написанного на языке python, который будет отвечать за авторизацию, и имя собственно модуля, например work:

python_path="/etc/freeradius/3.0/mods-config/python"
module = work

Так-же нужно расскоментировать те функции, которые будут вызываться модулем. Например:

mod_authorize = ${.module}
func_authorize = authorize
mod_authenticate = ${.module}
func_authenticate = authenticate

 

3) Создадим модуль work. Можно на основе example. В моём случае он адаптирован под python3 (в «базе» он поставляется пот python 2.7):

#! /usr/bin/env python3

import radiusd

def instantiate(p):
  print ("*** instantiate ***")
  print (p)
  # return 0 for success or -1 for failure

def authenticate(p):
    print ("*** Autefication!!***")
    print (p)
def authorize(p):
  print ("*** authorize ***")
  radiusd.radlog(radiusd.L_INFO, '*** radlog call in authorize ***')
  print (p)
  print (radiusd.config)
  return radiusd.RLM_MODULE_OK

def preacct(p):
  print ("*** preacct ***")
  print (p)
  return radiusd.RLM_MODULE_OK

def accounting(p):
  print ("*** accounting ***")
  radiusd.radlog(radiusd.L_INFO, '*** radlog call in accounting (0) ***')
  print (p)
  return radiusd.RLM_MODULE_OK

def pre_proxy(p):
  print ("*** pre_proxy ***")
  print (p)
  return radiusd.RLM_MODULE_OK

def post_proxy(p):
  print ("*** post_proxy ***")
  print (p)
  return radiusd.RLM_MODULE_OK

def post_auth(p):
  print ("*** post_auth ***")
  print (p)
  return radiusd.RLM_MODULE_OK

def recv_coa(p):
  print ("*** recv_coa ***")
  print (p)
  return radiusd.RLM_MODULE_OK

def send_coa(p):
  print ("*** send_coa ***")
  print (p)
  return radiusd.RLM_MODULE_OK

def detach():
  print ("*** goodbye from example.py ***")
  return radiusd.RLM_MODULE_OK

И чуть изменим файл radiusd.py:

#! /usr/bin/env python3

# from modules.h

RLM_MODULE_REJECT = 0
RLM_MODULE_FAIL = 1
RLM_MODULE_OK = 2
RLM_MODULE_HANDLED = 3
RLM_MODULE_INVALID = 4
RLM_MODULE_USERLOCK = 5
RLM_MODULE_NOTFOUND = 6
RLM_MODULE_NOOP = 7
RLM_MODULE_UPDATED = 8
RLM_MODULE_NUMCODES = 9

# from log.h
L_AUTH = 2
L_INFO = 3
L_ERR = 4
L_WARN = 5
L_PROXY = 6
L_ACCT = 7

L_DBG = 16
L_DBG_WARN = 17
L_DBG_ERR = 18
L_DBG_WARN_REQ = 19
L_DBG_ERR_REQ = 20

# log function
def radlog(level, msg):
    import sys
    sys.stdout.write(msg + '\n')

    level = level


В файле default включим модули в секциях authorize и authenticate:

authorize {
  python
....
}
authenticate {
  Auth-Type PAP {
    pap
    python
  }
...
}

Запускаем:

radtest steve testing localhost 1812 testing123

В логах наблюдаем:

Ready to process requests
(0) Received Access-Request Id 62 from 127.0.0.1:53324 to 127.0.0.1:1812 length 75
(0)   User-Name = "steve"
(0)   User-Password = "testing"
(0)   NAS-IP-Address = 126.0.0.1
(0)   NAS-Port = 1812
(0)   Message-Authenticator = 0xacf43d1ab9f8719bc9e92f0f7ebd4395
(0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default
(0)   authorize {
*** authorize ***
*** radlog call in authorize ***
(('User-Name', 'steve'), ('User-Password', 'testing'), ('NAS-IP-Address', '126.0.0.1'), ('NAS-Port', '1812'), ('Message-Authenticator', '0xacf43d1ab9f8719bc9e92f0f7ebd4395'))
{}
(0)     [python] = ok
(0)     policy filter_username {
(0)       if (&User-Name) {
(0)       if (&User-Name)  -> TRUE

Не запускается MySQL. Исправляем ))

Сначала смотрим логи mysql. Вдумчиво. Возможно что-то удастся понять и устранить (может банально кончилось место на диске).

Если не помогает, то в файле my.cnf добавляем строчку:

innodb_force_recovery=1

И далее пытаемся запустить mysql:

sudo service mysql start

Если запустилось — проверяем таблицы:

mysqlcheck -uroot -pукацука --auto-repair --all-databases

Далее убираем из my.cnf строчку innodb_force_recovery=1 иперезапускам сервис:

sudo service mysql start

Есть шанс что всё заработает 😉

Проверка доступности IP адресов по списку

Озадачил тут  Роскомнадзор: а проверьте, доступно 65321 IP адрес в вашей сети? И предоставило текстовый файлик. А нам что? 5 минут и скрипт готов:

#!/usr/local/bin/python3
# coding=utf-8
import socket
import threading
import time 
import sys
import os

vr="1.0"
thread_count=100
info="Сей дивный скрипт пробегает список IP и смотрит доступен он или нет"
copyleft="by Pavel Gribov, http://грибовы.рф";

#выводим имя ПК и версию скрипта                
hostname = socket.gethostname()
print ("Server: ",hostname)
print ("Version: ",vr)
print ("info: ",info)
print ("Copyright: ",copyleft)

def worker(ip):     
    response = os.system("fping " + ip+" >/dev/null")
    if response == 0:
        print ("Test:"+ip+" -ok");
  
if len(sys.argv)>=2: 
    fname=sys.argv[1]
else:
    print ("Параметры запуска:")
    print ("<filename>  - текстовый файл со списком IP")
    exit(0)
        
    
with open(fname, 'r') as f:
  ips= f.read().splitlines()    
   
for ip in ips:   
  thread = threading.Thread(target=worker, args=(ip,)).start()	
  while threading.active_count() >thread_count:
     time.sleep(1)

while threading.active_count() >1:
     time.sleep(1)