Настройка биллинговой системы abills + VPN + radius + mysql

Материал из Wiki МИАЦ ВО
Версия от 12:47, 23 октября 2007; 172.16.130.19 (обсуждение) (Новая: Попытка адаптировать документацию по биллинговой системе ABILLS применительно к использованию ее под О...)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигации Перейти к поиску

Попытка адаптировать документацию по биллинговой системе ABILLS применительно к использованию ее под ОС Linux Версия abills: 0.35 релиз

Этот документ базируется на оригинальной документации по ABILLS от Asmodeus’а http://abills.asmodeus.com.ua

Здесь будет описана установка биллинга для VPN сервера (abills + pppd + pptpd) Пути установки программ и расположения конфигурационных файлов несколько изменены по сравнению с оригинальной документацией. Вы можете их изменять, однако отдавайте себе отчет, что при этом потребуется изрядно переконфигурировать весь комплекс программ. Все компоненты (NAS, radius, web-сервер, база данных) расположены на одном сервере, хотя это не исключает возможности вынести например NAS или базу данных на другую машину.

Итак- устанавливаем пакеты, нужные для настройки биллинга freeradius-1.1.2-2mdv2007.0.i586.rpm, libfreeradius1-1.1.2-2mdv2007.0.i586.rpm, libfreeradius1-mysql-1.1.2-2mdv2007.0.i586.rpm, libradius0-0.3.2-6mdk.i586.rpm, ppp-radius-2.4.3-12mdv2007.0.i586.rpm, pptpd-server-1.3.0-2mdv2007.0.i586.rpm, radiusclient-utils-0.3.2-6mdk.i586.rpm, webmin*.rpm

Возможности ABillS

  1. Тарификация по времени
  2. Тарификация по трафику
  3. Периодические отчисления (месячная и дневная абонплата)
  4. Возможность раздельной и совместной тарификации по времени и трафику
  5. Ограничение доступа в интернет по времени суток
  6. Callback
  7. Система скидок
  8. Установка минимальной цены сессии
  9. Работа с неограниченным количеством NAS серверов
  10. Авторизация по SQL базе даных или по системной UNIX базе паролей
  11. Авторизация по PAP, CHAP, MS-CHAP, MS-CHAPv2+MPPE (CHAP, MS-CHAP, MS-CHAPv2 при сохраниени паролей в SQL базе)
  12. Шифрование траффика MPPE
  13. IEEE 802.1x
  14. Авторизация PPPoE по MAC адресу
  15. Авторизация PPTP по IP адресу (для MPD по IP и MAC одновременно)
  16. Изменение тарифного плана или снятие денег со счета по расписаню
  17. Классификация трафика (внутрений, внешний, бесплатный) (Только для VPN, Ipnet)
  18. Ограничение скорости в зависимости от вида трафика и времени суток (Только для VPN)
  19. Создание месячных предоплаченых по трафику пакетов
  20. Дневные, недельные и месячные лимиты по трафику и времени
  21. Отчёты по работе системы и с остоянию счетов за любой период времени
  22. Генерация и отправка администратору добовых и месячных отчётов по работе системы
  23. WEB интерфейс управления системой с возможностью настроики прав доступа
  24. Лог действий администратора, менеджера
  25. Ограничение сессий по количеству общего (in+out) трафика (для exppp, mpd, pppd + RADIUS plugin (Linux))
  26. Несъёмный минимум для подключений к NAS серверам (Tarif Plans → Credit Tresshold)
  27. Выписка счётов из пользовательского интерфейса
  28. Обратная связь
  29. Система предоплаченых карт.
  30. VoIP – GNU Gatekeeper, Asterisk
  31. Система пополнения через платёжные системы Webmoney.ru и RUpay.ru
  32. Squid монитор
  33. SNMP монитор и набор утилит для работы с NAS серверами.
  34. Система рассылки сообщений для пользователей.
  35. Распространяется по лицензии GNU GPL 2

pppd

Правим файл /etc/modprobe.preload и /etc/modules, добавляя в конец строку ppp_mppe и делаем

#modprobe ppp_mppe

Создаем файл /etc/ppp/options.pptpd со следующим содержимым:

mtu 1490
mru 1490
ms-dns 172.16.130.1             # ip адресс DNS сервера
ipcp-accept-local
ipcp-accept-remote
lcp-echo-failure 30
lcp-echo-interval 5
auth
+mschap-v2
defaultroute
mppe required,stateless
#plugin radius.so
#plugin radattr.so
#debug

Более детальное описание опций здесь - http://mppe-mppc.alphacron.de/

Примечание: в последнее время я пришел к выводу, что MPPE и MPPC в домашней сети не такая уж и полезная фича. Ресурсов отъедает прилично. По этому если вы строите NAS на недостаточно производительном железе, подумайте, нужно ли оно вам. Возможно лучшим выходом будет отключить обязательное шифрование в виндовом клиенте.

pptpd

pptpd, (подпольная кличка - PopTop) можете взять из своего дистрибутива

Правим файл /etc/pptpd.conf :

ppp /usr/sbin/pppd
option /etc/ppp/options.pptpd
debug
# stimeout 10
# noipparam
logwtmp
bcrelay eth0
localip ***.***.***.*** # Здесь IP адрес вашего сервера в локальной сети 
#remoteip 192.168.0.234-238,192.168.0.245 # Закоментировать, назначается
				 	  #радиусом
Редактируем файл /etc/ppp/chap-secret
# Secrets for authentication using CHAP
# client        server  secret                  IP addresses
vova    *       vova            192.168.200.5
Перезапускаем pptpd демон и пробуем войти по VPN c Win машины с авторизацией CHAP, или MS-CHAP V2 c шифрацией трафика с именем vova и паролем vova. Если все ок, снимаем ремарки со строк
plugin radius.so
plugin radattr.so

в файле options.pptpd и идем дальше.

Установка freeradius

Переименовываем файл

#mv /etc/raddb/users  /etc/raddb/users.old 

Создаем новый файл /etc/raddb/users и вставляем туда строки

DEFAULT Auth-Type = Accept
		Exec-Program-Wait = "/usr/abills/libexec/rauth.pl"

Правим файл /etc/raddb/acct_users

#Перед Exec-Program должен быть пробел
#Если каждого аккаунтинг-запроса в памяти оставались зомби-процессы racct.pl, то замените
#замените в файле acct_users Exec-Program на Exec-Program-Wait
DEFAULT Acct-Status-Type == Start
 		Exec-Program = "/usr/abills/libexec/racct.pl"
 DEFAULT Acct-Status-Type == Alive
 		Exec-Program = "/usr/abills/libexec/racct.pl"
DEFAULT Acct-Status-Type == Stop
 		Exec-Program = "/usr/abills/libexec/racct.pl"

Не забываем про пробелы перед Exec-Program

У большинства такая конфигурация работает нормально, а в моем случае после каждого аккаунтинг-запроса в памяти оставались зомби-процессы racct.pl. Проверить это можно командой:

ps ax|grep racct

Если у вас тоже остаются зомби, то рекомендую заменить в файле acct_users Exec-Program на Exec-Program-Wait

/etc/raddb/clients.conf В этот файл нужно вписать IP адрес или имя NAS сервера с которого будут поступать данные для радиуса и пароль доступа, те исправить строки secret.

client localhost {
   # Ниже пароль для доступа к радиусу. Запомните его, он 
   # понадобится в п. 8 
   secret = radsecret     
   shortname = shortname
}

/etc/raddb/radiusd.conf- Если вы желаете использовать MPPE, MPPC, MS-Chap V2 (протоколы шифрования и компрессии от M$ - для VPN очень желательно) то в файл /etc/raddb/radiusd.conf вносятся следующие изменения: В секции mschap {

use_mppe = yes
require_encription = yes
require_strong = yes

Cоздаются функции для преавторизации и поставторизации в секции modules {

exec pre_auth { 
  wait = yes 
  program = "/usr/abills/libexec/rauth.pl pre_auth" 
  input_pairs = request 
  output_pairs = config 
}
 
exec post_auth {
  wait = yes
  program = "/usr/abills/libexec/rauth.pl post_auth"
  input_pairs = request
  output_pairs = config
}

В секции ‘authorize’ внести ‘pre_auth’ и раскоментировать ‘mschap’.

authorize { 
  pre_auth 
  preprocess
 # auth_log 
 # attr_filter 
   chap 
  mschap 
  suffix 
  files 
} 

Для оповещения о неавторизированых пользователях правим секцию post-auth

post-auth {
  Post-Auth-Type REJECT {
     post_auth
  }
}

Для нормальной работы с NAS на основе pppd необходимо добавить в файл словарей freeradius’а /etc/raddb/dictionary и /etc/radiusclient/dictionary следующие строки:

# Limit session traffic
 ATTRIBUTE       Session-Octets-Limit            227     integer
 # What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out)
 ATTRIBUTE       Octets-Direction                228     integer
 # Connection Speed Limit
 ATTRIBUTE       PPPD-Upstream-Speed-Limit       230     integer
 ATTRIBUTE       PPPD-Downstream-Speed-Limit     231     integer
 ATTRIBUTE       PPPD-Upstream-Speed-Limit-1     232     integer
 ATTRIBUTE       PPPD-Downstream-Speed-Limit-1   233     integer
 ATTRIBUTE       PPPD-Upstream-Speed-Limit-2     234     integer
 ATTRIBUTE       PPPD-Downstream-Speed-Limit-2   235     integer
 ATTRIBUTE       PPPD-Upstream-Speed-Limit-3     236     integer
 ATTRIBUTE       PPPD-Downstream-Speed-Limit-3   237     integer

Проверка конфигурационных файлов freeradius

check-radiusd-config -level 345 radiusd on

Если все ок, то:

Radius server configuration looks OK.

При отладке останавливаем freeradius, и запускаем freeradius -X

MYSQL

Создаем файл pre_abills.sql следующего содержания:

use mysql;
INSERT INTO user (Host, User, Password) VALUES ('localhost','abills',password('sqlpassword'));
INSERT INTO db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Index_priv, Alter_priv) VALUES ('%', 'abills', 'abills', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y');
CREATE DATABASE abills;

Не забудьте исправить sqlpassword на свое усмотрение. Для тех кто не понял, это пароль mysql-пользователя abills, необходимый для доступа к базе данных abills

Cоздаём пользователя и базу.

Далее делаем в консоли.

# mysql -u root -p < pre_abills.sql
# mysqladmin flush-privileges

Я просто создал пользователя в webmin, дал ему полный доступ к базе “abills” и установил пароль.

На этом настройка mysql завершена.

Perl modules

Для работы системы нужны модули.

DBI 	
DBD::mysql	
Digest-MD5	для Chap авторизации
Digest-MD4	для MS-Chap авторизации
Crypt-DES 	для MS-Chap авторизации
Digest-SHA1	для MS-ChapV2 авторизации
libnet 	Нужен только при авторизации из UNIX passwd
Time-HiRes	Нужен только для тестирования скорости выполнения авторизации,
 		акаунтинга, и страниц веб интерфейса.
DB_File

Все модули, кроме DBI есть в rpm-ax.

Установить модуль perl-devel-5.8.8-7mdv2007.0.i586.rpm

Установить модули Perl-DBD-mysql-3.0006-2mdv2007.rpm и Perl-DB_File-1.814-1mdk.rpm

Очень удобно эти модули загрузить с сайта | www.cpan.org или установка с консоли. Вот способ установки:

# cd /root 
# perl -MCPAN -e shell 
o conf prerequisites_policy ask 
install    DBI      
install    Digest::MD5 
install    Digest::MD4 
install    Crypt::DES 
install    Digest::SHA1 
install    Bundle::libnet 
install    Time::HiRes 
quit

Abills

Скачиваем и распаковываем релиз версии 0.35 в отдельный каталог:

cd /usr/src/abills_distr
wget http://puzzle.dl.sourceforge.net/sourceforge/abills/abills-0.35.tgz
tar -xvzf abills-0.35.tgz

Правим конфигурационый файл системы /usr/abills/libexec/config.pl:

#DB configuration 
$conf{dbhost}='localhost';
$conf{dbname}='abills'; 
$conf{dblogin}='abills';

#Здесь нужно подставить пароль mysql-пользователя abills (п.2)
$conf{dbpasswd}='sqlpassword'; 
$conf{ADMIN_MAIL}='info@your.domain'; 
$conf{USERS_MAIL_DOMAIN}="your.domain";
#For MySQL 5 and highter
$conf{dbcharset}='cp1251';
# используется для шифрования паролей администраторов и пользователей.
$conf{secretkey}="test12345678901234567890"; 

#Лимит трафика на сессию, больше нельзя, изза глюка radiusclient'а
$conf{MAX_SESSION_TRAFFIC}=2047; 
# Проверять депозит по текущим сессиям, при достижении 0 сбрасывать с линии
$conf{periodic_check}=’yes’; 

Разкоментировать строку 74 для MySQL 5 и выше в файле /usr/abils/Abills/mysql/main.pm

#For mysql 5 or highter
  $self->{db}->do("set names ".$attr->{CHARSET}) if ($attr->{CHARSET});

При использовании модуля Dv полезно так же добавить в конфиг следующие параметры, и изменить их по своему усмотрению.

$conf{MAC_AUTO_ASSIGN}=0;    # Заполнять поле CID при cоединении, если оно не заполнено
$conf{DV_USER_CHG_TP}=0;     # Разрешить пользователю менять тарифный план из своего веб акаунта
$conf{ERROR_ALIVE_COUNT}=3;  # Количество периодов не пришедших Alive пакетов после которого сесия автоматом    попадает в Zap таблицу

При изменении значения в $conf{secretkey} поменяйте его также в файле abills.sql из дистрибутива abills. После этого загружаем структуру таблиц в базу:

Тут хитро. Дамп базы в дистрибутиве дан в кодировке cp1251 и для того, что бы его установить нужно открыть файл abills.sql и для каждой таблицы добавить

DEFAULT CHARSET=cp1251 

Вот пример для одной таблицы

CREATE TABLE `users_nas` ( 
  `uid` int(10) unsigned NOT NULL default '0', 
  `nas_id` smallint(5) unsigned NOT NULL default '0', 
  KEY `uid` (`uid`) 
) DEFAULT CHARSET=cp1251 ;

Заливаем пустую таблицу

#mysql -D abills < abills.sql

Для того, чтобы можно было осуществлять hangup подключенного пользователя необходимо добавить в файл /etc/sudoers:

apache   ALL = NOPASSWD: /usr/abills/misc/pppd_kill

Вносим в cron периодические процессы, /etc/crontab (уберите восклицательный знак в начале первой строки):

*/5 *  *  *  *   root    /usr/abills/libexec/billd -all
 1    0  *  *  *   root    /usr/abills/libexec/periodic daily
 1    0  1  *  *   root    /usr/abills/libexec/periodic monthly

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

1    3  *  *  *   root     /usr/abills/libexec/periodic backup

Определяем от имени какого пользователя запускается web-сервер в нашей системе. Для этого надо просмотреть файл httpd.conf и найти в нем директиву User, которая определяет имя владельца процесса. В моем случае:

User apache

Устанавливаем права на чтение и запись вебсервером для файлов веб интерфейса

chown -Rf apache /usr/abills/cgi-bin

Создаем недостающие каталоги:

mkdir /usr/abills/backup
chown apache /usr/abills/backup
mkdir /usr/abills/var
mkdir /usr/abills/var/log

Правим файл /usr/abills/Abills/defs.conf. После правки я бы рекомендовал скопировать этот файл в defs.conf.old, что бы после обновления abills не пришлось снова его править.

$SNMPWALK = '/usr/bin/snmpwalk';
$GZIP = '/bin/gzip';
$MYSQLDUMP = '/usr/bin/mysqldump';

В вашем случае пути к этим программам могут быть иными, проверьте командой which.

Еще: freeradius будет ругаться, что у вас нет логов abills, поэтому мы это исправляем.

touch /usr/abills/var/log/abills.log
chown radius /usr/abills/var/log/abills.log

Далее настраиваем apache | . Открываем веб интерфейс - https://your.host:9433/abills/admin/ Логин администратора по умолчанию - abills , пароль - abills. От имени этого администратора будут выполняться различные операции в автоматическом режиме, например снятие абонплаты в начале месяца, по этому удалять его не нужно, нужно только изменить пароль на более безопасный. Для реальных администраторов необходимо завести свои аккаунты и назначить им необходимые права: Система → Администраторы

Если впоследствии вам понадобится самая свежая функциональность обновления из CVS можно производить следующим образом:

cd /usr/src/abills_distr
    cvs -d:pserver:anonymous@abills.cvs.sourceforge.net:/cvsroot/abills login
    cvs -z3 -d:pserver:anonymous@abills.cvs.sourceforge.net:/cvsroot/abills checkout -r rel-0-3 abills      
    cp -Rf abills /usr/
chown -Rf apache /usr/abills/cgi-bin

После этого изучаем changelog и выполняем необходимые рекомендации.

Тот кто выполнил все предыдущие пункты и увидел вебинтерфейс заслужил первую бутылку пива. Дальнейшее описание специфично именно для Linux-систем с pppd.

Для нормального вывода русских букв в юзеровском интерфейсе нужно поправить в файле /usr/abills/cgi-bin/index.cgi строка примерно 42

было

my $sql = Abills::SQL->connect($conf{dbtype}, $conf{dbhost}, $conf{dbname}, $conf{dbuser}, $conf{dbpasswd});

стало Код:

my $sql = Abills::SQL->connect($conf{dbtype}, $conf{dbhost}, $conf{dbname}, $conf{dbuser}, $conf{dbpasswd},   { CHARSET => $conf{dbcharset}});

И все заработало.

Web server

Для работы web-интерфейса требуется установить и настроить web сервер. Как и в случае с mysql нет особого смысла собирать его из исходников, поскольку любой приличный дистрибутив уже имеет в своем составе web-сервер Apache. Он должен быть собран и сконфигурирован с поддержкой модуля mod_rewrite. Переписываем файл /usr/abills/misc/abills_httpd.conf в каталог /etc/httpd/conf/vhosts.d/

Создание ssl сертификата

В версии abills 0.36b в файл abills_httpd.conf добавлен ssl сертификат
Его можно создать вумя способами

Используем скрипт /usr/abills/misk/sslserts.sh

Запускаем скрипт

/usr/abills/misc/sslcerts.sh apache

И отвечаем на вопросы, которые будет задавать скрипт. В конце получим 2 сертификата, лежащий в папке /usr/abills/Certs
После этого править файл /etc/httpd/conf/vhosts.d/abills_httpd.conf не надо.

С помощью своего скрипта

Делаем следующее:

# cd /etc/ssl
# mkdir db
# mkdir ca
# mkdir clients
# touch /etc/ssl/db/index.txt
# echo "01" > /etc/ssl/db/serial

Создаем скрипт для создания нашего самоподписанного доверенного сертификата (CA) /etc/ssl/make_ca.sh :

#!/bin/sh
openssl req -new -newkey rsa:4096 -nodes -keyout ./ca/ca.key -x509 -days 3650 \
   -subj /C=RU/ST=Russia/L=Vologda/O=EI/OU=IT/CN=mail.volmed.org.ru/emailAddress=misk@volmed.org.ru -out ./ca/ca.crt

Где mail.volmed.org.ru адрес нашего почтового сервера

Запускаем скрипт make_ca.sh. Какое-то время он будет возиться с генерацией секретного ключа длиной в 4096 бит, на слабой машине это займет время... можете уменьшить длину ключа до 1024 или 2048 бит, если очень не терпится все поскорее попробовать. В итоге мы получим два файла в каталоге /etc/ssl/ca:
ca.crt - это наш самоподписанным доверенный сертификат, и
ca.key - его секретный ключ.
Правим файл /etc/httpd/conf/vhosts.d/abills_httpd.conf.
Добавляем строку. Было

Listen 9443
<VirtualHost _default_:9443>
DocumentRoot "/usr/abills/cgi-bin"

Стало

Listen 9443
<VirtualHost _default_:9443>
Alias /abills "/usr/abills/cgi-bin/"
DocumentRoot "/usr/abills/cgi-bin"

Было

   SSLCertificateFile /usr/abills/Certs/server.crt
   SSLCertificateKeyFile /usr/abills/Certs/server.key

Стало

   SSLCertificateFile /etc/ssl/ca/ca.crt
   SSLCertificateKeyFile /etc/ssl/ca/ca.key

И перезапускаем вебсервер

# /etc/init.d/httpd restart

Для доступа к web интерфейсу abills нужно открыть в фаерволе 9443 port и в строку адреса браузера набирать
https://host:9443/abills/admin

radiusclient

В мандивовском клиенте не хватает нескольких библиотек для работы. Я делал так выкачал с www.samba.org/ppp дистрибутив ppp-2.4.3.tar.gz. Распаковал в /usr/local/src

# ./configure
# make

Далее переписываем содержимое каталога /usr/local/src/ppp-2.4.3/pppd/plugins/radius/etc в каталог /etc/radiusclient/, кроме файла /etc/radiusclient/radiusclient.conf

Правим файл /etc/radiusclient/radiusclient.conf:

authserver      127.0.0.1
acctserver      127.0.0.1

В файл /etc/radiusclient/servers вносим IP адрес радиус-сервера и соответствующий ему пароль (см п.1)

127.0.0.1          radsecret

Шейпер

Здесь рассказывается как использовать атрибуты, передаваемые радиусом NAS’у на основе linux pppd. Это нужно для того, чтобы ограничивать пользователям скорость и выставлять фильтры. Последние версии pppd имеют в своем составе плагины для работы с radius-сервером. Убедитесь что в файле /etc/ppp/options.pptpd есть следующие строки:

 plugin radius.so
 plugin radattr.so

radius.so предназначен для аутентификации и аккаунтинга через радиус, а radattr.so принимает от радиуса дополнительные атрибуты и помещает их в файл /var/run/radattr.pppX , где pppX - имя интерфейса. Выглядит он примерно так:

MS-CHAP2-Success \207S=F17E6A6B06CD4B0C38F6....F35CD130BD7EBE
 MS-MPPE-Recv-Key \302\177\360\305\202I\362O....65\26\216#\336
 MS-MPPE-Send-Key \317Ab4\353\275R\24\331O\3....\236gr*\274$\233
 MS-MPPE-Encryption-Policy
 MS-MPPE-Encryption-Types
 Framed-IP-Address 192.168.144.226
 Filter-Id test_filter
 PPPD-Downstream-Speed-Limit 128
 PPPD-Upstream-Speed-Limit 128
 Octets-Direction Sum
 Session-Octets-Limit 106954752
 Framed-IP-Netmask 255.255.255.255
 MS-CHAP-MPPE-Keys p3\314wm\333B7@S/\024\370E\....\241'e\371K\303
 Acct-Interim-Interval 60
 Session-Timeout 29293

Этот файл удобно обрабатывать в скрипте /etc/ppp/ip-up.local, для этого добавляем в него следующие строки :

 if [ -f /var/run/radattr.$1 ]
   then
   DOWNSPEED=`/bin/awk  '/PPPD-Downstream-Speed-Limit/ {print $2}'  /var/run/radattr.$1`
   UPSPEED=`/bin/awk  '/PPPD-Upstream-Speed-Limit/ {print $2}'  /var/run/radattr.$1`
   FILTERS=`/bin/awk  '/Filter-Id/ {print $2}'  /var/run/radattr.$1`
 #echo $DOWNSPEED
 #echo $UPSPEED
 #echo $FILTERS
    /sbin/tc qdisc del dev $1 root    > /dev/null
    /sbin/tc qdisc del dev $1 ingress > /dev/null

 ##### speed server->client
   if [ "$UPSPEED" != "0" ] ;
   then
     /sbin/tc qdisc add dev $1 root handle 1: htb default 20 r2q 1
     /sbin/tc class add dev $1 parent 1: classid 1:1 htb rate ${UPSPEED}kbit burst 4k
     /sbin/tc class add dev $1 parent 1:1 classid 1:10 htb rate ${UPSPEED}kbit burst 4k prio 1
     /sbin/tc class add dev $1 parent 1:1 classid 1:20 htb rate ${UPSPEED}kbit burst 4k prio 2
     /sbin/tc qdisc add dev $1 parent 1:10 handle 10: sfq perturb 10 quantum 1500
     /sbin/tc qdisc add dev $1 parent 1:20 handle 20: sfq perturb 10 quantum 1500
     /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip tos 0x10 0xff flowid 1:10
     /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip protocol 1 0xff flowid 1:10
     /sbin/tc filter add dev $1 parent 1: protocol ip prio 10 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u160x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid 1:10
   fi 
 ##### speed client->server
   if [ "$DOWNSPEED" != "0" ] ;
   then
     /sbin/tc qdisc add dev $1 handle ffff: ingress
     /sbin/tc filter add dev $1 parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ${DOWNSPEED}kbit burst 12k drop flowid :1
   fi
 fi

Скорость можно выставлять индивидуально для каждого пользователя и в тарифном плане. При этом в тарифном плане можно установить разные upspeed и downspeed. Если установлена скорость в настройках пользователя, то скорость из тарифного плана игнорируется. Скорость выставляется в Kbit/s

Если у кого то не заработает (не будут отдаваться нужные параметры ), то скорее всего у вас старая версия Abills’а, обновитесь из CVS:

#!/bin/bash
cvs -d:pserver:anonymous@abills.cvs.sourceforge.net:/cvsroot/abills login
cvs -z3 -d:pserver:anonymous@abills.cvs.sourceforge.net:/cvsroot/abills checkout -r rel-0-3 abills

Я предполагаю, что вышеописанный шейпер далеко не идеален и можно было бы в нем что то улучшить.

Конфигурирование NAS

Теперь необходимо сконфигурировать NAS. Заходим в web-интерфейс администратора https://your.host:9433/abills/admin/
Логин - abills
пароль - abills
Идем: Система → Сервер доступа Создаем новый NAS с необходимыми параметрами.
В нашем случае:

IP 			127.0.0.1  
Название 		(произвольно, напр. - vpn1)
Radius NAS-Identifier 	Идентификатор сервера (можно не вписывать)
Опис	 		Описание сервера (Произв)
Type 			pppd:pppd + Radius plugin (linux)
Authorization 		SQL
Alive 			60 
Disable 		
IP:PORT 		
User
Password
RADIUS Parameters 	Acct-Interim-Interval=60

Значение Alive и значение параметра Acct-Interim-Interval нужно выбирать одинаковым. Осталось создать | тарифные планы и завести юзеров..

Проверяем
# radtest testuser testpassword 127.0.0.1:1812 0 radpasswd 0 127.0.0.1
testuser - имя пользователя из базы
testpassword - его пароль
radpasswd - пароль из файла /etc/radiusclient/servers
Если всё правильно настроено, в файле логов /usr/abills/var/log/abills.log должна появиться строка
2005-02-23 12:55:55 LOG_INFO: AUTH [testuser] NAS: 1 (xxx.xxx.xxx.xxx) GT: 0.03799

Если radius сервер на одной машине, а radius клиент на другой

Допустим, что
ip адрес машины радиус сервера 192.168.1.10
ip адрес машины радиус клиента 192.168.1.20
1. Правим файл /etc/raddb/users.conf

client 192.168.1.20  { 

2. Заходим в http://192.168.1.10/abills/admin
Далее Система ---> Сервер доступа
Выбираем нужный NAS сервер и меняем его IP адрес на 192.168.1.10
3. Проверка - из консоли мфшины 192.168.1.20 запускаем

radtest user passuser 192.168.1.10:1812 0 radpasswd 0 192.168.1.10

Где user и passuser - имя и пароль одного из пользователей abills.
radpasswd - пароль из файла /etc/raddb/users.conf

Добавляем статистику

abills/libexec/config.pl

$conf{s_detalization}='yes'; Более детальная статистика по сесиям
$conf{DV_LOG_CLEAN_PERIOD}=90 Время хранения логов детализации. Задаётся в днях.

В свободной версии нет подробной статистики по alive пакетам.
Для ее добавления делаем следующее (но без гарантии, что все правильно).
Редактируем файл /usr/abills/Abills/mysql/Acct.pm
Строка ~236 Вставляем строки
После

  elsif ($conf->{rt_billing}) {
    $self->rt_billing($RAD, $NAS);
   }

Вставляем

###################my#########################################
    $self->query($db, "SELECT acct_input_octets, acct_output_octets FROM dv_calls
    WHERE user_name='$RAD->{USER_NAME}' and acct_session_id='$RAD->{ACCT_SESSION_ID}';");
    my $a_ref1 = $self->{list}->[0];
       ($self->{INPUT33},
        $self->{OUTPUT33},
        )= @$a_ref1;

##################my########################################

Было. Строка ~264

#detalization for Exppp
if ($conf->{s_detalization} eq 'yes') {
   $RAD->{INTERIUM_INBYTE}=0 if (! defined($RAD->{INTERIUM_INBYTE}));
   $RAD->{INTERIUM_OUTBYTE}=0 if (! defined($RAD->{INTERIUM_OUTBYTE}));
   $RAD->{INTERIUM_INBYTE2}=0 if (! defined($RAD->{INTERIUM_INBYTE2}));
   $RAD->{INTERIUM_OUTBYTE2}=0 if (! defined($RAD->{INTERIUM_OUTBYTE2}));

Стало

#detalization for Exppp
if ($conf->{s_detalization} eq 'yes') {
###########################my###################################
   $self->{INPUT33}=0 if (! defined($self->{INPUT33}));
   $self->{OUTPUT33}=0 if (! defined($self->{OUTPUT33}));
    $RAD->{INBYTE}=0 if (! defined($RAD->{INBYTE}));
    $RAD->{OUTBYTE}=0 if (! defined($RAD->{OUTBYTE}));

    $RAD->{INTERIUM_INBYTE}=$RAD->{INBYTE} - $self->{INPUT33};
    $RAD->{INTERIUM_OUTBYTE} = $RAD->{OUTBYTE} - $self->{OUTPUT33};
############################my###################################

    $RAD->{INTERIUM_INBYTE2}=0 if (! defined($RAD->{INTERIUM_INBYTE2}));
    $RAD->{INTERIUM_OUTBYTE2}=0 if (! defined($RAD->{INTERIUM_OUTBYTE2}));

Как перевести web интерфейс с кодировки cp1251 на utf8

Не удобно, когда файлы хранятся, в отличной от основной кодировке. Я тут опишу, как перевести интерфейс abills в кодировку utf8. База данных при этом остается в cp1251, что вобщем и не важно.
1. Правим файл /usr/abils/libexec/config.pl

#For MySQL 5 and highter 
$conf{dbcharset}='utf8';
$conf{MAIL_CHARSET}='utf8'; 
$conf{default_language}='russian'; 
$conf{default_charset}='utf-8';

2. Файл /usr/abills/Abills/XML.pm строка ~577

my $CHARSET=(defined($attr->{CHARSET})) ? $attr->{CHARSET} : 'utf-8';

3. Файл /usr/abills/Abills/defs.conf строка ~38

$lang_charset='utf-8';

4. Файл /usr/abills/Abills/HTML.pm сторока ~98

$self->{CHARSET}=(defined($attr->{CHARSET})) ? $attr->{CHARSET} : 'utf-8';

5. Спомощью команды iconv перекодируем файлы в директории /usr/abils/language/. Например, для файла russian.pl

iconv -fcp1251 -tutf8 russian.pl -orussian.pl1 
mv russian.pl1 russian.pl

И поменять в них $CHARSET=" windows-1251" на $CHARSET=" utf8", хотя работает и без этого.

Ну вот вроде и все.

Настройка подключения к Totol Control

Totol Control - это такая железяка в которую входят 16 модемов и система управления ими со своей ОС. К ней можно подключиться через сом кабкль эмулятором терминала VT100, а после установок сети и telnet оп сети. Пишу сдесь настройки, которые я делал, что бы не забыть потом.

Настройка сервера доступа

  • Система ---> Сервер доступа
IP IP адрес Totol Control
Название Название сервера (например NAS)
Тип Usr:USR Netserver 8/16
Авторизация SQL
Alive (sec) Обязательно 0
IP:PORT Адрес и порт SNMP Total Сontrol (порт обычно 161), но его можно не ставить
Пароль Пароль для доступа SNMP к Total Сontrol

Остальные настройки теже.

Изменения в коде программы

Правим пути к командам в файле /usr/abills/Abills/defs.conf для команд snmpwalk, bzip, mysqldump, ifconfig
Пути можно найти с помощью команды which, например

# which snmpwalk
/usr/bin/snmpwalk

Все изменения в файле /usr/abills/Abills/nas.pl
Вместо строк

 elsif ($nas_type eq 'usr') {
   hangup_snmp($NAS, $PORT, { OID   => '.1.3.6.1.4.1.429.4.10.13.'. $PORT,
                                 TYPE  => 'integer',
                                 VALUE => 9 });

Вставить

 elsif ($nas_type eq 'usr') {
   hangup_usr($NAS, $PORT, $attr);
  }

Вместо строк

#####################################################################
# USR Netserver 8/16
#*******************************************************************
# Get stats from USR Netserver 8/16
# get_usrns_stats($SERVER, $PORT)
#*******************************************************************
sub stats_usrns  {
  my ($NAS, $PORT) = @_;
  my $SNMP_COM = $NAS->{NAS_MNG_PASSWORD} || '';

#USR trafic taker
  my $in  = `a=\`$SNMPWALK -v 1 -c "$SNMP_COM" $NAS->{NAS_IP} interfaces.ifTable.ifEntry.ifInOctets.$PORT  | awk '{print \$4}'\`; b=\`cat /usr/abills/var/devices/$NAS->{NAS_IP}-$PORT.In\`; c=\`expr \$a - \$b + 0\`; echo \$c`;
  my $out = `a=\`$SNMPWALK -v 1 -c "$SNMP_COM" $NAS->{NAS_IP} interfaces.ifTable.ifEntry.ifOutOctets.$PORT  | awk '{print \$4}'\`; b=\`cat /usr/abills/var/devices/$NAS->{NAS_IP}-$PORT.Out\`; c=\`expr \$a - \$b + 0\`; echo \$c`;
# $SNMPWALK -v 1 -c $SNMP_COM $SERVER interfaces.ifTable.ifEntry.ifInOctets.$PORT | awk '{print \$4}' `a=`$SNMPWALK -v 1 -c tstats 192.168.101.130 interfaces.ifTable.ifEntry.ifInOctets.$PORT | awk '{print \$4}'`; b=`cat /usr/abills/var/devices/$SERVER-$PORT.In`; c=`expr \$a - \$b + 0`; echo \$c`;
#
  $stats{in} = int($in);
  $stats{out} = int($out);

  return %stats;
}

Вставляем

#*******************************************************************
# HANGUP USR
# hangup_usr($SERVER, $PORT)
#*******************************************************************
sub hangup_usr {
    my ($NAS_IP, $PORT) = @_;
    $telnet_user = "!root";
    $telnet_pass = "passwd_telnet";
    push @commands, "login:\t$telnet_user";
    push @commands, "Password:\t$telnet_pass";
    push @commands, ">\treset S$PORT";
    push @commands, ">exit";

    my $result = telnet_cmd("$NAS->{NAS_IP}", \@commands);
    print $result;

    return 0;
      }


#####################################################################
# USR Netserver 8/16
#*******************************************************************
# Get stats from USR Netserver 8/16
# get_usrns_stats($SERVER, $PORT)
#*******************************************************************
sub stats_usrns  {
    my ($NAS, $PORT) = @_;
    my $SNMP_COM = $NAS->{NAS_MNG_PASSWORD} || '';
    #print  "Port =  $PORT\n";
    $PORT1 = $PORT + 2;
    #USR trafic taker

    my $in  = `a=\`$SNMPWALK -v 1 -c "$SNMP_COM" $NAS->{NAS_IP} interfaces.ifTable.ifEntry.ifInOctets.$PORT1 |awk 'print \$4}'\`;  echo \$a`;
    my $out = `a=\`$SNMPWALK -v 1 -c "$SNMP_COM" $NAS->{NAS_IP} interfaces.ifTable.ifEntry.ifOutOctets.$PORT1  |awk '{print \$4}'\`; echo \$a`;
    $stats{in}  = $in;
    $stats{out} = $out;
    $stats{error} = 0;
     if ( $in eq "\n" ) {
          if ( $out eq "\n" ){
            $stats{error} = 1;
            }
      }
        #elsif (int($in) + int($out) > 0) {
        #$stats{in}  = int($in);
        #$stats{out} = int($out);
        #       }

#print "$in\n$out\n";

    return %stats;
}

}

где passwd_telnet - пароль доступа по telnet

Файл /usr/abills/libexec/billd Была строка ~ 194

       elsif (defined($external_stats->{error})) {
        print "Error:  Login: $line->[0], NAS-IP: $NAS{NAS_IP}, Port: $line->[2], Session-ID: $acct_session_id\n" if ($debug == 1);
        $sessions->online_update({ USER_NAME       => $line->[0],
                                         ACCT_SESSION_ID => $acct_session_id,
                                         STATUS          => 5
                                      });
       }
      elsif (defined($external_stats->{in})) {
        $sessions->online_update({ USER_NAME => $line->[0], ACCT_SESSION_ID => $acct_session_id, %$external_stats });
       }

Стало

       elsif (($external_stats->{error}) == 1 ) {
        print "Error:  Login: $line->[0], NAS-IP: $NAS{NAS_IP}, Port: $line->[2], Session-ID: $acct_session_id\
n" if ($debug == 1);
        # Если и в предыдущий раз была ошибка, то убиваем сессию
            if ( $line->[18] == 5 )  {
                print "Kill session $line->[0]\nTime session $line->[9]\n ";
                print "Input traf  $acct_input_octets\nOutput traf $acct_output_octets\n";
                    my $ACCT_INFO = $sessions->online_info({ NAS_ID          => $nas_row->[0],
                                                    NAS_PORT        => $line->[2],
                                                    ACCT_SESSION_ID => $acct_session_id
                                                  });


                    $ACCT_INFO->{INBYTE}            = $acct_input_octets;
                    $ACCT_INFO->{OUTBYTE}           = $acct_output_octets;
                    $ACCT_INFO->{INBYTE2}           = $acct_input_octets_ext;
                    $ACCT_INFO->{OUTBYTE2}          = $acct_output_octets_ext;
                    $ACCT_INFO->{ACCT_STATUS_TYPE}  = 'Stop';
                    $ACCT_INFO->{ACCT_SESSION_TIME} = $line->[9];
                    $ACCT_INFO->{ACCT_TERMINATE_CAUSE} = 15;

                    my $r = $Acct->accounting($ACCT_INFO, \%NAS);
                    my $info = ;

             }
            # Устанавливаем статус ошибки (5) и пишем его в базу.
            else    {
        #       print "Error session $line->[0]\n";
                $sessions->online_update({ USER_NAME       => $line->[0],
                                 ACCT_SESSION_ID => $acct_session_id,
                                 STATUS          => 5
                                  })
                                  };


       }
      elsif (defined($external_stats->{in})) {
        $sessions->online_update({ USER_NAME => $line->[0],
                                ACCT_SESSION_ID => $acct_session_id,
                                STATUS          => 1,
                                %$external_stats
                                });