CentOS + iptables = роутер

Возникла необходимость настроить заново роутер используя linux. В качестве sandbox’a была взята достаточно мощная под эти нужды машинка:
Celeron 2.3 Ghz
512 DDR2 RAM
110 GB HDD

[root@sandbox ~]# uname -a
Linux 2090000.ru 2.6.18-194.17.4.el5 #1 SMP Mon Oct 25 15:51:07 EDT 2010 i686 i686 i386 GNU/Linux

Задача: необходимо раздавать интернеты. Учета нам не надо (по крайней мере сейчас. Если надо будет смотреть нагрузку – поставлю Nagios). Необходимо просто организовать сервер, который имел бы на борту dhcp, apache для работы/учебы/собственных проектов (настройка описываться не будет), samba (настройка описываться не будет) и igmpproxy для смотрения IP-TV. IP адрес мы получаем напрямую от провайдера – никаких VPN, L2TP и прочее здесь рассматриваться не будет.

Буду учитывать, что у вас уже стоит RPM подобная ОС (например CentOS или RHL) и исходя из этого пути до некоторых скриптов могут различаться. Я выбрал CentOS как одну из самых защищенных ОС (не ради холивара сказано).
Итак. Сначала настроим dhcpd, чтобы он раздавал ip адреса всем устройствам подключенным к роутеру.
Конфиг dhcpd:

[root@router ~]# cat /etc/dhcpd.conf
ddns-update-style interim;
not authoritative;

option domain-name-servers 8.8.8.8;
option subnet-mask 255.255.255.0;
option ntp-servers 195.189.239.2;

subnet 192.168.0.0 netmask 255.255.255.0 {
authoritative;
range 192.168.0.100 192.168.0.254;
option routers 192.168.0.15;
allow unknown-clients;
allow booting;
allow bootp;
next-server 192.168.0.15;
filename "pxelinux.0";

host workstation {
        option host-name "workstation";
        hardware ethernet 00:12:04:20:4F:DC;
        fixed-address 192.168.0.100;
    }
}

Если хотите сделать dhcp lease (выдавать всегда один и тот же ip адрес) то создайте каждому из привязанных компьютеров отдельную директиву host. Роутер у меня в lan смотрит с ip адресом 192.168.0.15. В wan с ipv4 адресом, который выдается провайдером и статичен.
Теперь настроим статические ip адреса для устройств.
Устройства у меня следующие:

eth0      Link encap:Ethernet  HWaddr 00:E1:4F:8A:F3:52
          inet addr:192.168.0.15  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:76412860 errors:0 dropped:0 overruns:0 frame:0
          TX packets:87997501 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:878317362 (837.6 MiB)  TX bytes:3277225758 (3.0 GiB)
          Interrupt:169 Base address:0x2000

eth1      Link encap:Ethernet  HWaddr 00:AD:F1:4F:12:11
          inet addr:172.20.21.43  Bcast:172.20.21.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:111604876 errors:1918 dropped:652 overruns:346 frame:0
          TX packets:102192491 errors:0 dropped:0 overruns:1 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3253943371 (3.0 GiB)  TX bytes:742431041 (708.0 MiB)
          Interrupt:201 Base address:0x2000

eth1 – внешний (wan) интерфейс
eth0 – внутренний (lan) интерфейс
Исходя из этого настройки для eth1 такие:

[root@router ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
# Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+
DEVICE=eth1
BOOTPROTO=dhcp
HWADDR=00:AD:F1:4F:12:11
ONBOOT=yes

А для eth0 статичные:

[root@router ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0
# Realtek Semiconductor Co., Ltd. RTL-8139/8139C/8139C+
DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.0.15
NETMASK=255.255.255.0
HWADDR=00:E1:4F:8A:F3:52
ONBOOT=yes

Можем попробовать стартануть dhcpd:

[root@router ~]# service dhcpd start

Если все в порядке всем подключенным устройствам, которые получают ip адреса по dhcp должны выдаться ipшники.
Потом можем включить запуск dhcpd при старте системы.

[root@router ~]# chkconfig --level 345 dhcpd on
[root@router ~]# chkconfig --list | grep dhcp
dhcpd           0:выкл  1:выкл  2:выкл  3:вкл   4:вкл   5:вкл   6:выкл

Итак, переходим к самому главному. Настройке iptables. Весь трафик будет направляться с помощью него. Так же мы реализуем защиту от некоторых типов атак. Для того, чтобы не мудрить ничего со скриптами я пишу все вручную сразу же в файл правил iptables /etc/sysconfig/iptables.

[root@router ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Sat Feb 12 22:33:45 2011
*mangle
:PREROUTING ACCEPT [16227109:13393411926]
:INPUT ACCEPT [2831999:1288367909]
:FORWARD ACCEPT [13381890:12101945321]
:OUTPUT ACCEPT [4421349:5811697252]
:POSTROUTING ACCEPT [17809930:17913843359]
-A PREROUTING -d 224.0.0.0/240.0.0.0 -p udp -j TTL --ttl-inc 1
COMMIT
# Completed on Sat Feb 12 22:33:45 2011
# Generated by iptables-save v1.3.5 on Sat Feb 12 22:33:45 2011
*filter
:INPUT ACCEPT [2675290:1156848403]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [4421234:5811684759]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -i eth1 -p gre -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -d 172.20.21.43 -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -d 172.20.21.43 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -d 172.20.21.43 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -d 172.20.21.43 -p tcp -m tcp --dport 3306 -j ACCEPT
-A INPUT -d 172.20.21.43 -p gre -j ACCEPT
-A INPUT -d 224.0.0.0/240.0.0.0 -i eth1 -j ACCEPT
-A INPUT -s 224.0.0.0/240.0.0.0 -i eth1 -j ACCEPT
-A INPUT -i eth1 -p gre -j ACCEPT
-A INPUT -i eth1 -p tcp -m tcp --dport 1723 -j ACCEPT
-A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 1/sec -j ACCEPT
-A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK RST -m limit --limit 1/sec -j ACCEPT
-A FORWARD -p icmp -m icmp --icmp-type 8 -m limit --limit 1/sec -j ACCEPT
-A FORWARD -d 224.0.0.0/240.0.0.0 -j ACCEPT
-A FORWARD -s 224.0.0.0/240.0.0.0 -j ACCEPT
-A FORWARD -j ACCEPT
-A OUTPUT -o eth0 -p gre -j ACCEPT
-A OUTPUT -o eth0 -p tcp -m tcp --dport 1723 -j ACCEPT
COMMIT
# Completed on Sat Feb 12 22:33:45 2011
# Generated by iptables-save v1.3.5 on Sat Feb 12 22:33:45 2011
*nat
:PREROUTING ACCEPT [102290:13380449]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [4360:349447]
-A PREROUTING -d 172.20.21.43 -p tcp -m tcp --dport 3389 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p tcp -m tcp --dport 30001 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p udp -m udp --dport 30002 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p udp -m udp --dport 5070 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p tcp -m tcp --dport 8000 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p tcp -m tcp --dport 31337 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p udp -m udp --dport 31337 -j DNAT --to-destination 192.168.0.100
-A PREROUTING -d 172.20.21.43 -p tcp -m tcp --dport 8333 -j DNAT --to-destination 192.168.0.100
-A POSTROUTING -j MASQUERADE
COMMIT
# Completed on Sat Feb 12 22:33:45 2011

В данной настройки с помощью PREROUTING я сделал “проброс портов” на свою рабочую станцию. Все порты, которые перечисленны мной используются для различных программ и прочего. Так же здесь реализован пропуск протокола GRE, который необходим, если с LAN машин вы собрались работать с VPN (бывает необходимость залезть в офисную сеть). Так же не забываем, в этом случае, открыть порт 1723, который используется так же для VPN.
Так же я сделал для себя правило для multicast, который у нас используется для вещания IP-TV.
Так же у меня на рабочей станции есть телефония, которая работает через SIP протокол. По умолчанию работать не хотело, но после подключения модулей nf_conntrack_sip и nf_nat_sip все заработало. Подключаются модули следующим образом:

modprobe nf_conntrack_sip
modprobe nf_nat_sip

Правило -A PREROUTING -d 224.0.0.0/240.0.0.0 -p udp -j TTL –ttl-inc 1 выставляет правильные TTL для пакетов мультикаста. По умолчанию IP-TV работать не хотело, даже когда я настроил igmpproxy. После установки этого правила все заработало.

Итак, переходим к последнему пункту – настройки igmpproxy.
Здесь все пошагово:
Подключим необходимые репозитории:
Для i386 архитектуры:
1. Устанавливаем epel репозиторий.

rpm -ihv http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm

2. Устанавливаем CentALT репозиторий.

rpm -ihv http://centos.alt.ru/repository/centos/5/i386/centalt-release-5-3.noarch.rpm

Для x86_64 архитектуры:
1. Устанавливаем epel репозиторий.

rpm -ihv http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

2. Устанавливаем CentALT репозиторий.

rpm -ihv http://centos.alt.ru/repository/centos/5/x86_64/centalt-release-5-3.noarch.rpm

Установим igmpproxy:

yum install igmpproxy

Конфиг igmpproxy:

[root@router ~]# cat /etc/igmpproxy.conf
#quickleave
phyint eth0 downstream ratelimit 0 threshold 1
        altnet 192.168.0.0/24
phyint eth1 upstream ratelimit 0 threshold 1
        altnet 239.1.0.0/16
        altnet 10.245.0.0/16
        altnet 239.255.255.0/24

Запускаем imgpproxy и смотрим IP-TV.
Все, на данном настройка сервера закончена.

Кстати, данная конфигурация идеально работает с IP-TV Электронного Города в Новосибирске. По крайней мере на моей STB IP-TV показывает идеально + данная конфигурация отлично справляется с нагрузкой в 3 компьютера, которые смотрят IP-TV в HDTV качестве (поток порядка 15-20 Мбит на один канал). В локальной P2P скорость теперь такая, как будто бы я подключен к сети напрямую (10-12 мегабайт/сек) против 4-5 на Asus WL-520GU, который сегодня, к сожалению, погиб в неравной борьбе с чистящей жидкостью, которую на неё уронила кошка. Подключив гигабитный свитч, поставив гигабитную сетевку можно достигнуть, наконец, скоростей в домашней сети.

Если кто-то нашел какие-то ошибки – пишите в комментариях.