Просмотр Исходного

В стандартной реализации связки Billing и XGE (вклчая Softrouter) отсутствует привязка ip+mac. Если она требуется, необходимо отредакритовать скрипт управления XGE в биллинге и, при необходимости, добавить синхронизатор MAC привязок.
{info}IP+MAC привязки реализованы через создание статических записей в ARP таблице{info}

{toc}

h1. Скрипт событий
# Создайте папку для измененного скрипта:
{code}mkdir -p /app/asr_billing/cfg/var/lib/event/
touch /app/asr_billing/cfg/var/lib/event/xge_router.sh
chmod a+x /app/asr_billing/cfg/var/lib/event/xge_router.sh{code}
# Созддайте файл */app/asr_billing/cfg/var/lib/event/xge_router.sh* со следующим содержимым:
{code}#!/bin/bash

. /usr/local/lib/carbon.shlib

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
__xge_coa_send session $ip mac set $mac
}

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
__xge_coa_send session $ip mac $mac
}

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_info() {
__xge_coa_send session $ip info
}

user_test() {
__xge_coa_send session $ip test
}


user_event_before() {
:
}

user_event_after() {
:
}

user_disconnect() {
__xge_coa_send session $ip disconnect
}
__xge_list_local(){
ipset -o save -l $4 | grep add | cut -d ' ' -f 3
}
__xge_ssh_send(){
echo -e "chroot /app/xge $@\nexit\n" | ssh_send --port ${telnet_port:-33} -u ${telnet_login:-root} -p ${telnet_password:-servicemode} ${nas_ip:-127.0.0.1}
}
users_from_nas() {
# здесь нельзя использовать coa тк буфер маленький у него и не войдет весь вывод
local SYNCDIR="/var/lib/event/sync/$nas_ip"
mkdir -p $SYNCDIR
if [ "$nas_ip" != "169.254.18.12" ]; then
__xge_ssh_send xgesh show list xge_blocked_list | grep '^[0-9].*' > $SYNCDIR/blocked_list.nas
__xge_ssh_send xgesh show list xge_negbal_list | grep '^[0-9].*' > $SYNCDIR/negbal_list.nas
__xge_ssh_send xgesh show list xge_auth_list | grep '^[0-9].*' > $SYNCDIR/auth_list.nas
fi
# чтоб на софтроутере пароль не указывать
if [ "$nas_ip" = "169.254.18.12" ]; then
__xge_list_local xgesh show list xge_blocked_list | grep '^[0-9].*' > $SYNCDIR/blocked_list.nas
__xge_list_local xgesh show list xge_negbal_list | grep '^[0-9].*' > $SYNCDIR/negbal_list.nas
__xge_list_local xgesh show list xge_auth_list | grep '^[0-9].*' > $SYNCDIR/auth_list.nas
fi
}

user_info(){
echo '<pre>' > /tmp/${user_id}_user_info.new
__xge_coa_send session $ip test human | grep "Reply-Message" | sed -e 's/Reply-Message =//g; s/^\s\+//g; s/^"//g; s/"$//g' >> /tmp/${user_id}_user_info.new
echo '</pre>' >> /tmp/${user_id}_user_info.new

mv -f /tmp/${user_id}_user_info.new /tmp/${user_id}_user_info
chown apache:apache /tmp/${user_id}_user_info
}

user_get_mac() {
local TMPDIR=/tmp/nas_event_daemon/$nas_ip/user_get_mac/
mkdir -p $TMPDIR/

__xge_coa_send session $ip mac get | grep "Reply-Message" | sed -e 's/Reply-Message =//g; s/^\s\+//g; s/^"//g; s/"$//g' >> ${TMPDIR}/${user_id}

chmod 777 -R /tmp/nas_event_daemon/
}{code}
# Перезапустите контейнер биллинга:
{code}/app/asr_billing/service restart{code}

h1. Синхронизация привязок MAC+IP на XGE по БД биллинга
Описано создание привязок на стороне XGE в случае если Вы решили внедрить привязку IP+MAC, у абонентов заведены MAC-адреса в учетных записях и Вы хотите назначить привязки на стороне XGE.
# Создайте файл скрипта
{code}touch /app/base/cfg/set_xge_ip_mac.sh
chmod a+x /app/base/cfg/set_xge_ip_mac.sh{code}
Заполните скрипт */app/base/cfg/set_xge_ip_mac.sh*
{code}#!/bin/bash

sqlexec "set heading off; select uf_ip2string(ip),mac from users where mac!='' and ip!=0 and deleted=0 and opt82=0 and abonent_id>1" | grep -v "^$" | sort -u | awk '$1$2{print $1";"$2}' > /tmp/ipmac.list

while IFS=';' read ip mac; do
if [[ $1 == "remove" ]]; then
chroot /app/xge xgesh session $ip mac remove
elif [[ $1 == "set" ]]; then
chroot /app/xge xgesh session $ip mac set $mac
else
echo xgesh session $ip mac set $mac
fi
done <<< "$(</tmp/ipmac.list)"{code}
Скрипт ожидает передачи параметров:
#* *set* - установить привязки
#* *remove* - удалить привязки
#* *без параметров* - напечатать в терминал команды для установки привязок по пользовательским сессиям без выполнения
# Запустите синхронизацию:
{code}bash -x /app/base/cfg/set_xge_ip_mac.sh set &>>/var/log/xge_ipmac_set.log{code}
Лог синхронизации можно будет найти по пути */var/log/xge_ipmac_set.log*

h1. Синхронизация IP+MAC по ARP таблице
Синхронизация выполняется вручную при необходимости, например при внедрении функции если абоненты уже заведены, но ранее привязка не исопльзовалась.
Скриты получают MAC-адреса абонентов из ARP-таблицы XGE.
# Создайте файлы скриптов и установите права на выполнение
{code}touch /app/xge/cfg/mac_autoget.sh
touch /app/base/cfg/mac_process.sh
chmod a+x /app/xge/cfg/mac_autoget.sh
chmod a+x /app/base/cfg/mac_process.sh{code}
# Создайте указанные ниже файлы и со следующим содержимым:
*/app/xge/cfg/mac_autoget.sh*
{code}#!/bin/bash

>/tmp/true_ipmac
#Проходим по списку IP юзеров, у которых в базе не прописан мак
#Если мак в arp таблице обнаружен, cоздаем статическую привязку, пишем в файл ip и mac
for ip in $(</tmp/users_ip_where_no_mac_in_db.list); do
current_mac="$(xgesh session $ip mac get)"
if [ "$current_mac" == "00:00:00:00:00:00" ]; then
continue
else
echo $ip $current_mac >> /tmp/true_ipmac
xgesh session $ip mac set $current_mac
fi
done {code}
*/app/base/cfg/mac_process.sh*
{code}#!/bin/bash

#Получаем из db список IP неудаленных юзеров, у которых пустой мак и есть ip
get_list() {
sqlexec "set heading off; select uf_ip2string(ip) from users where mac='' and ip!=0 and deleted=0 and opt82=0 and abonent_id>1" | grep -v "^$" | sort -u > /app/xge/tmp/users_ip_where_no_mac_in_db.list
}
#Вызываем сторонный скрипт получения маков из арп таблицы
mac_get() {
chroot /app/xge/ /cfg/mac_autoget.sh
}

#Обновлям маки юзеров из списка, который сгенерировал скрипт /app/xge/cfg/mac_autoget.sh
mac_save() {
[ ! -s /app/xge/tmp/true_ipmac ] && exit 11
while read ip mac ; do
curl -XPOST 'http://169.254.80.82:8082/rest_api/v2/Users/' -d 'method1=objects.get&arg1={"ip":"'$ip'"}&method2=set&arg2={"mac":"'$mac'"}&method3=save&arg3={}'
done <<< "$(</app/xge/tmp/true_ipmac)"

}

main() {
get_list
mac_get
mac_save
}

main{code}
# Запустите синхронизацию:
{code}bash -x /app/base/cfg/mac_process.sh &>>/var/log/xge_ipmac_arp_sync.log{code}
Лог синхронизации можно будет найти по пути */var/log/xge_ipmac_arp_sync.log*