4. Схема управления абонентами на NAS

Skip to end of metadata
Go to start of metadata

Прошлая схема с event_inc.sh выносила наружу слишком много нюансов по настройке, которые могли сказаться на дальнейшей стабильности работы схемы интеграции. В новой версии мы старались максимально скрыть нюансы работы системы.

План интеграции:

Шаг 1. Обновить биллинг до последней версии.

Шаг 2. Создать и настроить nas в менеджере 4го биллинга. Не забудьте указать имя скрипта событий (желательно, чтобы имя не пересекалось с уже существующими файлами в каталоге /var/lib/event/). Для каждого типа NAS (а иногда и для каждого NAS в принципе) нужно использовать своё имя скрипта.

Шаг 3. Пример работы скрипта вы можете посмотреть по пути /var/lib/event/example/xge_router.sh. Только для отправки на ваше оборудование нужно будет использовать свои команды.  

Шаг 4. Создать файл обработчик для вашего типа оборудования в каталоге /var/lib/event. Прописать управляющие команды по состояниям абонента (список состояний ниже). Добавить имя скрипта в настройках NAS в менеджере.

Шаг 5. Если до этого вы использовали свой скрипт отправки команд /var/lib/event/event_inc.sh, то его нужно забекапить и вместо него использовать скрипт event_inc.sh, текст которого описан в примере ниже.

* На типе подписки SLA Аутсорсинг специалисты технической поддержки могут настроить оборудование. В наличии схемы для MikroTik, Redback, Cisco. И создать скрипты отказоустойчивости и полной ежедневной синхронизации.

Список состояний абонента

user_add() - добавление нового абонента. Проходит при создании/изменении абонента в биллинге;
user_del() - удаление/изменение абонента в биллинге;
user_accept() - разрешение доступа в интернет (когда абонент не заблокирован и состояние "Все параметры заданы верно");
user_drop() - запрещение доступа в интернет (удаление с оборудования);
user_redirect() - переадресация на страницу заглушку при отрицательном балансе. Если редирект не используется нужно блокировать абонента;
user_redirect_cancel() - отмена переадресации на страницу заглушку при отрицательном балансе или отмена блокировки;
user_rate_set() - установка скорости абоненту из правил тарифа;
user_disconnect() - ручное отключение абонента из менеджера.

Все состояния системой вызываются группами, например при переходе абонента в отрицательный баланс проходят состояния:

  • user_accept
  • user_redirect
  • user_rate_set

При переходе обратно в положительный баланс:

  • user_accept
  • user_redirect_cancel
  • user_rate_set

Логи отправки событий можно смотреть здесь: /var/log/eventd.log

event_inc.sh

LOG_LEVEL=ALL

SENDER=$1; shift
EVENT=$1; shift
DATA=$@

for VAR in $DATA; do
      [[ "$VAR" = *"="* ]] && eval ${VAR%%=*}=\'${VAR#*=}\'
done

LOG INFO "$SENDER $EVENT $DATA"

user_refresh(){
    accept=1
    [ "$logged" = "-1" ] && accept=0
    [ "$enabled" = "0" ] && accept=0
    [ "$deleted" = "1" ] && accept=0
    [ "$own_disabled_end" != -1 ] && accept=0
    redirect=0
    [ "$over_limit" = "1" ] && redirect=1

    [ "$accept" = "1" ] && user_accept
    [ "$redirect" = "0" ] && user_redirect_cancel
    [ "$redirect" = "1" ] && user_redirect
    [ "$accept" = "0" ] && user_drop
}

user_data_changed(){
    if [ -f /var/lib/event/before/$id.before ]; then
	changed=0
	for VAR in $(</var/lib/event/before/$id.before); do
             [[ "$VAR" = *"="* ]] && eval ${VAR%%=*}=\'${VAR#*=}\'
        done
	for val in ip mac server enabled deleted auth_type nas_ip router_ip router_vlan router_port opt82 limit_ip acl; do
            old_val="old_$val"
            [ "${!val}" != "${!old_val}" ] && changed=1;
	done
    else
	changed=1
    fi

    if [ "$changed" = "1" ]; then
        (
            DATA_BEFORE=$(</var/lib/event/before/$id.before)
            DATA_BEFORE="${DATA_BEFORE// old_/ }"
            DATA=$DATA_BEFORE
            for VAR in $DATA_BEFORE; do
                 [[ "$VAR" = *"="* ]] && eval ${VAR%%=*}=\'${VAR#*=}\'
            done
            user_del
        )
        user_del
        user_add
	user_refresh
        user_rate_set
    fi
}


if [ -f /var/lib/event/$script_name ]; then
    source /var/lib/event/$script_name
    if [ "$EVENT" = "rate_set" ]; then
	user_rate_set
    elif [ "$EVENT" = "user_disconnect" ]; then
	user_disconnect
    elif [ "$EVENT" = "user_add" ]; then
	user_add
	user_refresh
    elif [ "$EVENT" = "user_del" ]; then
	user_del
    elif [ "$EVENT" = "user_data_changed_before" ]; then
	echo "${DATA// / old_}" >/var/lib/event/before/$id.before
    elif [ "$EVENT" = "user_data_changed" ]; then
	user_data_changed
    elif [ "$EVENT" = "radius_update_err" ]; then
	user_disconnect
#    elif [ "$EVENT" = "rad_acc_timeout" ]; then
#	user_disconnect
    elif [ "$EVENT" = "user_info" ]; then
	user_info 2>&1 > /tmp/${id}_user_info
	output="$(cat /tmp/${id}_user_info | head -c 8000 | iconv -f koi8-r -t cp1251)"
	rm -f /tmp/${id}_user_info
	{
	    . /etc/ics/ics.conf
	    echo -e "SET SQL DIALECT 3;\n"
	    echo -e "SET NAMES WIN1251;\n"
	    echo -e "CONNECT '127.0.0.1:/var/db/ics_main.gdb' USER '$ISC_USER' PASSWORD '$ISC_PASSWORD';\n"
	    echo -e "DELETE FROM users_diagnostic WHERE user_id='$id';\n"
	    echo -e "EXECUTE PROCEDURE KNL_USR_DIAGNOSTIC_INS('$id', '$output');\n"
	    echo -e "commit;\n"

	} >/tmp/$$.tmp
	isql < /tmp/$$.tmp
	rm -f /tmp/$$.tmp
    else
	user_refresh
    fi
else
    echo "NO SCRIPT FOUND!!!"
fi

Доступные переменные

Имя Содержимое
id=2 ID пользователя в биллинге
login=Administrator логин пользователя
ip=192.168.28.52 IP адрес пользователя
mac=12:34:56:78:90:10 MAC адрес пользователя, если есть MAC-привязка
server=1 Признак использования isNAT (0-NAT вкл, 1-NAT выкл)
snat_ip=8.8.8.8 NAT IP пользователя
finance_user=1 признак финансового пользователя
enabled=1 пользователь включен, 0 - отключен
deleted=0 пользователь не удален, 1 - удален в корзину
end_user=1 конечный пользователь, 0 - группа
logged=1 1-пользователь считается авторизованным
auth_type=1 тип авторизации (смотри ниже)
tariff_id=1 id тарифа
contract_number= номер договора
always_logged=0 1 - всегда подключен
nas_ip=0.0.0.0 IP адрес NAS-сервера указанный в Carbon Manager
router_ip=0.0.0.0 IP switch'a, 0.0.0.0 - не указан
router_vlan=-1 vlan switch'a, -1 - не указан
router_port=-1 порт switch'a, -1 - не указан
opt82=0 опция 82, 1 - включена
over_limit=0 1 - превышен лимит
limit=0 Порог отключения
balance=0 текущий баланс пользователя
unlimited=1 1-не отключать при превышении порога отключения
nas_type=0 тип NAS, через который подключен пользователь
radius_secret= пароль radius, указанный в настройках NAS
disabled_date= значение поля "отключить по дате"
rate_in= гарантированная входящая скорость из тарифа
rate_out= гарантированная исходящая скорость из тарифа
ceil_in= максимальная входящая скорость из тарифа
ceil_out= максимальная исходящая скорость из тарифа
double_login=0 1-попытка подключения при уже имеющемся соединении
acct_session_id= Accounting session id

Способы передачи команд оборудованию

В настоящее время для передачи команд оборудованию можно использовать несколько способов

  • /usr/bin/send_mikrotik_cmd (реализация Mikrotik API на python, крайне рекомендуется для Mikrotik) 
  • /usr/sbin/radclient (CoA клиент)
  • SNMP
  • /usr/local/bin/ssh_send (поддерживает протоколы SSH и Telnet)
  • /usr/local/bin/expect
  • При авторизации по radius в атрибутах пакета access-reply (настраивается отдельно для каждого тарифа на вкладке RADIUS, можно передавать только переменные $rate_in, $ceil_in, $rate_out, $ceil_out, $overlimit, $balance, $nat)

Пример скрипта отправки команд на NAS

#!/bin/bash

trap __exit EXIT

TMPDIR=/tmp/${0##*/}
mkdir -p $TMPDIR

__exit() {
	local ret=$?
	rm -f $TMPDIR/*.$$
	return $ret
}

# set -eux

burst_in=''
burst_out=''
ceil_in=${ceil_in:-1000}
rate_in=${rate_in:-1000}
ceil_out=${ceil_out:-1000}
rate_out=${rate_out:-1000}

__xge_coa_send() {
	echo "Filter-Id=\"$@\"" | radclient -x $nas_ip coa $coa_psw &>$TMPDIR/radclient.$$
	ret=$?
	# exit 254 отложить передачу, todo возможно и другие схожие busy context и тд
	grep "no response from server" $TMPDIR/radclient.$$ && exit 254
	cat $TMPDIR/radclient.$$
	return $ret
}

user_add() {
	[ "$auth_type" = "1" ] && __xge_coa_send session $ip start IPOE
}

user_del() {
	__xge_coa_send session $ip stop "user_del"
	__xge_coa_send session $ip remove
}

user_accept() {
	[ "$auth_type" = "1" ] && __xge_coa_send session $ip start IPOE
	__xge_coa_send session $ip redirect blocked cancel
	__xge_coa_send session $ip nat $snatip
}

user_drop() {
	__xge_coa_send session $ip redirect blocked
}

user_redirect() {
	__xge_coa_send session $ip redirect negbal
}

user_redirect_cancel() {
	__xge_coa_send session $ip redirect negbal cancel
}

user_rate_set() {
	__xge_coa_send session $ip rate set in $rate_in $ceil_in $burst_in out $rate_out $ceil_out $burst_out

}

user_rate_set_cancel() {
	__xge_coa_send session $ip rate remove
}

user_disconnect() {
	__xge_coa_send session $ip disconnect
}

Введите метки, чтобы добавить к этой странице:
Please wait 
Ищите метку? просто начните печатать.