Простой шлюз на iptables для раздачи интернета с модемного соединения (ppp0) в Linux(Debian и Ubuntu).

В данной статье рассмотрен пример скрипта iptables для организации шлюза. Должен признать, что для организации совсем простого выхода в интернет через компьютер на Linux, подключенный к интернету через модемное соединение (например 3G модем) она содержит много лишнего и поначалу может запутать. Поэтому опишу совсем простой случай.
Continue reading


Подсчет трафика

В статье про настройку маршрутизации и организацию доступа подсети в internet есть несколько правил, пишущих логи о пролетающих в маршрутизаторе пакетах. Настало время их художественно причесать, для удобного составления отчетов.

Предварительный парсинг логов

Данный скрипт читает /var/log/debug, парсит из него логи iptables в файлик в /var/log/traflogs/, после чего очищает/var/log/debug.

#!/usr/bin/perl -w

my $LOG_FILENAME = "/var/log/debug";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$mon = $mon +1;
$year = $year + 1900;
my $TAB_OUTPUT = "/var/log/traflogs/$year-$mon-$mday-$hour-$min-$sec.csv";

my %MONS = (
    "Jan"=>"01",
    "Feb"=>"02",
    "Mar"=>"03",
    "Apr"=>"04",
    "May"=>"05",
    "Jun"=>"06",
    "Jul"=>"07",
    "Aug"=>"08",
    "Sep"=>"09",
    "Oct"=>"10",
    "Nov"=>"11",
    "Dec"=>"12"
);

open (A,$LOG_FILENAME);
open (B,">".$TAB_OUTPUT);
$count = 0;
print B "datetime\t\ti_in\ti_out\tsource\t\tdestination\tletgth\tproto\tsport\tdport\tresult\n";
print B "-----------------------------------------------------------------------------------------------------------------\n";
while(<A>){
    if(~/(\w+)\s+(\d+)\s+([\d:]+)\s+.*?\]\s+.*?(\w+)\s+
        IN=([\d\w]*)\s+OUT=([\d\w]*)\s+.*?SRC=([\d\.]+)\s+DST=([\d\.]+)\s+LEN=(\d+).*?
        PROTO=(\w+)\s+SPT=(\d+)\s+DPT=(\d+)/xig){
        $count = $count + $9;
        print B "$year-$MONS{$1}-".($2<10?"0$2":$2)." $3\t$5\t$6\t$7\t$8\t$9\t$10\t$11\t$12\t$4\n";
    }

}
close(A);
close(B);
`cat /dev/null > /var/log/debug`

Разумно повесить его на cron, чтобы каждый час формировал такую табличку

# head /var/log/traflogs/2011-1-5-17-55-1.csv
datetime                i_in    i_out   source          destination     letgth  proto   sport   dport   result
-----------------------------------------------------------------------------------------------------------------
2011-01-05 16:55:07     eth0    ppp0    192.168.0.1     77.88.57.177    274     TCP     50488   5222    ACCEPT
2011-01-05 16:55:08     ppp0    eth0    77.88.57.177    192.168.0.1     40      TCP     5222    50488   ACCEPT
2011-01-05 16:55:09     eth0    ppp0    192.168.0.1     77.88.57.177    226     TCP     50488   5222    ACCEPT
2011-01-05 16:55:09     ppp0    eth0    77.88.57.177    192.168.0.1     40      TCP     5222    50488   ACCEPT
2011-01-05 16:55:12     eth0    ppp0    192.168.0.1     77.88.57.177    114     TCP     50488   5222    ACCEPT
2011-01-05 16:55:12     ppp0    eth0    77.88.57.177    192.168.0.1     40      TCP     5222    50488   ACCEPT
2011-01-05 16:55:16     eth0    ppp0    192.168.0.1     77.88.57.177    290     TCP     50488   5222    ACCEPT
2011-01-05 16:55:17     ppp0    eth0    77.88.57.177    192.168.0.1     40      TCP     5222    50488   ACCEPT

Размещение логов в БД

Создадим 3 таблички в БД MySQL

CREATE TABLE `devs` (
  `id` tinyint(2) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(8) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1

CREATE TABLE `protos` (
  `id` tinyint(2) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(8) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 |

CREATE TABLE `packs` (
  `dat` datetime DEFAULT NULL,
  `i_dev_id` tinyint(2) UNSIGNED NOT NULL DEFAULT '0',
  `o_dev_id` tinyint(2) UNSIGNED NOT NULL DEFAULT '0',
  `i_ip` int(11) UNSIGNED DEFAULT NULL,
  `o_ip` int(11) UNSIGNED DEFAULT NULL,
  `size` smallint(5) DEFAULT NULL,
  `proto_id` tinyint(2) UNSIGNED DEFAULT NULL,
  `i_port` smallint(5) DEFAULT NULL,
  `o_port` smallint(5) DEFAULT NULL,
  `accept` enum('0','1') NOT NULL DEFAULT '0',
  KEY `i_dev_id` (`i_dev_id`),
  KEY `o_dev_id` (`o_dev_id`),
  KEY `proto_id` (`proto_id`),
  KEY `i_port` (`i_port`),
  KEY `o_port` (`o_port`),
  KEY `dat` (`dat`),
  KEY `accept` (`accept`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Следующий скрипт читает содержимое каталога /var/log/traflogs/, все файлы *.csv перегоняет в *.csv.sql, после чего загружает их в БД с последующим удалением исходников *.csv

#!/usr/bin/perl -w

my $CSV_DIR = "/var/log/traflogs";
my $counter = 0;
my ($datetime,$i_dev,$o_dev,$i_ip,$o_ip,$size,$proto,$i_port,$o_port);

my %DEVS = (
""=>'0',
"eth0"=>'1',
"eth1"=>'2',
"eth2"=>'3',
"ppp0"=>'4',
"lo"=>"5"
);
my %PROTOS = (
'TCP'=>'1',
'UDP'=>'2'
);

opendir($dd, $CSV_DIR);
while($filename = readdir($dd)){
    if($filename ne '.' && $filename ne '..' && $filename=~/^.*\.csv$/g){
        chomp($filename);
        print $filename."\n";
        open (A,"$CSV_DIR/$filename");
        open (B,">$CSV_DIR/$filename.sql");
        $counter = 0;
        while(<A>){
            $counter = $counter+1;
            if($counter>2){
                ($datetime,$i_dev,$o_dev,$i_ip,$o_ip,$size,$proto,$i_port,$o_port,$result) = split /\t/;
                chomp($result);
                $i_dev = $DEVS{$i_dev};
                $o_dev = $DEVS{$o_dev};
                $proto = $PROTOS{$proto};
                $i_ip = ip_to_int($i_ip);
                $o_ip = ip_to_int($o_ip);
                print B "insert into packs values('$datetime','$i_dev','$o_dev','$i_ip','$o_ip','$size','$proto','$i_port','$o_port','".
                ($result eq 'ACCEPT'?"1":"0")
                ."');\n";
            }
        }
        close(A);
        close(B);
        `mysql -u root -ptoor trafd < $CSV_DIR/$filename.sql`;
        unlink("$CSV_DIR/$filename");
        unlink("$CSV_DIR/$filename.sql");
    }
}
closedir($dd);

sub ip_to_int{
    my ($ip) = @_;
    my ($a3,$a2,$a1,$a0) = split(/[^\d]/,$ip);
    return $a3*256*256*256 + $a2*256*256 + $a1*256 +$a0;
}

В результате имеем таблицу packs набитую информацией о пакетах.

Простые запросы для отчетов по трафику

Размер входящего трафика по портам

SELECT 
    i_port,
    round(sum(size)/1024/1024,3) AS MBytes 
FROM 
    packs 
WHERE 
    (
        (i_dev_id=4 AND o_dev_id=0) OR (i_dev_id=4 AND o_dev_id!=0)
    ) AND 
    accept='1' 
GROUP BY 
    i_port 
ORDER BY 
    MBytes DESC 
LIMIT 
    32

Получаем вот такой результат

+--------+--------+
| i_port | MBytes |
+--------+--------+
|     80 | 27.688 |
|     53 |  0.997 |
|    443 |  0.262 |
|   5222 |  0.205 |
|    123 |  0.052 |
|  11350 |  0.014 |
|  32767 |  0.004 |
|     25 |  0.001 |
|    110 |  0.001 |
|  12350 |  0.001 |
|   5277 |  0.001 |
|   7777 |  0.001 |
|  20253 |  0.000 |
|  24332 |  0.000 |
|  29605 |  0.000 |
|  32285 |  0.000 |
|  31902 |  0.000 |
|  21705 |  0.000 |
|  22306 |  0.000 |
|   4779 |  0.000 |
|  17944 |  0.000 |
|  22068 |  0.000 |
|  25343 |  0.000 |
|   4762 |  0.000 |
|  10176 |  0.000 |
|   1600 |  0.000 |
|   1720 |  0.000 |
|   1659 |  0.000 |
|   8625 |  0.000 |
|  27076 |  0.000 |
|  27858 |  0.000 |
|  27755 |  0.000 |
+--------+--------+

Размер исходящего трафика по портам

SELECT 
    o_port,
    round(sum(size)/1024/1024,3) AS MBytes 
FROM 
    packs 
WHERE 
    (
        (o_dev_id=4 AND i_dev_id=0) OR (o_dev_id=4 AND i_dev_id!=0)
    ) AND 
    accept='1' 
GROUP BY 
    o_port 
ORDER BY 
    MBytes DESC 
LIMIT 
    32

Даёт следующий результат

+--------+--------+
| o_port | MBytes |
+--------+--------+
|     80 |  7.067 |
|     53 |  0.418 |
|   5222 |  0.133 |
|    443 |  0.094 |
|    123 |  0.056 |
|  32767 |  0.031 |
|  11350 |  0.003 |
|    110 |  0.002 |
|   7777 |  0.002 |
|  32285 |  0.001 |
|  14439 |  0.001 |
|  17418 |  0.001 |
|   8776 |  0.001 |
|   5975 |  0.001 |
|   1899 |  0.001 |
|  13645 |  0.001 |
|  12350 |  0.001 |
|   3990 |  0.001 |
|   6615 |  0.001 |
|   8342 |  0.001 |
|   8625 |  0.001 |
|   9466 |  0.001 |
|   1636 |  0.001 |
|  19776 |  0.001 |
|   1090 |  0.001 |
|  21879 |  0.001 |
|  16385 |  0.001 |
|  27858 |  0.001 |
|  21520 |  0.001 |
|     25 |  0.001 |
|  28555 |  0.001 |
|  28222 |  0.001 |
+--------+--------+

Отчет о последних отброшенных пакетах

SELECT
    dat AS `date`,
    i.name AS `IN`,
    o.name AS `OUT`,
    o_port AS dport, 
    i_port AS sport, 
    INET_NTOA(i_ip) AS `from`,
    INET_NTOA(o_ip) AS `to`,
    IF(proto_id=1,'TCP','UDP') AS `proto`  
FROM 
    devs AS i 
        RIGHT JOIN 
    packs 
        ON i.id=packs.i_dev_id 
        LEFT JOIN 
    devs AS o 
        ON o.id=packs.o_dev_id 
WHERE 
    accept='0'
ORDER BY
    `date` DESC 
LIMIT 
    32;

Получаем что-то вроде

+---------------------+------+------+-------+-------+-------------+---------------+-------+
| date                | IN   | OUT  | dport | sport | from        | to            | proto |
+---------------------+------+------+-------+-------+-------------+---------------+-------+
| 2011-01-05 15:38:53 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:38:53 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:28:09 | NULL | lo   |   953 | 32767 | 127.0.0.1   | 127.0.0.1     | TCP   |
| 2011-01-05 15:28:03 | NULL | lo   |   953 | 32767 | 127.0.0.1   | 127.0.0.1     | TCP   |
| 2011-01-05 15:28:00 | NULL | lo   |   953 | 32767 | 127.0.0.1   | 127.0.0.1     | TCP   |
| 2011-01-05 15:26:52 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:26:52 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:14:52 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:14:52 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:02:51 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 15:02:51 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:50:51 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:50:51 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:38:50 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:38:50 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:26:49 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:26:49 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:14:49 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:14:49 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:02:48 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 14:02:48 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 13:50:48 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 13:50:48 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 13:38:47 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 13:38:47 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
| 2011-01-05 13:26:46 | eth0 | NULL |   138 |   138 | 192.168.0.1 | 192.168.0.255 | UDP   |
+---------------------+------+------+-------+-------+-------------+---------------+-------+

При желании запросы можно разнообразить


Настройка межсетевого экрана и маршрутизации(iptables)

Итак, у нас есть настроенное ppp-подключение и 3 поднятых ethernet-сетевые карты, смотрящие в разные подсети

Теперь стоит относительно сложная и интересная задача настройки маршрутизации между этими сетями и обеспечения доступа из них в internet через ppp-соединение на шлюзе.

Все это будет сделано несколькими скриптами с правилами iptables, которые для удобства будут расположены в отдельном каталоге/root/iptables

clear.sh

Очистка таблиц и цепочек от старых правил

#!/bin/sh

iptables -v -F
iptables -v -X

rules_logs.sh

Цепочки, для записи в лог и окончательного принятия или отбрасывания пакетов. Логи будут писаться в /var/log/debug

#!/bin/sh

################################################################################################
# Ведение логов
###############################################################################################
iptables -v -N LOG_ACCEPT
iptables -v -A LOG_ACCEPT -p all -j LOG --log-level DEBUG --log-prefix " ACCEPT "
iptables -v -A LOG_ACCEPT -p all -j ACCEPT

iptables -v -N LOG_DROP
iptables -v -A LOG_DROP -p all -j LOG --log-level DEBUG --log-prefix " DROP "
iptables -v -A LOG_DROP -p all -j DROP

rules_logs.sh

Цепочки, принимающие или отбрасывающие пакеты с определённых портов

#!/bin/sh

iptables -v -N ALLOW_FTP
iptables -v -A ALLOW_FTP -p tcp -m multiport --source-ports 21 -j LOG_ACCEPT
iptables -v -A ALLOW_FTP -p tcp -m multiport --destination-ports 21 -j LOG_ACCEPT
iptables -v -A ALLOW_FTP -p all -j RETURN

iptables -v -N ALLOW_SSH
iptables -v -A ALLOW_SSH -p tcp -m multiport --source-ports 22 -j LOG_ACCEPT
iptables -v -A ALLOW_SSH -p tcp -m multiport --destination-ports 22 -j LOG_ACCEPT
iptables -v -A ALLOW_SSH -p all -j RETURN

iptables -v -N ALLOW_SMTP
iptables -v -A ALLOW_SMTP -p tcp -m multiport --source-ports 25 -j LOG_ACCEPT
iptables -v -A ALLOW_SMTP -p tcp -m multiport --destination-ports 25 -j LOG_ACCEPT
iptables -v -A ALLOW_SMTP -p all -j RETURN

iptables -v -N ALLOW_DNS
iptables -v -A ALLOW_DNS -p udp -m multiport --source-ports 53 -j LOG_ACCEPT
iptables -v -A ALLOW_DNS -p udp -m multiport --destination-ports 53 -j LOG_ACCEPT
iptables -v -A ALLOW_DNS -p all -j RETURN

iptables -v -N ALLOW_DHCP
iptables -v -A ALLOW_DHCP -p udp -m multiport --source-ports 67,68 -j LOG_ACCEPT
iptables -v -A ALLOW_DHCP -p udp -m multiport --destination-ports 67,68 -j LOG_ACCEPT
iptables -v -A ALLOW_DHCP -p all -j RETURN

iptables -v -N ALLOW_HTTP
iptables -v -A ALLOW_HTTP -p tcp -m multiport --source-ports 80 -j LOG_ACCEPT
iptables -v -A ALLOW_HTTP -p tcp -m multiport --destination-ports 80 -j LOG_ACCEPT
iptables -v -A ALLOW_HTTP -p all -j RETURN

iptables -v -N ALLOW_HTTPC
iptables -v -A ALLOW_HTTPC -p tcp -m multiport --source-ports 81 -j LOG_ACCEPT
iptables -v -A ALLOW_HTTPC -p tcp -m multiport --destination-ports 81 -j LOG_ACCEPT
iptables -v -A ALLOW_HTTPC -p all -j RETURN

iptables -v -N ALLOW_POP
iptables -v -A ALLOW_POP -p tcp -m multiport --source-ports 110 -j LOG_ACCEPT
iptables -v -A ALLOW_POP -p tcp -m multiport --destination-ports 110 -j LOG_ACCEPT
iptables -v -A ALLOW_POP -p all -j RETURN

iptables -v -N ALLOW_SMB
iptables -v -A ALLOW_SMB -p tcp -m multiport --source-ports 139,445 -j LOG_ACCEPT
iptables -v -A ALLOW_SMB -p tcp -m multiport --destination-ports 139,445 -j LOG_ACCEPT
iptables -v -A ALLOW_SMB -p all -j RETURN

iptables -v -N ALLOW_HTTPS
iptables -v -A ALLOW_HTTPS -p tcp -m multiport --source-ports 443 -j LOG_ACCEPT
iptables -v -A ALLOW_HTTPS -p tcp -m multiport --destination-ports 443 -j LOG_ACCEPT
iptables -v -A ALLOW_FTP -p all -j RETURN

iptables -v -N ALLOW_SMTPS
iptables -v -A ALLOW_SMTPS -p tcp -m multiport --source-ports 465 -j LOG_ACCEPT
iptables -v -A ALLOW_SMTPS -p tcp -m multiport --destination-ports 465 -j LOG_ACCEPT
iptables -v -A ALLOW_SMTPS -p all -j RETURN

iptables -v -N ALLOW_POPS
iptables -v -A ALLOW_POPS -p tcp -m multiport --source-ports 995 -j LOG_ACCEPT
iptables -v -A ALLOW_POPS -p tcp -m multiport --destination-ports 995 -j LOG_ACCEPT
iptables -v -A ALLOW_POPS -p all -j RETURN

iptables -v -N ALLOW_SQUID
iptables -v -A ALLOW_SQUID -p tcp -m multiport --source-ports 3128 -j LOG_ACCEPT
iptables -v -A ALLOW_SQUID -p tcp -m multiport --destination-ports 3128 -j LOG_ACCEPT
iptables -v -A ALLOW_SQUID -p all -j RETURN

iptables -v -N ALLOW_ICQ
iptables -v -A ALLOW_ICQ -p tcp -m multiport --source-ports 5190 -j LOG_ACCEPT
iptables -v -A ALLOW_ICQ -p tcp -m multiport --destination-ports 5190 -j LOG_ACCEPT
iptables -v -A ALLOW_ICQ -p all -j RETURN

iptables -v -N ALLOW_XMPP
iptables -v -A ALLOW_XMPP -p tcp -m multiport --source-ports 5222 -j LOG_ACCEPT
iptables -v -A ALLOW_XMPP -p tcp -m multiport --destination-ports 5222 -j LOG_ACCEPT
iptables -v -A ALLOW_XMPP -p all -j RETURN

iptables -v -N ALLOW_WESNOTH
iptables -v -A ALLOW_WESNOTH -p tcp -m multiport --source-ports 14998,14999,15000,15001 -j LOG_ACCEPT
iptables -v -A ALLOW_WESNOTH -p tcp -m multiport --destination-ports 14998,14999,15000,15001 -j LOG_ACCEPT
iptables -v -A ALLOW_WESNOTH -p all -j RETURN

iptables -v -N ALLOW_ICMP
iptables -v -A ALLOW_ICMP -p icmp --icmp-type 8 -j LOG_ACCEPT
iptables -v -A ALLOW_ICMP -p all -j RETURN

iptables -v -N DENY_FTP
iptables -v -A DENY_FTP -p tcp -m multiport --source-ports 21 -j LOG_DROP
iptables -v -A DENY_FTP -p tcp -m multiport --destination-ports 21 -j LOG_DROP
iptables -v -A DENY_FTP -p all -j RETURN

iptables -v -N DENY_SSH
iptables -v -A DENY_SSH -p tcp -m multiport --source-ports 22 -j LOG_DROP
iptables -v -A DENY_SSH -p tcp -m multiport --destination-ports 22 -j LOG_DROP
iptables -v -A DENY_SSH -p all -j RETURN

iptables -v -N DENY_SMTP
iptables -v -A DENY_SMTP -p tcp -m multiport --source-ports 25 -j LOG_DROP
iptables -v -A DENY_SMTP -p tcp -m multiport --destination-ports 25 -j LOG_DROP
iptables -v -A DENY_SMTP -p all -j RETURN

iptables -v -N DENY_DNS
iptables -v -A DENY_DNS -p udp -m multiport --source-ports 53 -j LOG_DROP
iptables -v -A DENY_DNS -p udp -m multiport --destination-ports 53 -j LOG_DROP
iptables -v -A DENY_DNS -p all -j RETURN

iptables -v -N DENY_DHCP
iptables -v -A DENY_DHCP -p udp -m multiport --source-ports 67,68 -j LOG_DROP
iptables -v -A DENY_DHCP -p udp -m multiport --destination-ports 67,68 -j LOG_DROP
iptables -v -A DENY_DHCP -p all -j RETURN

iptables -v -N DENY_HTTP
iptables -v -A DENY_HTTP -p tcp -m multiport --source-ports 80 -j LOG_DROP
iptables -v -A DENY_HTTP -p tcp -m multiport --destination-ports 80 -j LOG_DROP
iptables -v -A DENY_HTTP -p all -j RETURN

iptables -v -N DENY_HTTPC
iptables -v -A DENY_HTTPC -p tcp -m multiport --source-ports 81 -j LOG_DROP
iptables -v -A DENY_HTTPC -p tcp -m multiport --destination-ports 81 -j LOG_DROP
iptables -v -A DENY_HTTPC -p all -j RETURN

iptables -v -N DENY_POP
iptables -v -A DENY_POP -p tcp -m multiport --source-ports 110 -j LOG_DROP
iptables -v -A DENY_POP -p tcp -m multiport --destination-ports 110 -j LOG_DROP
iptables -v -A DENY_POP -p all -j RETURN

iptables -v -N DENY_SMB
iptables -v -A DENY_SMB -p tcp -m multiport --source-ports 139,445 -j LOG_DROP
iptables -v -A DENY_SMB -p tcp -m multiport --destination-ports 139,445 -j LOG_DROP
iptables -v -A DENY_SMB -p all -j RETURN

iptables -v -N DENY_HTTPS
iptables -v -A DENY_HTTPS -p tcp -m multiport --source-ports 443 -j LOG_DROP
iptables -v -A DENY_HTTPS -p tcp -m multiport --destination-ports 443 -j LOG_DROP
iptables -v -A DENY_FTP -p all -j RETURN

iptables -v -N DENY_SMTPS
iptables -v -A DENY_SMTPS -p tcp -m multiport --source-ports 465 -j LOG_DROP
iptables -v -A DENY_SMTPS -p tcp -m multiport --destination-ports 465 -j LOG_DROP
iptables -v -A DENY_SMTPS -p all -j RETURN

iptables -v -N DENY_POPS
iptables -v -A DENY_POPS -p tcp -m multiport --source-ports 995 -j LOG_DROP
iptables -v -A DENY_POPS -p tcp -m multiport --destination-ports 995 -j LOG_DROP
iptables -v -A DENY_POPS -p all -j RETURN

iptables -v -N DENY_SQUID
iptables -v -A DENY_SQUID -p tcp -m multiport --source-ports 3128 -j LOG_DROP
iptables -v -A DENY_SQUID -p tcp -m multiport --destination-ports 3128 -j LOG_DROP
iptables -v -A DENY_SQUID -p all -j RETURN

iptables -v -N DENY_ICQ
iptables -v -A DENY_ICQ -p tcp -m multiport --source-ports 5190 -j LOG_DROP
iptables -v -A DENY_ICQ -p tcp -m multiport --destination-ports 5190 -j LOG_DROP
iptables -v -A DENY_ICQ -p all -j RETURN

iptables -v -N DENY_XMPP
iptables -v -A DENY_XMPP -p tcp -m multiport --source-ports 5222 -j LOG_DROP
iptables -v -A DENY_XMPP -p tcp -m multiport --destination-ports 5222 -j LOG_DROP
iptables -v -A DENY_XMPP -p all -j RETURN

iptables -v -N DENY_WESNOTH
iptables -v -A DENY_WESNOTH -p tcp -m multiport --source-ports 14998,14999,15000,15001 -j LOG_DROP
iptables -v -A DENY_WESNOTH -p tcp -m multiport --destination-ports 14998,14999,15000,15001 -j LOG_DROP
iptables -v -A DENY_WESNOTH -p all -j RETURN

iptables -v -N DENY_ICMP
iptables -v -A DENY_ICMP -p icmp --icmp-type 8 -j LOG_DROP
iptables -v -A DENY_ICMP -p all -j RETURN

rules_users.sh

#!/bin/sh

###################################################################################
# Правила для FORWARD привелегированных пользователей
##################################################################################
iptables -v -N FORWARDS_ROOT
iptables -v -A FORWARDS_ROOT -p all -j LOG_ACCEPT
iptables -v -A FORWARDS_ROOT -p all -j RETURN
###################################################################################
# Правила для FORWARD обычных пользователей
##################################################################################
iptables -v -N FORWARDS_USER
iptables -v -A FORWARDS_USER -p all -j RETURN

###################################################################################
# Правила для INNER привелегированных пользователей
##################################################################################
iptables -v -N INNERS_ROOT
iptables -v -A INNERS_ROOT -p all -j LOG_ACCEPT
iptables -v -A INNERS_ROOT -p all -j RETURN
###################################################################################
# Правила для INNER обычных пользователей
##################################################################################
iptables -v -N INNERS_USER
iptables -v -A INNERS_USER -j ALLOW_DNS
iptables -v -A INNERS_USER -j ALLOW_SQUID
iptables -v -A INNERS_USER -j ALLOW_SMB
iptables -v -A INNERS_USER -j RETURN
###################################################################################
# Правила для INNER админов
##################################################################################
iptables -v -N INNERS_ADMIN
iptables -v -A INNERS_ADMIN -j ALLOW_DNS
iptables -v -A INNERS_ADMIN -j ALLOW_SQUID
iptables -v -A INNERS_ADMIN -j ALLOW_SMB
iptables -v -A INNERS_ADMIN -j ALLOW_SSH
iptables -v -A INNERS_ADMIN -j ALLOW_HTTPC
iptables -v -A INNERS_ADMIN -j RETURN

Цепочки, определяющие какому типу пользователей какие порты разрешены или запрещены. По умолчанию для пакеты, предназначенных шлюзу, отбрасываются(INNER-правила), и необходимо разрешить соединение по нужным портам. Для пакетов, проходящих мимо шлюза(маршрутизируемых) по умолчанию нет запретов, и прописываются запрещённые порты. Умолчальные правила прописаны в файле rules_politics.sh.

rules_groups.sh

Цепочки, определяющие к какому типу пользователей относитятся пакеты, приходящие с определённых IP локальной сети

#!/bin/sh

##################################################################################
# Группы пользователей для доступа к интернетам
##################################################################################
iptables -v -N FORWARDS_USERGROUPS
# Привелегированные пользователи. В интернет - без ограничений
#iptables -v -A FORWARDS_USERGROUPS --source 192.168.1.64 -j FORWARDS_ROOT
#iptables -v -A FORWARDS_USERGROUPS --destination 192.168.1.64 -m conntrack --ctstate ESTABLISHED,RELATED -j FORWARDS_ROOT
# Обычные пользователи.
iptables -v -A FORWARDS_USERGROUPS --source 192.168.1.64 -j FORWARDS_USER
iptables -v -A FORWARDS_USERGROUPS --destination 192.168.1.64 -m conntrack --ctstate ESTABLISHED,RELATED -j FORWARDS_USER
iptables -v -A FORWARDS_USERGROUPS --source 192.168.0.1 -j FORWARDS_USER
iptables -v -A FORWARDS_USERGROUPS --destination 192.168.0.1 -j FORWARDS_USER
# Неизвестные пользователи - в топку
iptables -v -A FORWARDS_USERGROUPS -j RETURN

##################################################################################
# Группы пользователей для доступа к шлюзу
##################################################################################
iptables -v -N INNERS_USERGROUPS

# Привелегированные пользователи. К серверу - без ограничений
iptables -v -A INNERS_USERGROUPS --source 192.168.1.1 -j INNERS_ROOT
iptables -v -A INNERS_USERGROUPS --destination 192.168.1.1 -m conntrack --ctstate ESTABLISHED,RELATED -j INNERS_ROOT

iptables -v -A INNERS_USERGROUPS --source 192.168.2.1 -j INNERS_ROOT
iptables -v -A INNERS_USERGROUPS --destination 192.168.2.1 -m conntrack --ctstate ESTABLISHED,RELATED -j INNERS_ROOT

iptables -v -A INNERS_USERGROUPS --source 192.168.0.128 -j INNERS_ROOT
iptables -v -A INNERS_USERGROUPS --destination 192.168.0.128 -m conntrack --ctstate ESTABLISHED,RELATED -j INNERS_ROOT

# Обычные пользователи.

iptables -v -A INNERS_USERGROUPS --source 192.168.0.1 -j INNERS_USER
iptables -v -A INNERS_USERGROUPS --destination 192.168.0.1 -m conntrack --ctstate ESTABLISHED,RELATED -j INNERS_USER

# Админы.

iptables -v -A INNERS_USERGROUPS --source 192.168.1.64 -j INNERS_ADMIN
iptables -v -A INNERS_USERGROUPS --destination 192.168.1.64 -m conntrack --ctstate ESTABLISHED,RELATED -j INNERS_ADMIN

iptables -v -A INNERS_USERGROUPS --source 192.168.0.1 -j INNERS_ADMIN
iptables -v -A INNERS_USERGROUPS --destination 192.168.0.1 -m conntrack --ctstate ESTABLISHED,RELATED -j INNERS_ADMIN
# Неизвестные пользователи - в топку
iptables -v -A INNERS_USERGROUPS -j RETURN

rules_redirect.sh

Тут расположены цепочки, отправляющие пришедших на 80-й порт на 3128-порт(прокси сервер), то есть все хождения по http — принудительно через прокси. Так же тут прописываются правила на получение DHCP-пакетов любым хостом.

#!/bin/sh

iptables -v -A INPUT -p UDP -m multiport --source-ports 67 -j LOG_ACCEPT
iptables -v -A INPUT -p UDP -m multiport --destination-ports 68 -j LOG_ACCEPT
iptables -v -A OUTPUT -p UDP -m multiport --source-ports 67 -j LOG_ACCEPT
iptables -v -A OUTPUT -p UDP -m multiport --destination-ports 68 -j LOG_ACCEPT

iptables -v -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128
iptables -v -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128
iptables -v -t nat -A PREROUTING -i eth2 -p tcp --dport 80 -j REDIRECT --to-port 3128
b

rules_politics.sh

Правила по умолчанию, если ни одно из вышеперечисленных не сработало

#!/bin/sh

################################################################################# Обработка входящих и исходящих пакетов
##################################################################################
# Все остальные входящие пакеты - на проверку
iptables -v -A INPUT -p all -j INNERS_USERGROUPS
# Все исходящие пакеты - на проверку
iptables -v -A OUTPUT -p all -j INNERS_USERGROUPS

################################################################################# Политики по умолчанию
################################################################################
# Все входящие по умолчанию глушим
iptables -v -A INPUT -p all -j LOG_DROP
# Все исходящие по умолчанию глушим
iptables -v -A OUTPUT -p all -j LOG_DROP
# Все пролетающие по умолчанию пропускаем
iptables -v -A FORWARD -p all -j LOG_ACCEPT

rules_ppp0.sh

Тут подключаются все вышеописанные правила, даётся доступ шлюза к ppp-соединению, пробрасываются маршруты между подсетями и устраивается маскарадинг для ppp0.

#!/bin/sh

echo "=============================== clear old rules ============================================";
/root/iptables/clear.sh
echo "==================================== set log rules =======================================";
/root/iptables/rules_logs.sh
echo "==================================== set services rules =======================================";
/root/iptables/rules_services.sh
echo "=================================== set users rules  ========================================";
/root/iptables/rules_users.sh
echo "===================================  set groups rules ========================================";
/root/iptables/rules_groups.sh
echo "===================================== set prerouting ======================================";
/root/iptables/rules_redirect.sh
echo "====================================  set post routing =======================================";
iptables -v -t nat -A POSTROUTING -s 192.168.0.0/24 -o ppp0 -j MASQUERADE
iptables -v -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADE
iptables -v -t nat -A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
echo "=================================== set routing ========================================";
################################################################################
# Пробрасываем маршруты
################################################################################
iptables -v -A INPUT -p all -i ppp0 -m conntrack --ctstate ESTABLISHED,RELATED -j LOG_ACCEPT
iptables -v -A OUTPUT -p all -o ppp0 -j LOG_ACCEPT

iptables -v -A FORWARD -i ppp0 -o eth0 --source 0.0.0.0/0 --destination 192.168.0.0/24 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i ppp0 -o eth1 --source 0.0.0.0/0 --destination 192.168.1.0/24 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i ppp0 -o eth2 --source 0.0.0.0/0 --destination 192.168.2.0/24 -j FORWARDS_USERGROUPS

iptables -v -A FORWARD -i eth0 -o ppp0 --source 191.168.0.0/24 --destination 0.0.0.0/0 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i eth0 -o eth1 --source 191.168.0.0/24 --destination 192.168.1.0/24 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i eth0 -o eth2 --source 191.168.0.0/24 --destination 192.168.2.0/24 -j FORWARDS_USERGROUPS

iptables -v -A FORWARD -i eth1 -o ppp0 --source 191.168.1.0/24 --destination 0.0.0.0/0 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i eth1 -o eth0 --source 191.168.1.0/24 --destination 192.168.0.0/24 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i eth1 -o eth2 --source 191.168.1.0/24 --destination 192.168.2.0/24 -j FORWARDS_USERGROUPS

iptables -v -A FORWARD -i eth2 -o ppp0 --source 191.168.2.0/24 --destination 0.0.0.0/0 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i eth2 -o eth0 --source 191.168.2.0/24 --destination 192.168.0.0/24 -j FORWARDS_USERGROUPS
iptables -v -A FORWARD -i eth2 -o eth1 --source 191.168.2.0/24 --destination 192.168.1.0/24 -j FORWARDS_USERGROUPS

echo "====================================== set politics =====================================";
/root/iptables/rules_politics.sh

Запуск

Чтобы правила применялись при загрузке машины, сделаем символическую ссылку

ln -s /root/iptables/rules_eth0.sh /etc/rc.firewall

И пропишем в rc.local

/etc/rc.firewall