Скрипты ip-up и ip-down с ipset для Accel-ppp

Приведу пример скриптов которые я раньше использовал, в список allowip добавлялись IP адреса которым разрешен интернет, а в denyip которые переадресовывались на http страницу с информацией о негативном депозите.

Скрипт ip-up:

#!/bin/sh
# ip-up
IFNAME=$1
IP=$5
AWK=/usr/bin/awk
DEBUG=0

if [ -f /var/run/radattr.$IFNAME ]; then
  FILTERS=`${AWK}  '/Filter-Id/ {print $2}'  /var/run/radattr.${IFNAME}`
fi;

if [ w${FILTERS} = wNEG_DEPOSIT ] ; then
   /sbin/ipset add denyip $IP -exist
  if [ w${DEBUG} != w ] ; then
    echo "$(date '+%Y/%m/%d %H:%M') --- UP neg filter User: ${USER_NAME} Filter: ${FILTERS} IF: ${IFNAME} IP: $IP" >> /tmp/neg
  fi;
  exit;

else
  if [ "${DEBUG}" != "" ] ; then
    echo "$(date '+%Y/%m/%d %H:%M') --- UP User: ${USER_NAME} Filter: ${FILTERS} IF: ${IFNAME} IP: $IP" >> /tmp/allow
  fi;

  /sbin/ipset add allowip $IP -exist
fi;

Скрипт ip-down:

#!/bin/sh
# ip-down
IFNAME=$1
IP=$5
AWK=/usr/bin/awk
DEBUG=0

if [ -f /var/run/radattr.$IFNAME ]; then
   FILTERS=`${AWK}  '/Filter-Id/ {print $2}'  /var/run/radattr.$IFNAME`
   USER_NAME=`${AWK}  '/User-Name/ {print $2}'  /var/run/radattr.${IFNAME}`
fi;

# Filters
if [ w${FILTERS} = wNEG_DEPOSIT ] ; then
    /sbin/ipset del denyip $IP -exist
   if [ w${DEBUG} != w ] ; then
     echo "$(date '+%Y/%m/%d %H:%M') --- Down neg filter User: ${USER_NAME} Filter: ${FILTERS} IF: ${IFNAME} IP: $IP" >> /tmp/neg
   fi;
   exit;
else
  if [ "${DEBUG}" != "" ] ; then
    echo "$(date '+%Y/%m/%d %H:%M') --- DOWN User: ${USER_NAME} Filter: ${FILTERS} IF: ${IFNAME} IP: $IP" >> /tmp/allow
  fi;

  /sbin/ipset del allowip $IP -exist
fi;

Соответственно должны быть созданы списки:

/sbin/ipset -N allowip iphash
/sbin/ipset -N denyip iphash

И iptables правила.
Разрешаем FORWARD для allowip:

/sbin/iptables -A FORWARD -m set --match-set allowip src -j ACCEPT
/sbin/iptables -A FORWARD -m set --match-set allowip dst -j ACCEPT

NAT:

/sbin/iptables -t nat -I POSTROUTING -s 10.0.0.0/24 -j SNAT --to-source 11.11.11.1 --persistent

Для denyip настраиваем переадресацию всех http запросов, разрешаем FORWARD к странице на которую выполняется переадресация и запрещаем FORWARD по умолчанию для всего остального:

/sbin/iptables -t nat -A PREROUTING -p tcp -m multiport --dport 80 -m set --match-set denyip src -j DNAT --to-destination 11.11.11.1:80
/sbin/iptables -A FORWARD -s 11.11.11.1 -j ACCEPT
/sbin/iptables -A FORWARD -d 11.11.11.1 -j ACCEPT
/sbin/iptables -P FORWARD DROP

Перед ipset командой можно также добавить проверку на существование списка, но чем проще скрипты, тем лучше производительность:

allownet=`/sbin/ipset -L |grep allowip |sed 's/ //'|awk -F: '{ print $2 }'`
if [ "${allownet}" = "" ]; then
/sbin/ipset -N allowip iphash
fi;

Замечу что при дублирующихся сессиях, будут пропадать IP из списков, так как в списке не может быть одинаковых адресов, а если например есть две дублирующиеся сессии и одна из них завершается, то соответственно и IP будет уделен из списка, соответственно если вторая сессия останется онлайн, то уже без IP в списке.
Поэтому можно отказаться от ipset allowip настроив ip-unnumbered, а в ipset denyip добавлять адреса через L4-redirect и вовсе отказаться от этих скриптов, ну и решить проблему с дублирующимися IP если она есть.

Смотрите также мои статьи:
Скрипт добавления IP адресов из файла в ipset
Сборка и установка accel-ppp

Скрипт добавления IP адресов из файла в ipset

Понадобилось однажды написать скрипт чтобы добавить в ipset все IP для которых били подняты сессии на сервере доступа, использовался биллинг Abills, поэтому я решил взять IP адреса из MySQL таблицы биллинга.

Первым делом создадим тестовый ipset:

ipset create test iphash

Создадим файл скрипта:

nano iplist.sh

Добавим в него содержимое:

mysql -u root -e "SELECT INET_NTOA(framed_ip_address) FROM abills.internet_online WHERE (status=1 or status>=3) AND guest=0;" -s -N > iplist.txt
iplist_data=$(cat iplist.txt)
for row_data in $iplist_data; do ipset -exist add test ${row_data}; done
rm iplist.txt

Выполняем скрипт и проверяем:

chmod +x iplist.sh
./iplist.sh
ipset list test | wc -l
ipset -L

Смотрите также мою статью — Скрипты ip-up и ip-down с ipset для Accel-ppp