главная - Статьи - Linux, FreeBSD
Настройка iptables и NAT
Задача: настроить шлюз в интернет для офиса на основе обычного компьютера с установленной Linux с двумя сетевыми картами.
Условимся, что внутренняя сетевая карта называется eth1, внешняя - eth0.
Если в дальнейшем будет нужна статистика и пр., то настроить Squid будет не так и сложно.
Для простоты обозначений, наш шлюз будем называть сервер. Поехали...
1. Создаем скрипт правил iptables iptables.sh
Например, в директории /root создадим файл iptables.sh, дадим ему права на исполнение:
chmod +x /root/iptables.sh
Теперь поместим в этот файл следующий текст:
# Define vars
IF_EXT="eth0"
IF_INT="eth1"
IPT="/sbin/iptables"
# flush
$IPT --flush
$IPT -t nat --flush
$IPT -t mangle --flush
$IPT -X
# loopback
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# default
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP
# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# PROTECT FIREWALL
$IPT -N bad_packets
$IPT -P bad_packets ACCEPT
$IPT -A bad_packets -i $IF_EXT -s 10.0.0.0/8 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 172.16.0.0/12 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 192.168.0.0/12 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 127.0.0.0/8 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 0.0.0.0/8 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 169.254.0.0/16 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 192.0.2.0/24 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 204.152.64.0/23 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 224.0.0.0/3 -j DROP
$IPT -A bad_packets -i $IF_EXT -s 240.0.0.0/5 -j DROP
$IPT -A INPUT -j bad_packets
$IPT -A OUTPUT -j bad_packets
$IPT -A FORWARD -j bad_packets
# FORWARD chain
# #########################################
# allow new connections from local net to out
$IPT -A FORWARD -i $IF_INT -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# do not allow new connections from internet, but support established connections from local network
$IPT -A FORWARD -i $IF_EXT -o $IF_INT -m state --state ESTABLISHED,RELATED -j ACCEPT
# NAT
# #########################################
# SNAT - local users to out internet
$IPT -t nat -A POSTROUTING -o $IF_EXT -j MASQUERADE
# INPUT chain
# #########################################
$IPT -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i $IF_INT -p tcp --dport 22 -j ACCEPT
# OUTPUT chain
# #########################################
# new local connections
$IPT -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
2. Комментарии к скрипту iptables.sh
- Все секции снабжены минимальными комментариями, поэтому в них не запутается даже новичок.
- Наиболее "туманная" секция - # PROTECT FIREWALL, но во-первых, временно вы можете ее вообще убрать, а во-вторых, если задуматься, там всё просто. Мы защищаем наш сервер от атак, когда из внешней сети пытаются "прикинуться" внутренними адресами. Вот и все.
- Чтобы наш сервер в принципе мог выпускать во внешний мир клиентов локальной сети, обязательно надо включить forwarding (почти в самом начале скрипта):
# allow forwarding
echo 1 > /proc/sys/net/ipv4/ip_forwardДанный параметр также может быть задан через параметр:
net.ipv4.ip_forward = 1 в файле /etc/sysctl.conf.
Чтобы изменения в файле sysctl.conf вступили в силу, выполните следующую команду:
sysctl -p /etc/sysctl.conf
- В секции # INPUT chain мы разрешаем клиентам локальной сети подключаться к серверу по ssh. Обратите внимание, несмотря на то, что к самому серверу можно обратиться только по ssh, клиенты локальной сети не будут ограничены в выходе в интернет. Цепочка INPUT не для них!
- В цепочке # OUTPUT chain мы разрешаем серверу обращаться во внешний мир (скачивать обновления, например). Для упрощения считаем, что мы доверяем нашему серверу и разрешаем ему любые исходящие соединения.
- Еще раз отмечу - цепочки INPUT и OUTPUT работают только для тех пакетов, которые адресованы локальной машине, в нашем случае это сам сервер.
- Фактически, пакет из локальной сети в интернет проходит две (упрощенно) цепочки: FORWARD -> POSTROUTING. Более детальное описание этапов прохождения пакетов через iptables смотрите в статье "Порядок прохождения таблиц и цепочек IPTABLES". Поэтому все ограничения клиентов локальной сети (разрешить ли ICQ, WWW, POP3 и т.п.) настраиваются правилами FORWARD (секция #FORWARD chain). Например, для того, чтобы разрешить доступ только к сайтам, пишем:
$IPT -A FORWARD -i $IF_INT -o $IF_EXT -dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Правило по-умолчанию ($IPT -A FORWARD -i $IF_INT -o $IF_EXT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT) естественно, удаляем либо комментируем символом #. - Для того, чтобы после перезагрузки правила iptables не стирались, после того, как выполните скрипт iptables.sh и убедитесь, что все работает так, как надо, выполните команду:
service iptables save
Эта команда сохранит настройки iptables. Эта команда подойдет для RHEL-основанных дистрибутивов. Для других не знаю. Если нужен универсальный метод - поместите запуск этого скрипта в автозагрузку. - Пожалуй, все. Естественно, если вы новичок, НИКОГДА не настраивайте правила iptables находясь не за клавиатурой самого сервера. Ведь если вы случайно запретите себе доступ, то придется ноги-в-руки-и-на-работу :) Если вы уже знаете, что делаете, это к вам не относится.
- Если есть вопросы, пишите!
Авторизуйтесь для добавления комментариев!
Чуть-чуть ликбеза. Мы настроим (1) forwarding (маршрутизацию) и (2) NAT (netowrk address translation).
(1) Маршрутизация (forwarding) в данном случае означает, что когда пакет из локальной сети в поисках "ya.ru" (или иного сайта или внешнего IP) попадает на наш шлюз, то шлюз должен знать, что такие пакеты надо передать на внешний интерфейс (eth0) - мол, летите, соколы, дальше. Дальше точно так же (ну, пусть не точно также, ну пусть и совсем не так же) от одного узла до другого провайдеры перекидывают наш пакет все дальше от нас и все ближе к цели.
(2) NAT. Как много в этом слове... Пример. Вася открывает сайт ya.ru (IP: 213.180.193.3). Т.к. в локальной сети IP-адреса локальные (не маршрутизируются в интернет, ну никак), то наш шлюз подменяет адрес источника пакета (ноутбук Васи, src=192.168.1.134) на свой собственный IP адрес (src=1.2.3.4), выданный провайдером. Сайт ya.ru будет считать, что IP Васи не 192.168.1.134, а 1.2.3.4. И ответный пакет ya.ru отправит нашему шлюзу. При получении ответа от удаленного сервера наш шлюз вспомнит, какая локальная машина запрашивала 213.180.193.3 и в ответном пакете поменяет dst с 1.2.3.4 на 192.168.1.134.
Такой NAT еще называют SNAT (Source NAT), т.к. изначально меняется адрес источника (src, source). Есть другой NAT - DNAT (destination nat, dst nat). Но морочить себе голову сейчас мы не дадим, не так ли ;)