http://linuxforum.ru/viewtopic.php?pid=176106#p176106
Вопросов стало много, поэтому решил написать заметку как сделать простой шлюз и firewall для Debian, критика, вопросы и указание ошибок приветствуется, в соответствующей теме.
Каждый выход в интернет не только дает возможность подключаться к различным серверам и сайтам, но и создает потенциальную опасность проникновения на наш компьютер извне. Не стоит пренебрегать этой опасностью. Ситуация усугубляется оттого, что в некоторых (пока еще) широко распространненных операционных системах по умолчанию остаются открытыми многие порты, что позволяет подключаться из интернета к пользователю незаметно для последнего.
Поэтому в основу любого firewall должны быть заложены правила по закрытию и контролированию портов.
В нашем случае действуют политики по умолчанию - всё закрыть, открыть извне только то что нам необходимо, а также сам шлюз и компьютеры локальной сети могут открывать порты в обратную сторону самостоятельно, вот как эти правила выглядят на языке iptables:
# Закрываем изначально ВСЁ (т.е. изначально все что не разрешено - запрещено):
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Состояние ESTABLISHED говорит о том, что это не первый пакет в соединении.
# Пропускать все уже инициированные соединения, а также дочерние от них
iptables -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
# Пропускать новые, а так же уже инициированные и их дочерние соединения
iptables -A OUTPUT -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# Разрешить форвардинг для новых, а так же уже инициированных и их дочерних соединений
iptables -A FORWARD -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Исходные данные.
Компьютер подключенный к интернет через pppoe (для настройки лучше использовать pppoeconf - это скрипт входящий в стандартную установку Debian), интерфейс ppp0.
Шлюзом будет машина с ip = 192.168.0.1
Для того чтобы наш шлюз раздавал dns клиентам необходимо поствить dnsmasq, если у вас стоит какой-то другой кэшируюший dns-сервер то dnsmasq устанавливать нет необходимости:
$ aptitude install dnsmasq iptables
Настраивать dnsmasq никак не надо.
Раздача интернета будет осуществлена на локальную сеть подключенную к интерфейсу eth1, ip адреса: 192.168.0.0/24.
Все это можно в принципе изменить, в скрипте введены для этого переменные в шапке - например если у вас интернет подключен напрямую к eth0 без pppoe, то достаточно изменить export WAN=ppp0 на export WAN=eth0, так же и с остальным.
В нашем случае вот примерно как будут выглядеть настройки сетевых интерфейсов:
$ cat /etc/network/interfaces
# Файл описывает сетевые интерфейсы доступные в системе
# и способы активирования их.
# The loopback network interface
auto lo
iface lo inet loopback
# PPPoE
auto eth0
iface eth0 inet manual
auto dsl-provider
iface dsl-provider inet ppp
pre-up ifconfig eth0 up
provider dsl-provider
# eth1 - Локальная сеть
auto eth1
iface eth1 inet static
address 192.168.0.1
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.0.255
Ну собственно вот наш скрипт:
#!/bin/bash
# Тут в принципе может и не надо этого всего но не помеха вдруг какой модуль не подгружен или форвардинг не включен
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
modprobe iptable_nat
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
# Объявление переменных
export IPT="iptables"
# Интерфейс который смотрит в интернет
export WAN=ppp0
# Локальная сеть
export LAN=eth1
export LAN_IP_RANGE=192.168.0.0/24
# Очистка всех цепочек iptables
$IPT -F
$IPT -F -t nat
$IPT -F -t mangle
$IPT -X
$IPT -t nat -X
$IPT -t mangle -X
# Закрываем изначально ВСЁ (т.е. изначально все что не разрешено - запрещено):
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# разрешаем локальный траффик для loopback и внутренней сети
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i $LAN -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A OUTPUT -o $LAN -j ACCEPT
# Состояние ESTABLISHED говорит о том, что это не первый пакет в соединении.
# Пропускать все уже инициированные соединения, а также дочерние от них
$IPT -A INPUT -p all -m state --state ESTABLISHED,RELATED -j ACCEPT
# Пропускать новые, а так же уже инициированные и их дочерние соединения
$IPT -A OUTPUT -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# Разрешить форвардинг для новых, а так же уже инициированных и их дочерних соединений
$IPT -A FORWARD -p all -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# Включаем фрагментацию пакетов. Необходимо из за разных значений MTU
$IPT -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# Отбрасывать все пакеты, которые не могут быть идентифицированы и поэтому не могут иметь определенного статуса.
$IPT -A INPUT -m state --state INVALID -j DROP
$IPT -A FORWARD -m state --state INVALID -j DROP
# Приводит к связыванию системных ресурсов, так что реальный обмен данными становится не возможным.
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A OUTPUT -p tcp ! --syn -m state --state NEW -j DROP
# Разрешаем доступ из внутренней сети наружу
$IPT -A FORWARD -i $LAN -o $WAN -j ACCEPT
# Запрещаем доступ снаружи во внутреннюю сеть
$IPT -A FORWARD -i $WAN -o $LAN -j REJECT
# Маскарадинг
$IPT -t nat -A POSTROUTING -o $WAN -s $LAN_IP_RANGE -j MASQUERADE
# Далее дано как пример открытие портов извне:
# **********************************************************************
# Открываем порт для ssh
$IPT -A INPUT -i $WAN -p tcp --dport 22 -j ACCEPT
# Открытие портов для торрентов (такие же указать в torrent-клиенте)
$IPT -A INPUT -i $WAN -p tcp -m multiport --ports 50100:51100 -j ACCEPT
# Открытие 443 порта
$IPT -A INPUT -p tcp --dport 443 -j ACCEPT
# Открываем 80 порт для веб сайтов
$IPT -A INPUT -i $WAN -p all --dport 80 -j ACCEPT
# Открытие портов для игровых серверов
$IPT -A INPUT -i $WAN -p tcp --dport 27010:27030 -j ACCEPT
$IPT -A INPUT -i $WAN -p udp --dport 27010:27030 -j ACCEPT
# **********************************************************************
# Вывод информации о состоянии
$IPT -L
Открытие портов приведено как пример.
Теперь сохраняем скрипт в файл, допустим /etc/firewall.sh, делаем его исполняемым.
$ chmod +x /etc/firewall.sh
Для начала чтобы скрипт выполнялся во время загрузки можно поместить ссылку в rc.local до строчки exit 0:
$ cat rc.local
#!/bin/sh -e
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.
sh /etc/firewall.sh
exit 0
Поместить запуск в rc.local не есть самое правильное решение, более правильно - это сохранить правила iptables перед выключением, потом перед поднятием сетевого интерфейса загрузить правила, объясню как это сделать:
Для сохранения правил iptables существует команда:
$ iptables-save > /etc/ip_rulles.lst
После этого правила будут сохранены в файле (имя произвольное) /etc/ip_rulles.lst
Для загрузки правил соответственно:
$ iptables-restore < /etc/ip_rulles.lst
Ну и самое интересное - в файле настроек сети /etc/network/interfaces в каждый из интерфейсов можно добавлять секции которые будут выполнятся до поднятия, после поднятия, до отключения и после отключения интерфейса - секции:
pre-up
up
post-down
down
В нашем примере сохранение \ восстановление правил лучше поместить в секцию с loopback interface, вот как это будет выглядеть:
# The loopback network interface
auto lo
iface lo inet loopback
pre-up echo "1" > /proc/sys/net/ipv4/ip_forward # Включаем форвардинг пакетов
pre-up iptables-restore < /etc/ip_rulles.lst # Загружаем правила
post-down iptables-save > /etc/ip_rulles.lst # Сохраняем правила
После этого из rc.local необходимо лишнее убрать.
Теперь необходимо выполнить наш скрипт и сохранить правила
$ sh /etc/firewall.sh
$ iptables-save > /etc/ip_rulles.lst
Теперь все правила будут выставляться автоматически.
Также если сделать restart сети - правила сохраняться и сразу загрузятся.
Чтобы обновить можно принудительно сделать:
$ /etc/init.d/networking restart # start | stop | force-reload
или
$ ifdown lo
$ ifup lo
IP-калькулятор
Руководство по iptables
По следам темы Помогите раздать инет в сети
И многих других подобных.
И повторю - это простой вариант шлюза - целью было показать как это делается на примере.
Оригинал у меня.
Отправить комментарий