Iptables, squid and DNS

Доброе время суток всем,

Возникла неприятная проблема. Поставил Оpen Suse 11.3 x32. На ней поднял DNS и Squid, т.к. собирался использовать эту машинку как шлюз в инет и прозрачный прокси.

Если запускать только как НАТ, то в сети машины получают инет. Если же запустить скипт Iptables, то инет пропадает, а также пропадают запросы на ДНС сервера :frowning:

Возможно, кто-то уже сталкивался с подобной проблемой и подделиться ее решением.

Заранее спасибо.

Так а правила iptables вы нам покажете? Телепаты в Шарм-эль-Шейхе… :slight_smile:
Или вы все службы поднимали с отключённым фаерволом, а теперь его включили и всё потеряли? =)

Почему не покажу, покажу. Просто вчера не успел его выложить.

Итак правила Iptables:

#!/bin/sh

MYHOST=‘192.168.0.1’
LAN=‘192.168.0.0/24’
WAN=‘1.1.1.0/24’
EX_ETH=eth0 #смотрит в инет #
IN_ETH=eth1 # смотрит в локалку #
PROXY_PORT=8080
PROXY_IP=192.168.0.1

EX_IP=

modprobe ip_conntrack_ftp
modprobe iptable_nat

IPTABLES=’/usr/sbin/iptables’
echo 0 > /proc/sys/net/ipv4/ip_forward

обнуляю цепочки

$IPTABLES --flush
$IPTABLES -t nat --flush
$IPTABLES -t mangle --flush
$IPTABLES --delete-chain
$IPTABLES -t nat --delete-chain
$IPTABLES -t mangle --delete-chain
$IPTABLES -t filter -F > /dev/null 2>&1
$IPTABLES -t filter -X > /dev/null 2>&1
$IPTABLES -t nat -F > /dev/null 2>&1
$IPTABLES -t nat -X > /dev/null 2>&1
$IPTABLES -t mangle -F > /dev/null 2>&1
$IPTABLES -t mangle -X > /dev/null 2>&1
$IPTABLES -t filter -P INPUT ACCEPT > /dev/null 2>&1
$IPTABLES -t filter -P OUTPUT ACCEPT > /dev/null 2>&1
$IPTABLES -t filter -P FORWARD ACCEPT > /dev/null 2>&1
$IPTABLES -t nat -P PREROUTING ACCEPT > /dev/null 2>&1
$IPTABLES -t nat -P POSTROUTING ACCEPT > /dev/null 2>&1
$IPTABLES -t nat -P OUTPUT ACCEPT > /dev/null 2>&1
$IPTABLES -t mangle -P POSTROUTING ACCEPT > /dev/null 2>&1
$IPTABLES -t mangle -P OUTPUT ACCEPT > /dev/null 2>&1
$IPTABLES -t mangle -P PREROUTING ACCEPT > /dev/null 2>&1
$IPTABLES -t mangle -P INPUT ACCEPT > /dev/null 2>&1
$IPTABLES -t mangle -P FORWARD ACCEPT > /dev/null 2>&1

задаю политики по умолчанию#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
echo 1 > /proc/sys/net/ipv4/ip_forward

$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

$IPTABLES -A INPUT -p icmp --icmp-type 8 -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type 0 -j ACCEPT
$IPTABLES -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT

$IPTABLES -A INPUT -p udp -s $LAN --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -p udp -d $LAN --sport 53 -j ACCEPT
$IPTABLES -A INPUT -p udp -s $WAN --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -p udp -d $WAN --sport 53 -j ACCEPT

$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 80 -j ACCEPT
$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 443 -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -m state --state NEW --dport 80 -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -m state --state NEW --dport 443 -j ACCEPT

$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 21 -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -m state --state NEW --sport 20 -j ACCEPT
$IPTABLES -A INPUT -p tcp -m state --state NEW --dport 4000:4029 -j ACCEPT

$IPTABLES -A OUTPUT -p tcp -m state --state NEW --dport 25 -j ACCEPT
$IPTABLES -A OUTPUT -p tcp -m state --state NEW --dport 110 -j ACCEPT

$IPTABLES -A POSTROUTING -t nat -o $EX_ETH -s $LAN -d 0/0 -j MASQUERADE
$IPTABLES -A FORWARD -t filter -o $EX_ETH -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -t filter -i $IN_ETH -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -t nat -A PREROUTING -p tcp -i $EX_ETH -d $EX_IP --dport 80 --sport 1024:65535 -j DNAT --to 192.168.0.2:80
$IPTABLES -A FORWARD -p tcp -i $EX_ETH -o $IN_ETH -d 192.168.0.2 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -t filter -i $IN_ETH -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -t filter -i $EX_ETH -m state --state ESTABLISHED,RELATED -j ACCEPT

$IPTABLES -t nat -A PREROUTING -i $IN_ETH -p tcp --dport 80 -j REDIRECT --to-port $PROXY_PORT
$IPTABLES -t nat -A PREROUTING -i $IN_ETH -p tcp --dport 20 -j REDIRECT --to-port $PROXY_PORT
$IPTABLES -t nat -A PREROUTING -i $IN_ETH -p tcp --dport 21 -j REDIRECT --to-port $PROXY_PORT

Ну вот вроде показал правила,
и что-то гуру молчат :frowning:

Может быть у кого есть идеи? или подскажите где не так?

Заранее спасибо.

susefirewall2 Что с ним включен\выключен, вы уверены что от него в системе не остается своих правил, настроек и т.п. Если вы используете свой скрип, для настройки фаервола.
Смотрите какие реально используются правила через iptables.

Не очень понял фразу

Если запускать только как НАТ … Если же запустить скипт Iptables

Как вы запускаете только нат? если он в любом случае реализуется с помощью правил Iptables?

Попробуйте с каждой проблемой разбираться отдельно, насколько я понял запущен локальный кеширующий DNS, сделайте к нему запросы (подключитесь запросите ардрес), не можете подключится дело одно, Днс не может запросить запрос у сервер адальше другое. через tcpdump можно посмотреть что происходит. С ДНС разобрались где проблема идем дальше.

Если через нат работает через прокси нет, то подключаемся к прокси на 8080 так работает? Да у сквида в настройках прописано работать в прозрачном режиме?

Насчет Susefirewall2, он вообще был удален из системы. Насчет оставляет свои правила или нет не уверен.
Правила, которые я использую для настройки Iptables приведены выше.

Вы совершенно правильно поняли, я поднял локальный кеширующий ДНС. И как раз таки с ним сейчас у меня основые проблемы, вернее я так подозреваю, что проблемы с настройками Iptables.

Насчет НАТ, я имею ввиду, что если из всех правил Iptables оставить только
$IPTABLES -A FORWARD -p tcp -i $EX_ETH -o $IN_ETH -d 192.168.0.2 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -t filter -i $IN_ETH -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -t filter -i $EX_ETH -m state --state ESTABLISHED,RELATED -j ACCEPT

тогда, мои запросы к ДНС серверу обрабатываются, как на локальном сервере, так и на машинах в локальной сети.

Если же я запускую всю цепочку вышеприведенных правил, то мой ДНС загибается. Я не могу осщуствить запрос к нему ни с самого ДНС сервера, ни с машин в локальной сети. При этом, если в сетевых интерфейсах локальных машин указать в качестве ДНС сервера, адреса ДНС-серверов провайдера, то запросы отрабатываются. Следовательно делаю вывод, что что-то не так в правилах Iptables.

Пожалуйста, если у кого есть рабочие правила скиньте, чтобы посмотреть в чем может быть причина?

Для информации:
В настройках named.conf я указываю ему ДНС сервера моего провайдера и говорю,что сначала шел форфардинг.

Еще раз призываю вас, попробовать понять что у вас происходит и из этого исходить. А не копировать правила не понимая что они делают. Попробуем разобрать правило, которое вы привели в качестве функции НАТ.
$IPTABLES -A FORWARD -p tcp -i $EX_ETH -o $IN_ETH -d 192.168.0.2 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT

Берем только пакеты
-p tcp - протокола TCP
-i $EX_ETH - пришедшие на внешний интерфейс eth0 ( тоесть из интернета)
-o $IN_ETH - собирающиеся уйти в eth1 (локалку)
-d 192.168.0.2 - только те где адрес получателя 192.168.0.2
–dport 80 - порт получателя 80
–sport 1024:65535 порт отправителя в диапазоне от 1024 до 65535
Действие пропустить, Вы уверены что к вам из интернета может придти пакет с адресом получателя 192.168.0.2? Мне кажется правило никогда не сработает. И функциональности NАТ-а, то есть подмены адреса в этом правиле нет. Эти 3 представленные вами правила никакого ната не дадут.

Для того что бы посмотреть какие правила у вас работаю действительно а не какие вы пытаетесь добавить с помощью скрипта используйте команду iptables -t таблица] -L цепочка]

Я не большой знаток iptables и могу ошибаться но последовательность правил играет роль, срабатывает первое подходящее по критериям, у вас получается с начало все блокируем

задаю политики по умолчанию#

$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
А до разрешающих правил дело может и не дойти, не уверен что с дефолтными это работает именно так, но обычно блокировка всего оставшегося пишется в конце.

В предыдущий раз я предложил вам проверить, можете ли вы подключится к своему серверу DNS из локальной сети или нет, сделать это можно утилитой nslookup если не можете значит либо сервер не работает, либо правила блокирую к нему доступ. Если подключится можете но он не может вам ответить на запрос, значит он не может обращаться во внешний мир это уже другие правила.
Посмотреть что мы блокируем или наоборот пропускам можно например с помощью параметра -j LOG так же есть замечательная утилита tcpdump.

Не подумайте что я пытаюсь умничать, или обидеть вас. Скорее наоборот, сам с правилами имел дело очень давно, и уже все забыл. Просто пытаюсь показать вам направление в котором надо действовать. Так как задачи у всех разные, и способы решения тоже и за вас, фаервол на вряли кто нибудь настроит, сказав вам что конкретно нужно делать. Так как имхо с вашей задачей вполне хватило бы стандартного сусешного фаервола, и галочки маскарадинга. ну может быть + одно правило для proxy. Да и мои вполне конкретные предложения вы не выполнили.

Gankov,

Прошу прощения, не заметил, что вместе с правилами НАТ скопировал порт-маппинг. Мне это правило понадобиться в будущем, т.к. оно дает возможность привязать какой-либо севриз внутри сети к внешнему Ip. В моем случае это будет корпоративный портал. Так что вы тут не правы, что это правило не сработает, оно как раз-таки сработает, это тоже самое, если вы на обычном маршутизаторе сделаете привязку портов :slight_smile:

Насчет политики по умолчанию, вы тоже не правы. Т.е. проще задать сначало все запретить, а потом уже разрешать то, что нужно. Такой же принцип как в Squid, или в любом другом фаейрволе. Хотя конечно, можно все открыть, а потом закрывать все порты :slight_smile: Хотя вы правы насчет того, что порядок правил имеют значение, т.к. сработает первое подходящее по условию.

Я прекрасно понял все ваши советы. И я знаю, что у меня сейчас проблема именно с ДНС доступом. Т.е. как уже говорил, если не запускать все правила скрипка, а просто запустить НАТ, т.е. форвардинг с внутренного интерфейса к внешнему и маскарадинг адресов, то ДНС работает замечательно. Другими словами он обслуживает запросы локальной сети и запросы самого сервера.

Но как только я запускаю весь скрипт, который я привел ранее, то мой ДНС молчит, причем молчит как на самом сервере, так и с локальки. При этом если я прописыаю в сетевых интерфейсах локальных машин ДНС провайдера, то nslookup проходит, и как следствие идет разрешение имен и работает браузер.

В связи с этим я и прошу помощи разобраться, что не так с правилами iptables в отношении ДНС.

$IPTABLES -A INPUT -p udp -s $LAN --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -p udp -d $LAN --sport 53 -j ACCEPT
$IPTABLES -A INPUT -p udp -s $WAN --dport 53 -j ACCEPT
$IPTABLES -A OUTPUT -p udp -d $WAN --sport 53 -j ACCEPT.

При этом хочу заметить, что они прекрасно работали на Suse 10.3.

Ваши предложения я учел, просто насколько я знаю запросы ДНС не проходят через прокси, через него в основном идет трафик по 80 порту, т.е. весь Интернет, там даже было проблематично считать ftp трафик.

В одном вы совершенно правы никто за меня не создаст мои правила, но есть типичные правила для опреденных служб, в частности для ДНС. Поэтому я прошу у кого они работают на Suse 11.3 помочь мне разобраться и указать на мои ошибки в правилах.

Заранее спасибо.

Порядок имеет значение, если вы первым устанавливаете правило под которое подходят все пакеты и которое выбрасывает(DROP) эти пакеты, то ни один пакет не будет проверятся по разрешающим правилам, которых вы можете написать сколько угодно. С вашими четырьмя строчками с 53 портом вроде все в порядке, проблема в чем то другом и ее надо найти. Вы узнали где у вас отбрасываются пакеты? Я уже несколько раз намекал как узнать.
Хорошо давайте разбираться по пунктам:
1 - вывод команды iptables -nL и команды iptables -t nat -nL
2 - в правилах
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
Меняем DROP на ACCEPT все остальные правила оставляем и проверяем работает ли DNS, и желательно убедится что работает именно ваш DNS. Так мы проверим что отброс нужных нам пакетов происходит именно в этих политиках. Возвращаем все назад.
3 - В самый конец скрипта дописываем
iptables -t filter -A INPUT -j LOG --log-prefix “DROP INPUT”
iptables -t filter -A OUTPUT -j LOG --log-prefix “DROP OUTPUT”
Выполняем правила смотрим лог Видем все пакеты которые выбрасываем, ищем от нашей машины пытающейся подключится к нашему DNS.
4 - Если ничего интересного не выкидываем. Смотри через tcpdump а что приходит от машины делающей запрос DNS.

Остальные действия после результатов.

Gankov - не мутите воду! иногда лучше читать, чем говорить :wink:

Stranger_v_night

Все у вас правильно в большинстве случаев прописано в правилах. Единственное, что их не достаточно для работы ната))

политики по умолчанию лучше прописать ручками следующим образом:
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

$IPT -P PREROUTING ACCEPT -t nat
$IPT -P POSTROUTING ACCEPT -t nat
$IPT -P OUTPUT ACCEPT -t nat
$IPT -P INPUT ACCEPT -t nat

$IPT -P PREROUTING ACCEPT -t mangle
$IPT -P INPUT ACCEPT -t mangle
$IPT -P FORWARD ACCEPT -t mangle
$IPT -P OUTPUT ACCEPT -t mangle
$IPT -P POSTROUTING ACCEPT -t mangle

этого вполне достаточно (не забываем, конечно, про сами правила потом))))

не плохо бы юзать команду dmesg|tail для просмотра блокированных пакетов
ну и совсем хорошо добавиль следующие правила для наглядности:

router:/ # cat /etc/init.d/rc.firewall|grep LOG
$IPT -t filter -j LOG --log-level DEBUG --log-prefix "filter (inp) " -A INPUT
$IPT -t filter -j LOG --log-level DEBUG --log-prefix "filter (fwd) " -A FORWARD
$IPT -t nat -j LOG --log-level DEBUG --log-prefix "nat (post) " -A POSTROUTING
$IPT -t nat -j LOG --log-level DEBUG --log-prefix "nat (out) " -A OUTPUT
$IPT -t nat -j LOG --log-level DEBUG --log-prefix "nat (in) " -A INPUT
$IPT -t filter -j LOG --log-level DEBUG --log-prefix "filter (out) " -A OUTPUT

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

обращаться лучше в личку, т.к. тут бываю крайне редко…

А это пример простого скрипта для организации “NAT” в локальной сети на реальном внешнем адресе, т.е. разрешаем из локалки в инет всем все, запрещаем из инета в локалку все:

------------------------- начало примера ------------------
#!/bin/sh

Start/stop/restart iptables.

IPT=/usr/sbin/iptables

INT_DEV=eth1
EXT_DEV=eth0
EXT_IP=192.168.1.1
LAN=192.168.0.0/24

Start iptables:

ipt_start() {
echo “Start Firewall…”
#clear table and add default rule
$IPT -F
$IPT -X
$IPT -Z
$IPT -F -t nat
$IPT -X -t nat
$IPT -Z -t nat
$IPT -F -t mangle
$IPT -X -t mangle
$IPT -Z -t mangle
$IPT -F -t raw
$IPT -X -t raw
$IPT -Z -t raw
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP

$IPT -P PREROUTING ACCEPT -t nat
$IPT -P POSTROUTING ACCEPT -t nat
$IPT -P OUTPUT ACCEPT -t nat
$IPT -P INPUT ACCEPT -t nat

$IPT -P PREROUTING ACCEPT -t mangle
$IPT -P INPUT ACCEPT -t mangle
$IPT -P FORWARD ACCEPT -t mangle
$IPT -P OUTPUT ACCEPT -t mangle
$IPT -P POSTROUTING ACCEPT -t mangle

$IPT -P PREROUTING ACCEPT -t raw

$IPT -P INPUT ACCEPT -t raw

$IPT -P FORWARD ACCEPT -t raw

$IPT -P OUTPUT ACCEPT -t raw

$IPT -P POSTROUTING ACCEPT -t raw

#######add main rule

##INPUT
$IPT -A INPUT -j ACCEPT -i lo
$IPT -A INPUT -m state --state INVALID -j DROP
$IPT -A INPUT --fragment -p ICMP -j DROP
$IPT -A INPUT -j DROP -i $EXT_DEV -m addrtype --dst-type broadcast
$IPT -A INPUT -j ACCEPT -i $INT_DEV -s $LAN
$IPT -A INPUT -j ACCEPT -m state --state related,established
$IPT -t filter -j LOG --log-level DEBUG --log-prefix "filter (inp) " -A INPUT

FORWARD

$IPT -A FORWARD -j ACCEPT -i $INT_DEV
$IPT -A FORWARD -j ACCEPT -i $EXT_DEV -m state --state related,established
$IPT -t filter -j LOG --log-level DEBUG --log-prefix "filter (fwd) " -A FORWARD

PREROUTING

$IPT -t nat -A PREROUTING -j REDIRECT -p tcp -m multiport --dport 80 --to-ports 3128 ! -d 192.168.0.0/16
$IPT -t nat -j LOG --log-level DEBUG --log-prefix "nat (pre) " -A PREROUTING

POSTROUTING

$IPT -t nat -A POSTROUTING -s $EXT_IP -o $EXT_DEV -j SNAT --to-source $EXT_IP
IPT -t nat -A POSTROUTING -s $LAN -o $EXT_DEV -j SNAT --to-source $EXT_IP
$IPT -t nat -j LOG --log-level DEBUG --log-prefix "nat (post) " -A POSTROUTING

OUTPUT

$IPT -A OUTPUT -j ACCEPT -o lo
$IPT -A OUTPUT -j DROP -o $EXT_DEV -m addrtype --dst-type broadcast
$IPT -A OUTPUT --fragment -p ICMP -j DROP
$IPT -A OUTPUT -j ACCEPT -s $LAN
$IPT -A OUTPUT -j ACCEPT -o $EXT_DEV
$IPT -t filter -j LOG --log-level DEBUG --log-prefix "filter (out) " -A OUTPUT

#start forward
echo 1 > /proc/sys/net/ipv4/ip_forward
#add static route

if -f /etc/init.d/rc.route]; then /etc/init.d/rc.route; fi

ipt_stop() {
echo 0 > /proc/sys/net/ipv4/ip_forward
echo “Stopping firewall… all rule ACCEPT”

$IPT -F
$IPT -X
$IPT -Z
$IPT -F -t nat
$IPT -X -t nat
$IPT -Z -t nat

$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT

$IPT -P INPUT ACCEPT -t nat
$IPT -P OUTPUT ACCEPT -t nat
$IPT -P PREROUTING ACCEPT -t nat
$IPT -P POSTROUTING ACCEPT -t nat

$IPT -A INPUT -j ACCEPT -i lo
$IPT -A INPUT -j ACCEPT -i $INT_DEV -s $LAN
$IPT -A INPUT -j ACCEPT -i $EXT_DEV
$IPT -A OUTPUT -j ACCEPT -o lo
$IPT -A OUTPUT -j ACCEPT -o $INT_DEV -d $LAN
$IPT -A OUTPUT -j ACCEPT -o $EXT_DEV

}

Restart iptables:

ipt_restart() {
ipt_stop
sleep 1
ipt_start
}

case “$1” in
‘start’)
ipt_start
;;
‘stop’)
ipt_stop
;;
‘restart’)
ipt_restart
;;
*)
echo “usage $0 start|stop|restart”
esac

-------------------------- конец примера ------------------

PS: должно работать. если конечно чего не одзабыл сейчас) ну а далее свои привила в соответствии с конкретными запросами

Спасибо spetr78,
все сработало :slight_smile:
Только был прикол со сквидом, почему не захотел на родном порту 3128 вести логи,а переставил его на 8080, и логи пошли.

Буду смотреть свои правила и искать ошибку, в чем у них не так.