Настройка dial-in сервера под Red Hat linux (dial-in redhat linux ppp billing statistic limit mgetty mysql)
Ключевые слова: dial-in, redhat, linux, ppp, billing, statistic, limit, mgetty, mysql, (найти похожие документы)
From: Igor Chumak <igoor(собак)mail.ru>
Date: Mon, 24 Jul 2004 18:21:07 +0000 (UTC)
Subject: Настройка dial-in сервера под Red Hat linux
Оригинал: http://212.26.129.139:8080/other/linux/dial_in.htm
Настройка dial-in сервера под Red Hat linux
После того, как я настроил pppd для доступа извне офиса к локальной
сети и интернет, мне захотелось большего:
* ограничить время работы удалённых юзеров (ибо их много, а
модемов мало)
* разграничить доступ к ресурсам сети (кого-то пускать везде,
кого-то только к прокси-серверу..)
Итак, чем я пользовался:
* mgetty 1.1.28-9
* ppp 2.4.1-3
* mysql 3.23.49-3
* mysql-server-3.23.49-3
Разграничение доступа к сети firewall'ом
1. Скрипт для создания dial-in юзеров выглядит так:
------------------------------------------
#!/bin/sh
name=$1
if [ -z $name ]
then
echo Username??
exit
fi
if [ $name == " *"]
then
echo Username??
exit
fi
echo Add user \"$name\"
cmd="/usr/sbin/useradd -c \"Dial-in 2 $name\" -d /dev/null -g dial-in-users -M -s /bin/false $name"
echo $cmd
/usr/sbin/useradd -c "Dial-in 2 $name" -d /dev/null -g dial-in-users -M -s /bin/false $name
if [ $? -eq 0 ]
then
echo Add pap-secrets entry..
echo $name $HOSTNAME \"\" \* >> /etc/ppp/pap-secrets
addscript="INSERT INTO users VALUES ( '$name', '3600');"
echo Add time-limit..
mysql -B -s -h localhost -e "$addscript" dial_in
echo Set passwd user \"$name\"
passwd $name
fi
------------------------------------------
Группа dial-in-users должна существовать!
2. /etc/ppp/ip-up.local
При подъёме ppp+ интерфейса выполняется настройка firewall и
дополнительная проверка:
------------------------------------------
#!/bin/sh
pppPID=`cat /var/run/$IFNAME.pid`
dialindir="/etc/ppp/dial-in"
. $dialindir/firewall $PEERNAME $IFNAME
. $dialindir/ip-up-script $PEERNAME $IFNAME $pppPID
------------------------------------------
3. /etc/ppp/dial-in/firewall
Подразумевается, что firewall наш на базе iptables, и что последнее
правило в цепочках INPUT и FORWARD (policy DROP) изменению не подлежит
(у меня там LOG).
LAN_IP - IP-адрес, к которому даём полный доступ
WINS1,WINS2 - WINS-сервера в локальной сети
------------------------------------------
#!/bin/sh
mydirname="/etc/ppp/dial-in"
# Setup firewall rulezz 2 new PPP link
PEERNAME=$1
IFNAME=$2
export IFNAME
LAN_IP=192.168.10.202
WINS1=192.168.10.200
WINS2=192.168.10.201
# Сначала грохнем старые правила
# Наоборот сортированный список N правил, которые надобно грохнуть
inp=`iptables -L INPUT -n -v --line-number|grep $IFNAME|awk '{print $1}'|sort -n -r`
for i in $inp
do
echo $i
iptables -D INPUT $i
done
inp=`iptables -L FORWARD -n -v --line-number|grep $IFNAME|awk '{print $1}'|sort -n -r`
for i in $inp
do
echo $i
iptables -D FORWARD $i
done
lastINPUTrule=`iptables -L INPUT -n -v --line-number|awk '{print $1}'|sort -n -r|head -1`
lastFORWARDrule=`iptables -L FORWARD -n -v --line-number|awk '{print $1}'|sort -n -r|head -1`
# Теперь зададим новые
# INPUT
iptables -I INPUT $lastINPUTrule -p ALL -i $IFNAME -d $LAN_IP -j ACCEPT
#FORWARD
# wins access 2 all
iptables -I FORWARD $lastFORWARDrule -p tcp -i $IFNAME -d $WINS1 --dport wins -j ACCEPT
iptables -I FORWARD $lastFORWARDrule -p udp -i $IFNAME -d $WINS1 --dport wins -j ACCEPT
iptables -I FORWARD $lastFORWARDrule -p tcp -i $IFNAME -d $WINS2 --dport wins -j ACCEPT
iptables -I FORWARD $lastFORWARDrule -p udp -i $IFNAME -d $WINS2 --dport wins -j ACCEPT
#mydirname=`dirname $0`
#echo $mydirname/$PEERNAME>>/var/log/ppp.log
if [ -f $mydirname/$PEERNAME ]
then
. $mydirname/$PEERNAME $lastFORWARDrule $IFNAME
fi
------------------------------------------
Для юзеров с более хитрыми правами на сеть вызываются скрипты с доп.
правилами:
/etc/ppp/dial-in/USERNAME:
------------------------------------------
# $lastFORWARDrule $IFNAME
# Правила для юзера super
iptables -I FORWARD $1 -p tcp -i $2 -d 192.168.10.11 -j ACCEPT
------------------------------------------
Ограничение времени работы юзера
Суммарная продолжительность всех сеансов связи за сутки не должна
превышать заданного нами лимита.
1. Создаём базу dial_in со следующими таблицами:
------------------------------------------
# phpMyAdmin MySQL-Dump
# http://phpwizard.net/phpMyAdmin/
#
# Host: localhost Database : dial_in
# --------------------------------------------------------
#
# Table structure for table 'current_sessions'
#
CREATE TABLE current_sessions (
id bigint(10) NOT NULL auto_increment,
peername varchar(20) NOT NULL,
linkname varchar(10) NOT NULL,
pppd_pid int(8) DEFAULT '0' NOT NULL,
start_time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
start_time_utc bigint(16) DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
UNIQUE id (id)
);
# --------------------------------------------------------
#
# Table structure for table 'done_sessions'
#
CREATE TABLE done_sessions (
id bigint(14) NOT NULL auto_increment,
peername varchar(20) NOT NULL,
start_time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
start_time_utc bigint(16) DEFAULT '0' NOT NULL,
length_session int(6) DEFAULT '0' NOT NULL,
PRIMARY KEY (id),
UNIQUE id (id),
KEY id_2 (id)
);
# --------------------------------------------------------
#
# Table structure for table 'users'
#
CREATE TABLE users (
peername varchar(20) NOT NULL,
timelimit int(8) DEFAULT '3600' NOT NULL,
PRIMARY KEY (peername),
UNIQUE peername (peername),
KEY peername_2 (peername)
);
------------------------------------------
2. /etc/ppp/dial-in/ip-up-script
Запоминает в таблице current_sessions начало сеанса связи
------------------------------------------
#!/bin/sh
mydirname="/etc/ppp/dial-in"
peername=$1
linkname=$2
ppp_pid=$3
now=`date +%Y:%m:%d\ %T`
now_utc=`date +%s`
script1="delete from current_sessions where peername=\"$peername\" and linkname=\"$linkname\""
script2="insert into current_sessions
(peername,linkname,pppd_pid,start_time,start_time_utc) values
(\"$peername\",\"$linkname\",\"$ppp_pid\",\"$now\",\"$now_utc\")"
#mysql_user=" -u nobody "
mysql -B -s -h localhost $mysql_user -e "$script1" dial_in
mysql -B -s -h localhost $mysql_user -e "$script2" dial_in
. $mydirname/test-of-limit $peername $ppp_p
------------------------------------------
3. /etc/ppp/dial-in/test-of-limit
Проверяет, не превышен ли дневной лимит. При превышении рвёт связь и
шлёт письмо на root
------------------------------------------
#!/bin/sh
# Test user $1 for owerquoting && disconnect
peername=$1
ppp_pid=$2
#mysql_user=" -u nobody "
script1="select sum(length_session) from done_sessions where peername=\"$peername\""
script2="select min(start_time_utc) from current_sessions where peername=\"$peername\""
t1=`mysql -B -s -h localhost $mysql_user -e "$script1" dial_in`
t2=`mysql -B -s -h localhost $mysql_user -e "$script2" dial_in`
if [ $t2 != "NULL" ]
then
t3=`date +%s`
itogo=$(($t1-$t2+$t3))
else
itogo=$t1
fi
# echo $itogo $t1 $t2 $t3
script3="select min(timelimit) from users where
peername=\"$peername\""
limit=`mysql -B -s -h localhost $mysql_user -e "$script3" dial_in`
if [ $limit != "NULL" ]
then
if [ $limit -lt $itogo ]
then
echo `date +%c` $peername $limit -lt $itogo | mail root -s "Overtime on PPP"
kill $ppp_pid
fi
fi
------------------------------------------
4. /etc/ppp/dial-in/ip-down-script
При окончании сеанса связи пересчитывает суточный баланс юзера
------------------------------------------
#!/bin/sh
#echo $0 $*>>/var/log/ppp-script
peername=$1
linkname=$2
#ppp_pid=$3
length_session=$3
#mysql_user=" -u nobody "
script1="select \"$peername\",\"$length_session\",min(start_time_utc)
from current_sessions where peername=\"$peername\" and linkname=\"$linkname\""
script2="insert into done_sessions (peername,length_session,start_time_utc) $script1"
mysql -B -s -h localhost $mysql_user -e "$script2" dial_in
script3="delete from current_sessions where peername=\"$peername\" and
linkname=\"$linkname\""
mysql -B -s -h localhost $mysql_user -e "$script3" dial_in
------------------------------------------
5. /etc/ppp/dial-in/ppp.cron-10min
Через каждые 5-10 мин вызываем из cron'а, проверяем уже подключенных
юзеров.
------------------------------------------
#!/bin/sh
#peername=$1
#ppp_pid=$2
mydirname="/etc/ppp/dial-in"
#mysql_user=" -u nobody "
script1="select distinct CONCAT_WS(\":\",peername,pppd_pid) from current_sessions"
peer_list=`mysql -B -s -h localhost $mysql_user -e "$script1" dial_in`
for ii in $peer_list
do
# echo $ii
pdd=`expr index $ii :`
# echo $pdd
ppp_pid=${ii:pdd}
username=${ii:0:$((pdd-1))}
# echo $ppp_pid $username
. $mydirname/test-of-limit $username $ppp_pid
done
------------------------------------------
6. /etc/ppp/dial-in/ppp.cron-zero
Обнуляем статистику раз в сутки, отправляем отчет по почте
------------------------------------------
#!/bin/sh
#peername=$1
#ppp_pid=$2
#mysql_user=" -u nobody "
script2="delete from done_sessions"
now=`date +%s`
script1="update current_sessions set start_time_utc=$now"
. /etc/ppp/dial-in/statistika|mail root -s "PPP dayly statystic"
mysql -B -s -h localhost $mysql_user -e "$script1" dial_in
mysql -B -s -h localhost $mysql_user -e "$script2" dial_in
------------------------------------------
/etc/ppp/dial-in/statistika
------------------------------------------
#!/bin/sh
#mysql_user=" -u nobody "
script1="select * from current_sessions"
#script2="select * from done_sessions"
script2="select peername,count(id),sum(length_session) from done_sessions group by peername"
echo Current sessions
mysql -B -h localhost $mysql_user -e "$script1" dial_in
echo Done sessions
mysql -B -h localhost $mysql_user -e "$script2" dial_in
------------------------------------------
Доступ к базе либо от root (дополнительных настроек не потребуется),
либо от простого юзера (раскомментируем строчки с mysql_user,
настраиваем права доступа)
Всем скриптам дать chmod 755 !
Используемые статьи:
* Настройка PPP dial-in сервера (PAP аутентификация)
http://212.26.129.139/howto/PPP-dial-in.htm
* Iptables Tutorial 1.1.9
http://212.26.129.139/howto/iptables/Iptables%20Tutorial%201_1_9.htm
* Advanced Bash-Scripting Guide
http://212.26.129.139/howto/abs-guide/HTML/