Имеем: шлюз с тремя сетевыми интерфейсами на openSUSE linux 11.3 (32bit). Два внешних смотрят в интернет (два разных провайдера). Внутренний интерфейс смотрит в локальную сеть. Также на шлюзе поднят squid (v3.0.STABLE25) и suseFirewall. Первый провайдер выдает адреса через DHCP, у второго - внешний IP.
Необходимо: http-запросы из локалки в зависимости от ip-шников юзеров посылать через squid либо к одному провайдеру, либо к другому.
Ознакомившись с темой принял решение делать маршрутизацию через iproute.
Для этого создал две дополнительные таблицы маршрутизации provider_1 и provider_2. Прописал таблицы в /etc/iproute2/rt_tables. Указал маршруты к соответствующим сетям (ip route add), указал правила для маршрутизации (ip rule add), написал скрипт в автозагрузку (/etc/init.d/after.local). В squid’е прописал acl и указал “tcp_outgoing_address” и “server_persistent_connections off” как и рекомендуют. В suseFirewall’е включил роутинг и маскарадинг.
Но… При попытке обращения к любому сайту через любого провайдера выдается сообщение что не удается определить ip-адрес источника:
"ERROR
The requested URL could not be retrieved
The following error was encountered while trying to retrieve the URL: Google
Unable to determine IP address from host name “www.google.ru”
The DNS server returned:
Server Failure: The name server was unable to process this query.
Допустим, у нас такие сетевые параметры:
Провайдер 1 (DHCP), eth1:
IP: 10.8.5.14
Mask: 255.255.0.0
Gate: 10.8.0.1
DNS1: 10.8.0.101
DNS2: 192.168.10.101
DNS3: 192.168.10.102
Провайдер 2 (Manual), eth2:
IP: 80.242.156.56
Mask: 255.255.255.252
Gate: 80.247.156.55
DNS1: 192.8.128.130
DNS2: 192.8.128.137
Локальная сеть, eth0:
IP: 192.168.0.10
Mask: 255.255.255.0
Содержимое скрипта (адаптировано для перезапуска):
#!/bin/sh
#Manual policy routing for 2 internet providers
ip route flush table provider_1
ip route flush table provider_2
ip route add default via 10.8.0.1 table provider_1
ip route add default via 80.242.156.55 table provider_2
ip route add 10.8.0.0/16 dev eth1 src 10.8.5.14 table provider_1
ip route add 80.242.156.56/30 dev eth2 src 80.242.156.56 table provider_2
ip route add 195.8.128.130 dev eth2
ip route add 195.8.128.137 dev eth2
ip route add 10.8.0.101 dev eth1
ip route add 192.168.10.101 dev eth1
ip route add 192.168.10.102 dev eth1
ip route add 192.168.0.0/24 dev eth0 table provider_1
ip route add 192.168.0.0/24 dev eth0 table provider_2
ip rule del table provider_1
ip rule del table provider_2
ip rule add from 10.8.5.14 lookup provider_1
ip rule add from 80.242.156.56 lookup provider_2
ip route flush cache
В squid’е прописано:
http_port 192.168.0.10:3128
acl prov_1 src 192.168.0.15-192.168.0.32
acl prov_1 src 192.168.0.44-192.168.0.128
tcp_outgoing_address 10.8.5.14 prov_1
tcp_outgoing_address 80.242.156.56 prov_2
server_persistent_connections off
В suseFirewall’е прописано:
FW_ROUTE=“yes”
FW_MASQUERADE=“yes”
FW_MASQ_DEV=“zone:ext”
FW_MASQ_NETS=“192.168.0.0/24”
Вывод route -n:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
80.242.156.56 0.0.0.0 255.255.255.252 U 0 0 0 eth2
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.8.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
Вывод ip ro:
80.242.156.56/30 dev eth2 proto kernel scope link src 80.242.156.56
192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.10
10.8.0.0/16 dev eth1 proto kernel scope link src 10.8.5.14
169.254.0.0/16 dev eth0 scope link
127.0.0.0/8 dev lo scope link
Вывод ip ru:
0: from all lookup local
32764: from 80.242.156.56 lookup provider_metrocom
32765: from 10.8.5.14 lookup provider_lenreg
32766: from all lookup main
32767: from all lookup default
Не могу понять в чем дело. Люди пишут у них все работает! Конфиги, вроде, теже у всех. Переписывал скрипт с легкими вариациями на тему “ip route add 127.0.0.0/8 dev lo table provider_1” [provider_2] – добавление локального маршрута в таблицу первого/второго провайдера; “ip route add 195.8.128.130 dev eth2 table provider_2”, " ip route add 10.8.0.101 dev eth1 table provider_1" – помещал DNS’ы из основной таблицы main в таблицы провайдеров. Но это ничего не дает.
В логах файрвола ничего криминального не обнаружил, блокированных соединений нет (даже с FW_LOG_DROP_ALL=“yes”). На всякий случай пробовал отключать: rcSuSEfirewall2 stop – без результата.
Что самое интересное: по отдельности каналы работают. Т.е. если вставить один кабель в сетевуху и указать соответствующий дефолтный шлюз в таблице main (именно в main!!!) – все живет прекрасно! Такое впечатление, что не обрабатываются дополнительные таблицы маршрутизации provider_1 и provider_2 (или криво обрабатываются как-то…).
Судя по выводу браузера есть проблемы с DNS. Но почему squid не может определить DNS-сервера – это вопрос. Кстати, в /etc/resolve.conf nameserver’ы прописаны, а squid оттуда должен считывать. Логи squid’а тоже малоинформативны - ничего не увидел.
Хотя squid -k parse выдает замечание:
“WARNING: failed to resolve 192.168.0.10 to a fully qualified hostname”, но с этим, по идее, должно все работать (можно вылечить с помощью visible_hostname). Пробовал подключаться и без сквида.
Нашел также что-то про “rp_filter”, но делу это не помогло.
Приветствуется любая помощь сообщества!