4

Первоначально опубликовано в Unix и Linux, но никто не смог ответить на него, поэтому перенесу вопрос здесь:

Мой вопрос касается маршрутизации на основе исходного кода на CentOS 5 с 2 WAN плюс порт LAN (NAT) с балансировкой нагрузки, но прежде чем что-то делать, прежде чем начать описывать проблему ...

Я знаю, что эта тема много раз поднималась здесь при обмене стеками, и кажется, что 5 лучших ответов (упорядочены от большинства к наименьшему):

  1. Отключить rp_filter
  2. Маркировка /Connmark на основе политики маршрутизации
  3. Маршрутизация на основе IP-адресов (добавьте больше IP-адресов)
  4. Установите pfSense, Shorewall, Ubuntu?, и т.д.
  5. Купить дорогой Cisco /3com /Juniper /Etc ... маршрутизатор

В большинстве случаев некоторые из этих ответов верны, но для меня решения 1 и 2 не имеют тренировки (я не отказываюсь по крайней мере от пункта 2, потому что у меня могут быть некоторые проблемы с моей настройкой), пункт 3 в основном изолирует проблему вместо того, чтобы ее решать (что также усложняет таблицы маршрутизации), решения 4 и 5 просто не входят в сферу применения, поскольку у меня нет ресурсов для покупки специализированного оборудования и я не могу отключить сервер, поскольку он находится в производстве, чтобы подвести итог замене сервер CentOS с чем-то "лучше" снят со стола.

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

Интерфейсы:

eth1: IP: 10.0.0.1, GW: 10.0.0.1, NM: 255.255.255.0 (LAN)
eth0: IP: 10.0.1.1, GW: 10.0.1.254, NM: 255.255.255.0 (ISP1 - ADSL Router)
eth2: IP: 10.0.2.1, GW: 10.0.2.254, NM: 255.255.255.0 (ISP2 - ADSL Router)

/etc/sysctl.conf:

# Controls IP packet forwarding
net.ipv4.ip_forward = 1

# Controls source route verification
net.ipv4.conf.default.rp_filter = 0

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1

# Ignoring broadcasts request
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_messages = 1

/ и т.д. / iproute2 / rt_tables:

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
2 ISP1
3 ISP2

/etc/sysconfig/network-scripts/route-eth0:

10.0.1.0/24 dev eth0 src 10.0.1.1 table ISP1
default via 10.0.1.254 dev eth0 table ISP1

/etc/sysconfig/network-scripts/route-eth2:

10.0.2.0/24 dev eth2 src 10.0.2.1 table ISP2
default via 10.0.2.254 dev eth2 table ISP2

/etc/sysconfig/network-scripts/rule-eth0:

fwmark 2 table ISP1
from 10.0.1.1 table ISP1

/etc/sysconfig/network-scripts/rule-eth2:

fwmark 3 table ISP2
from 10.0.2.1 table ISP2

/etc/sysconfig/iptables:

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Basic Rules
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT

# SSH
-A INPUT -i eth0 -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -i eth2 -m tcp -p tcp --dport 22 -j ACCEPT

# OpenVPN
-A INPUT -i eth0 -m udp -p udp --dport 1194 -j ACCEPT
-A INPUT -i eth2 -m udp -p udp --dport 1194 -j ACCEPT

# Allow everything from LAN
-A INPUT -i eth1 -j ACCEPT

# Allow everything from the VPN
-A INPUT -i tun0 -j ACCEPT

# Default Drop on everything else
-A INPUT -j DROP

# Allow forwarding from LAN and VPN
-A FORWARD -i eth1 -j ACCEPT
-A FORWARD -i tun0 -j ACCEPT

# Allow all outbound traffic
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth1 -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# DNAT to Developer Box (SSH Server)
-A PREROUTING -i eth0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222
-A PREROUTING -i eth2 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222

# SNAT
-A POSTROUTING -o eth0 -j SNAT --to-source 10.0.1.1
-A POSTROUTING -o eth2 -j SNAT --to-source 10.0.2.1
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# Mark Based Routing? (based on NerdBoys site)
-A PREROUTING -j CONNMARK --restore-mark
-A PREROUTING --match mark --mark 2 -j ACCEPT
-A PREROUTING -i eth0 -j MARK --set-mark 2
-A PREROUTING --match mark --mark 3 -j ACCEPT
-A PREROUTING -i eth2 -j MARK --set-mark 3
-A PREROUTING -j CONNMARK --save-mark
COMMIT

Балансировка нагрузки возможна с помощью скрипта gwping bash, который в основном отслеживает 2 wans (eth0 и eth2) и устанавливает маршруты и веса по умолчанию на сервере следующим образом (при балансировке нагрузки или при 2 wans):

ip route replace default scope global nexthop via 10.0.1.1 dev eth0 weight 1 nexthop via 10.0.2.1 dev eth1 weight 1

Проблема, которая у меня есть, заключается в том, что даже с этой настройкой, что многие люди сходятся во мнении, является правильным, у меня все еще есть проблемы с доступом к службам внутри сети извне (в частности, с коробкой разработчика ssh и OpenVPN), даже если пакеты "помечаются" и маршрутизируются соответственно, ответ из окна разработки всегда идет по неверному пути. Я не знаю, пропускаю ли я что-то в области mangle или nat или вообще неправильно понимаю маршрутизацию на основе источника, в любом случае, если кто-то знает, как сделать эту работу соответствующим образом, это будет любезно оценено.

Мои источники для этой настройки:

lartc.org/lartc.html#LARTC.RPDB.MULTIPLE-LINKS
fatalsite.net/?p=90
nerdboys.com/2006/05/05/conning-the-mark-multiwan-connections-using-iptables-mark-connmark-and-iproute2/
policyrouting.org/PolicyRoutingBook/ONLINE/CH08.web.html
unix.stackexchange.com/questions/58635/iptables-set-mark-route-diferent-ports-through-different-interfaces
unix.stackexchange.com/questions/22770/two-interfaces-two-addresses-two-gateways
bulma.net/body.phtml?nIdNoticia=2145

С наилучшими пожеланиями

PS1: я обнаружил веб-сайт, на котором написано, что метки в таблице маршрутизации должны отличаться от меток iptables + 1 (kim.attr.ee/2010/08/source-based-policy-routing-on-centos.html) Это правда? или этот сайт супер-неправильный.


Обновление 15/08/2013 22:15

После дополнительных исследований и отладки я обнаружил веб-сайт, на котором написано, что я забыл добавить часть SNAT в таблицу пост-маршрутизации, поэтому я добавил следующие правила в конфигурацию iptables:

-A POSTROUTING --match mark --mark 2 -j SNAT --to-source 10.0.1.1
-A POSTROUTING --match mark --mark 3 -j SNAT --to-source 10.0.2.1

Но я все еще не могу подключиться к devbox извне сети. С хорошей стороны, iptables -t nat -nvL POSTROUTING дает подсказку о том, как работает политика маршрутизации на основе connmark, так что, возможно, что-то связано на границе маршрутизатора ISP1 и ISP2:

Chain POSTROUTING (policy ACCEPT 520 packets, 56738 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 SNAT       all  --  *      *       0.0.0.0/0            0.0.0.0/0           MARK match 0x2 to:10.0.1.1
    6   312 SNAT       all  --  *      *       0.0.0.0/0            0.0.0.0/0           MARK match 0x3 to:10.0.2.1
  903 70490 SNAT       all  --  *      eth0    0.0.0.0/0            0.0.0.0/0           to:10.0.1.1
  931 78070 SNAT       all  --  *      eth2    0.0.0.0/0            0.0.0.0/0           to:10.0.2.1

Также я добавляю больше информации из моей установки, пожалуйста, кто-нибудь, бросьте мне спасательный круг, так как у меня заканчиваются идеи ...>. <

ip route show:

10.8.0.2 dev tun0  proto kernel  scope link  src 10.8.0.1
10.0.2.0/24 dev eth2  proto kernel  scope link  src 10.0.2.1
10.0.0.0/24 dev eth1  proto kernel  scope link  src 10.0.0.1
10.8.0.0/24 via 10.8.0.2 dev tun0
10.0.1.0/24 dev eth0  proto kernel  scope link  src 10.0.1.1
169.254.0.0/16 dev eth2  scope link
default
        nexthop via 10.0.1.254  dev eth0 weight 1
        nexthop via 10.0.2.254  dev eth2 weight 1

ip rule show:

0:      from all lookup 255
1024:   from all fwmark 0x2 lookup ISP1
1025:   from all fwmark 0x3 lookup ISP2
2024:   from 10.0.1.1 lookup ISP1
2025:   from 10.0.2.1 lookup ISP2
32766:  from all lookup main
32767:  from all lookup default

Новые источники:

sarcasmasaservice.com/2013/04/linux-routing-capabilities-my-abuse-thereof/

С наилучшими пожеланиями

3 ответа3

4

Что ж...

После тысяч часов отладки, попыток различных настроек и 72 часов интенсивного тестирования на производстве я смог найти правильное решение / настройку, проблема была в правилах iptables (раздел mangle), пакеты, по-видимому, были помечены правильно при входе но когда они выходят, для dnat'ted пакетов ничего не было, в любом случае, вот мое окончательное решение моей проблемы:

/etc/sysconfig/iptables:

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Basic Rules
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth2 -m state --state RELATED,ESTABLISHED -j ACCEPT

# SSH
-A INPUT -i eth0 -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -i eth2 -m tcp -p tcp --dport 22 -j ACCEPT

# OpenVPN
-A INPUT -i eth0 -m udp -p udp --dport 1194 -j ACCEPT
-A INPUT -i eth2 -m udp -p udp --dport 1194 -j ACCEPT

# Allow everything from LAN
-A INPUT -i eth1 -j ACCEPT

# Allow everything from the VPN
-A INPUT -i tun0 -j ACCEPT

# Default Drop on everything else
-A INPUT -j DROP

# Allow forwarding from LAN and VPN
-A FORWARD -i eth1 -j ACCEPT
-A FORWARD -i tun0 -j ACCEPT

# Allow all outbound traffic
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -o eth1 -j ACCEPT
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# DNAT to Developer Box (SSH Server)
-A PREROUTING -i eth0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222
-A PREROUTING -i eth2 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.200:2222

# SNAT
-A POSTROUTING -o eth0 -j SNAT --to-source 10.0.1.1
-A POSTROUTING -o eth2 -j SNAT --to-source 10.0.2.1
COMMIT

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# CONNMARK Source Based Routing
-A PREROUTING -i eth0 -m state --state NEW,RELATED,ESTABLISHED -d 10.0.1.1 -j CONNMARK --set-mark 0x2
-A PREROUTING -i eth2 -m state --state NEW,RELATED,ESTABLISHED -d 10.0.2.1 -j CONNMARK --set-mark 0x3
-A PREROUTING -i eth1 -m connmark --mark 0x2 -j CONNMARK --restore-mark
-A PREROUTING -i eth1 -m connmark --mark 0x3 -j CONNMARK --restore-mark
-A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
COMMIT

Очевидно, плюс все предыдущие настройки, связанные с iproute и gwping (для балансировки нагрузки на канал и восстановления после отказа), решения стали возможными благодаря источникам [1] и [2], которые указали мне на другую часть (Luca Gibelli для часть PREROUTING и Карл Боуден (часть OUTPUT) решения, а также другие источники для других веб-сайтов, которые указали мне правильное направление поиска. Надеюсь, что это поможет другому сисадмину в будущем.

С наилучшими пожеланиями

Источники:

[1]www.nervous.it/2010/09/dnat-and-ip-source-routing-woes/
[2]blog.khax.net/2009/12/01/multi-gateway-balancing-with-iptables/
[3]home.regit.org/netfilter-en/links-load-balancing/
[4]mailman.ds9a.nl/pipermail/lartc/2006q2/018964.html
[5]web.archive.org/web/20120320115329/http://versa.net.au/index.php?option=com_content&task=view&id=21&Itemid=34

Обновление 10/10/2013

OpenVPN требует дополнительной директивы конфигурации для работы с множественной установкой wan (как и предыдущая), поэтому просто добавьте параметр multihome в ваш server.conf (OpenVPN> = 2.1, для более низких версий просто измените локальную директиву, чтобы прослушивать только в конкретный айпи) и тебе хорошо идти.

0

просто совет для вас. Я делаю то же самое, но без балансировки нагрузки и трех ссылок, и я даже не использую iptables для всего этого. Я считаю, что использование простой маршрутизации на основе политик и socat намного эффективнее

мои rt_tables:

100     lan
102     wireless
103     wan1
104     wan2
105     wan3

в интерфейсах для каждой ссылки WAN:

/bin/ip route add <wan network id> dev eth0 src <wan host ip> table wan1
/bin/ip route add default via <wan gateway address> table wan1
/bin/ip rule add from <wan host ip> table wan1

в интерфейсах вниз для каждой ссылки WAN:

/bin/ip route del default via <wan gateway address> table wan1
/bin/ip rule del from <wan host ip> table wan1

вынудить клиента локальной сети определенную ссылку: поместите это в свой сценарий up интерфейса:

/bin/ip rule add from <lan client ip> table <wan table number of link to force it through>

и это в сценарии вниз:

/bin/ip rule del from <lan client ip> table <wan table number of link to force it through>

чтобы отправить входящее соединение на конкретную машину (например, веб-сервер), добавьте что-то подобное в rc.local (это может работать, когда связь установлена или нет)

exec socat -T15 tcp4-listen:80,reuseaddr,fork tcp:<lan host ip to send it to>:80 >> /var/log/socat-web.log 2>&1

затем включите IP-пересылку и маскарад, а также любые другие правила брандмауэра, которые вам нужны

в Ubuntu вы можете даже создать выскочку для socat, это мой /etc/init/socat-web.conf:

description "socat web port tunnel"
author      "jacqueline"

start on started mountall
stop on shutdown
respawn
respawn limit 99 5

script
    export HOME="/root"
    exec socat -T15 tcp4-listen:80,reuseaddr,fork tcp:192.168.0.97:80 >> /var/log/socat-web.log 2>&1
end script

post-start script
   # Optionally put a script here that will notifiy you socat has (re)started
end script
0

@CentOS_noob

Во-первых, отличная работа и большое спасибо за обмен, большое спасибо! Я боролся с этим годами. :)

Если вы хотите направить указанные услуги по выбранной ссылке, вы можете сделать это так, как указано в ваших текущих правилах МАРКИРОВКИ.

iptables -t mangle -A PREROUTING -i br1 -s 10.1.1.2 -p tcp --dport 80 -m state --state NEW,RELATED,ESTABLISHED -j CONNMARK --set-mark 0x3
iptables -t mangle -A PREROUTING -i br1 -s 10.1.1.2 -p icmp  -j CONNMARK --set-mark 0x4

Куда:

br1 - is LAN interface
10.1.1.2 - is LAN's IP of some host.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .