Итак пишу что и как делал.
Во-первых хотел извиниться за то, что долго не отвечал - просто не было времени.
Во-вторых, сразу оговорюсь, что "биллинговой системой" я по незнанию называл любой способ подсчета трафика по каждому пользователю сети индивидуально. У меня стояла задача сделать шлюз для рабочей сетки в офисе на 100 компьютеров максимум, чтобы по каждому пользователю/компьютеру можно было посчитать трафик, посмотреть посещенные страницы, заблокировать/разблокировать доступ к каким-либо ресурсам в инете или вообще отключить инет. Как это будет работать при других условиях - сказать не могу.
Итак задача стояла такая:
1. Исходные данные:
1.1 Есть внутренняя офисная сеть - 192.168.0.0/24 каждому компьютеру в сети задан статический IP адрес.
1.2 Есть внешняя сеть с инетом - 195.210.ххх.ууу - отдельный кабель от провайдера до шлюза.
1.3 Есть внешний сервер, стоящий у совсем других людей на адресе 89.249.ххх.ууу - там почта и ftp.
1.4 Есть некоторое количество банк-клиентов работающих внутри сети, которым нужен доступ к соответствующим узлам в инете.
2. Задача:
2.1 Сделать сеть недоступной из инета.
2.2 Сделать инет доступным из сети.
2.3 Авторизовать каким либо образом каждого пользователя на шлюзе и считать по нему трафик. Если трафик превышает лимит - отключить пользователя. Если у пользователя нет права пользоваться инетом - сделать невозможным его самовольное подключение.
2.4 Фильтровать содержимое запрашиваемых пользователем ресурсов в соответствии с правами пользователя на просмотр.
2.5 Обеспечить постоянную неблокируемую работу банк-клиентов.
2.6 Обеспечить постоянную неблокируемую работу корпоративной почты и ftp (т.е. только через наш внешний сервер).
3. Исполнение:
Часть 1. IPTABLES.
Я взял за основу приложенный к учебнику по iptables скрипт rc.firewall.txt и немного поправил его для своих нужд:
#!/bin/sh
#
# 1. Конфигурация.
#
# Здесь задаются основные настройки брандмауэра, которые зависят от Вашей конфигурации сети.
#
############################################################################
# 1.1 Настройки интернет.
#
# INET_IP - Здесь должен быть указан реальный IP адрес, выданный провайдером услуг доступа в интернет.
# INET_IFACE - устройство, через которое осуществляется подключение к интернет.
# INET_BROADCAST - широковещательный адрес.
#
INET_IP="195.210.XXX.YYY"
INET_IFACE="eth0"
INET_BROADCAST="195.210.XXX.255"
############################################################################
# 1.2 Настройки локальной сети.
#
# Конфигурация локальной сети.
# LAN_IP - локальный IP адрес брандмауэра.
# LAN_IP_RANGE - широковещательный адрес + маска подсети.
# LAN_IFACE - интерфейс, подключенный к локальной сети.
#
LAN_IP="192.168.0.1"
LAN_IP_RANGE="192.168.0.0/24"
LAN_IFACE="eth1"
############################################################################
# 1.4 Локальный интерфейс "loopback".
#
LO_IFACE="lo"
LO_IP="127.0.0.1"
############################################################################
############################################################################
#
# 1.5 Путь к файлу iptables (обычно "/usr/sbin/iptables" или "/sbin/iptables").
#
IPTABLES="/sbin/iptables"
# Очистка...
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -t mangle -F
$IPTABLES -X
$IPTABLES -t nat -X
$IPTABLES -t mangle -X
#
# 1.6 Дополнительно.
#
# Описываем порты, которые нам могут пригодиться.
# Настраиваем систему таким образом, что
# 1. Пакеты на почту и другие разрешенные сервера мы просто пропускаем насквозь.
# 2. Пакеты, идущие по защищенному соединению (https) мы пропускаем, но подсчитываем
# отдельно, не разбивая на пользователей.
# 3. Всех пользователей мы проверяем на предмет соответствия их IP адресов их MAC адресам.
# 4. Остальные пакеты - перенаправляем на squid.
# 5. И наконец - считаем вообще весь трафик, проходящий через фаервол.
# Порт для HTTPS
HTTPS="443"
# Порт squid.
SQUID="3128"
# Далее порты, которые будем заворачивать на squid
SQV_HTTP="80"
SQV_FTP="21"
# Описываем адреса, которые нам могут пригодиться.
# Тут будут те адреса, до которых доступ будет всегда и у всех,
# независимо от того, можно им в инет, или нет.
#Почта.
IP_MAIL="89.249.XXX.YYY" # Почта 1
IP_MAIL1="62.113.XXX.YYY" # Почта 2
# Порт почты SMTP
MAIL_SMTP="25"
# Порт почты POP
MAIL_POP="110"
# FTP сервер для передачи данных в филиалы - работает у всех.
IP_HICFTP="89.249.XXX.YYY"
# Банк-клиенты.
IP_BANK_1="XXX.YYY.QQQ.ZZZ"
IP_BANK_2="XXX.YYY.QQQ.ZZZ"
IP_BANK_3_1="XXX.YYY.QQQ.ZZZ"
IP_BANK_3_2="XXX.YYY.QQQ.ZZZ"
# Пользователи.
# Пользователь №1
USER_1_IP="192.168.0.2"
USER_1_MAC="00:00:00:00:00:01"
# ............
# Пользователь № N
USER_N_IP="192.168.0.254"
USER_N_MAC="00:00:00:00:00:02"
###########################################################################
#
# 2. Подгрузка модулей.
#
#
# Проверка зависимостей модулей.
#
#/sbin/depmod -a
#
# 2.1 Подгрузка необходимых модулей (нужное раскомментировать).
#
#/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
#/sbin/modprobe iptable_filter
#/sbin/modprobe iptable_mangle
#/sbin/modprobe iptable_nat
#/sbin/modprobe ipt_LOG
#/sbin/modprobe ipt_limit
#/sbin/modprobe ipt_state
#/sbin/modprobe ipt_owner
#/sbin/modprobe ipt_REJECT
#/sbin/modprobe ipt_MASQUERADE
/sbin/modprobe ip_conntrack_ftp
#/sbin/modprobe ip_conntrack_irc
/sbin/modprobe ip_nat_ftp
#/sbin/modprobe ip_nat_irc
# 4. Настройка правил.
#
#
# 4.1 Таблица Filter
#
#
# 4.1.1 Политики по умолчанию
#
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP
#
# 4.1.2 Создание пользовательских цепочек
#
#
# Создание цепочки для "плохих" пакетов
#
$IPTABLES -N bad_tcp_packets
#
# Создание отдельных цепочек для различных протоколов
#
$IPTABLES -N allowed
$IPTABLES -N tcp_packets
$IPTABLES -N udp_packets
$IPTABLES -N icmp_packets
#
# Создние цепочки, которая будет сверять IP и MAC адреса.
#
$IPTABLES -N verify
#
# Создание цепочек для подсчета трафика
#
# Для общего трафика
$IPTABLES -N trafficcount
# Для https
$IPTABLES -N secured
#
# 4.1.3 Содержимое пользовательских цепочек
#
#
# Цепочка bad_tcp_packets
#
# Отфильтровываются все пакеты, которые распознаются как NEW, но не
# являются SYN пакетами, а также обрабатываются SYN/ACK пакеты,
# имеющие статус NEW.
# Эта цепочка может быть использована для защиты от вторжения
# и сканирования портов.
#
$IPTABLES -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
-m state --state NEW -j REJECT --reject-with tcp-reset
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
--log-prefix "New not syn:"
$IPTABLES -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
#
# Цепочка allowed
#
# Дополнительная проверка.
# По задумке цепочка вызывается из цепочки tcp_packets, на прошедшие
# проверку пакеты.
# Проверяем, является ли пакет SYN пакетом, т.е. запросом на соединение.
$IPTABLES -A allowed -p TCP --syn -j ACCEPT
# Пропускаем все пакеты с признаком ESTABLISHED и RELATED.
$IPTABLES -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
# Сбрасываем все остальные пакеты.
$IPTABLES -A allowed -p TCP -j DROP
#
# Цепочка tcp_packets
#
# По идее рулит входящими tcp пакетами из инета.
# Но поскольку у нас нет никаких инет-сервисов в локалке
# мы просто перекидываем все пакеты в allowed.
$IPTABLES -A tcp_packets -j allowed
#
# Правила для UDP.
#
#
# В сетях Microsoft Вас может завалить бродкастами.
# Правило блокирует широковещательные пакеты, поступающие на порты
# со 135 по 139. Эти порты используются протоколами SMB и NetBIOS.
# Данное правило предотвращает переполнение таблицы трассировщика в
# сетях Microsoft.
#
$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d $INET_BROADCAST \
--destination-port 135:139 -j DROP
#
# Это правило блокирует DHCP запросы извне.
#
$IPTABLES -A udp_packets -p UDP -i $INET_IFACE -d 255.255.255.255 \
--destination-port 67:68 -j DROP
#
# Правила для ICMP.
# Тут проверяется тип ICMP сообщения. Пропускаются только
# ICMP Echo Request, TTL equals 0 during transit и
# TTL equals 0 during reassembly. Все остальные типы ICMP
# сообщений должны проходить и так, т.к. имеют состояние RELATED.
#
#
# Чтобы брандмауэр перестал откликаться на ping -
# закомментируйте эту строчку.
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
$IPTABLES -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
#
# Цепочка для подсчета трафика.
#
$IPTABLES -A trafficcount -p ALL -j RETURN
#
# Цепочка подсчета HTTPS трафика.
#
$IPTABLES -A secured -p tcp --dport $HTTPS -j RETURN
#
# Цепочка верификации IP адреса и MAC адреса пользователя.
#
# Тут поочередно всех проверяем на соответствие - если кто-то себе подставил
# чужой IP - его тупа сбросит.
$IPTABLES -A verify -p ALL -s $USER_1_IP -m mac --mac-source $USER_1_MAC -j RETURN
# .....................
$IPTABLES -A verify -p ALL -s $USER_N_IP -m mac --mac-source $USER_N_MAC -j RETURN
# И напоследок - всем остальным - DROP
$IPTABLES -A verify -p ALL -s $LAN_IP_RANGE -j DROP
#
# 4.1.4 Цепочка INPUT.
#
#
# Фильтруем "плохие пакеты" через цепочку bad_tcp_packets.
#
$IPTABLES -A INPUT -p tcp -j bad_tcp_packets
#
# Правила для "своих" сетей, т.е. не для интернета.
#
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LAN_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$IPTABLES -A INPUT -p ALL -i $LO_IFACE -s $INET_IP -j ACCEPT
#
# Правила для пакетов, приходящих их интернета.
#
# Это правило эквивалентно правилу, стоящему в цепочке alowed и в некоторой степени
# является избыточным, однако, оно несколько разгружает сетевой фильтр,
# поскольку значительная доля трафика пропускается этим правилом и не проходит
# всю последовательность до цепочки alowed.
# Каждое правило тут - сначала запускает пакет в цепочку подсчета трафика, затем обрабатывет далее
$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j trafficcount
$IPTABLES -A INPUT -p ALL -d $INET_IP -m state --state ESTABLISHED,RELATED \
-j ACCEPT
# Отправляем tcp пакеты в соответствующую цепочку.
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j trafficcount
$IPTABLES -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
# Отправляем udp пакеты в соответствующую цепочку.
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j trafficcount
$IPTABLES -A INPUT -p UDP -i $INET_IFACE -j udp_packets
# Отправляем icmp пакеты в соответствующую цепочку.
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j trafficcount
$IPTABLES -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
#
# Клиенты Microsoft Network имеют дурную привычку выдавать огромное количесво
# групповых пакетов в диапазоне адресов 224.0.0.0/8. Поэтому можно использовать данное
# правило для предотвращения засорения логов, в случае, если с внешней стороны
# имеется какая либо сеть Microsoft Network. Подобную же проблему решают два последних
# правила в цепочке udp_packets.
#
$IPTABLES -A INPUT -i $INET_IFACE -d 224.0.0.0/8 -j DROP
#
# Весь отбрасываемый траффик журналируется.
#
$IPTABLES -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT INPUT packet died: "
#
# 4.1.5 Цепочка FORWARD.
#
# Фильтруем "плохие пакеты".
$IPTABLES -A FORWARD -p tcp -j bad_tcp_packets
# Пробиваем мак и айпи на соответствие.
$IPTABLES -A FORWARD -p ALL -j verify
# Пропускаем пакеты на известные и разрешенные хосты.
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_HICFTP -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_BANK_1 -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_BANK_2 -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_BANK_3_1 -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_BANK_3_2 -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_MAIL -p tcp --dport $MAIL_SMTP -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_MAIL -p tcp --dport $MAIL_POP -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_MAIL1 -p tcp --dport $MAIL_SMTP -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -d $IP_MAIL1 -p tcp --dport $MAIL_POP -j ACCEPT
# Пропускаем HTTPS мимо сквида, попутно считая.
$IPTABLES -A FORWARD -i $LAN_IFACE -p tcp --dport $HTTPS -j secured
$IPTABLES -A FORWARD -i $LAN_IFACE -p tcp --dport $HTTPS -j ACCEPT
# Пропускаем пакеты на SQUID.
$IPTABLES -A FORWARD -i $LAN_IFACE -p tcp --dport $SQV_HTTP -j ACCEPT
$IPTABLES -A FORWARD -i $LAN_IFACE -p tcp --dport $SQV_FTP -j ACCEPT
# Пропускаем ответные пакеты в локальную сеть.
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j trafficcount
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Весь отбрасываемый траффик журналируется.
#
$IPTABLES -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT FORWARD packet died: "
#
# 4.1.6 Цепочка OUTPUT.
#
#
# Фильтруем "плохие пакеты".
#
$IPTABLES -A OUTPUT -p tcp -j bad_tcp_packets
#
# Правила OUTPUT, определяющие, какие IP будут допущены.
#
$IPTABLES -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$IPTABLES -A OUTPUT -p ALL -s $INET_IP -j ACCEPT
#
# Весь отбрасываемый траффик журналируется.
#
$IPTABLES -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
--log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
######
# 4.2 Таблица nat.
#
#
# 4.2.1 Задаем политики по умолчанию.
#
#
# 4.2.2 Создаем пользовательские цепочки.
#
#
# 4.2.3 Содежимое пользовательских цепочек.
#
#
# 4.2.4 Цепочка PREROUTING.
#
# Принимаем те пакеты, которые всегда разрешены и идут
# мимо сквида до того, как они уйдут в сквид.
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_HICFTP -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_BANK_1 -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_BANK_2 -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_BANK_3_1 -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_BANK_3_2 -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $LAN_IP -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_MAIL -j ACCEPT
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -d $IP_MAIL1 -j ACCEPT
# Перенаправляем пакеты на сквид.
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -p tcp --dport $SQV_HTTP -j REDIRECT --to-ports $SQUID
$IPTABLES -t nat -A PREROUTING -i $LAN_IFACE -p tcp --dport $SQV_FTP -j REDIRECT --to-ports $SQUID
#
# 4.2.5 Цепочка POSTROUTING.
#
#
# Включаем простой IP форвардинг и преобразование сетевых адресов.
#
$IPTABLES -t nat -A POSTROUTING -o $INET_IFACE -j SNAT --to-source $INET_IP
################################################################
#
# 5. Включение перенаправления пакетов
# Лучше делать это в конце, ибо к моменту включения форвардинга все
# правила уже заданы.
echo "1" > /proc/sys/net/ipv4/ip_forward
exit 0
Старался сделать его максимально удобочитаемым.
Для подсчета общего трафика и https написал 2 скрипта - один срабатывает каждые 30 минут и кладет трафик в файл, другой срабатывает в 23.55 и собирает статистику за день.
Это тот, что собирает трафик раз в 30 минут:
#!/bin/sh
#
# Этим скриптом выковыривается насчитанное количество трафика за 30 минут и кладется в папку daystat
# с именем HH-MM.txt
# затем сбрасываются счетчики.
# Забиваем переменные
IPTABLES="/sbin/iptables" # Путь до IPTABLES
HOUR=`date +%H` # Час
MINUTE=`date +%M` # Минута
DAYSTAT='/home/madkox/daystat' # Путь до папки с дневной статистикой
# Собираем дату вместе для получения имени файла
NUMTODAY=$HOUR-$MINUTE
# Задаем названия файлам
TRAF="$NUMTODAY-traf"
SECU="$NUMTODAY-https"
# Обнуляем переменные (если трафика нет вообще).
STAT=`expr 0`
HTTPS=`expr 0`
# Собираем трафик и обнуляем счетчики
STAT=`$IPTABLES -L -Z trafficcount -v -x | head -c 149 | tail -c 9`
HTTPS=`$IPTABLES -L -Z secured -v -x | head -c 144 | tail -c 9`
echo $STAT > $DAYSTAT/${TRAF}.txt
echo $HTTPS > $DAYSTAT/${SECU}.txt
exit 0
А этот - для запуска раз в день:
#!/bin/sh
#
# Забиваем переменные
MONTH=`date +%m` # Месяц
YEAR=`date +%y` # Год
MONTHSTAT='/home/madkox/monthstat' # Путь до папки с месячной статистикой
DAYSTAT='/home/madkox/daystat' # Путь до папки с дневной статистикой
# Собираем дату вместе для получения имени файла
NUMTODAY=$MONTH-$YEAR
# Создаем имена файлов
TRAF="$NUMTODAY-mtraf"
SECU="$NUMTODAY-mhttps"
# Идем в папку где у нас лежат файлы с месячной статистикой
cd $MONTHSTAT
# Проверяем, создавался ли уже в этом месяце файл с отчетом трафика.
if [ -e "$TRAF.txt" ]
then
File=$TRAF.txt
{
read line1
} < $File
TRAF_COUNTER="$line1" # если да - то устанавливаем счетчик равным вчерашнему числу.
else
TRAF_COUNTER=`expr 0` # если нет - то устанавливаем счетчик в ноль.
fi
# Проверяем, создавался ли уже в этом месяце файл с отчетом https.
if [ -e "$SECU.txt" ]
then
File=$SECU.txt
{
read line1
} < $File
HTTPS_COUNTER="$line1" # если да - то устанавливаем счетчик равным вчерашнему числу.
else
HTTPS_COUNTER=`expr 0` # если нет - то устанавливаем счетчик в ноль.
fi
# Идем в папку с дневной статистикой
cd $DAYSTAT
# циклом читаем дневные файлы и складываем их трафик
for file in *traf.txt
do
{
read line1
} < $file
TRAF_COUNTER=`expr $TRAF_COUNTER + $line1`
rm -f $file
done
for file in *https.txt
do
{
read line1
} < $file
HTTPS_COUNTER=`expr $HTTPS_COUNTER + $line1`
rm -f $file
done
# Далее перезаписываем файлы с месячной статистикой.
echo $TRAF_COUNTER > $MONTHSTAT/${TRAF}.txt
echo $HTTPS_COUNTER > $MONTHSTAT/${SECU}.txt
exit 0
Возможно где-то что-то можно было сделать и лучше и надежнее, но у меня получилось вот так.
Продолжение следует...