LINUX.ORG.RU
решено ФорумAdmin

Несколько таблиц маршрутизации

 , ,


2

2

Есть такая конфигурация:

client:
eth0 - lan

server:
eth0 - inet
eth1 - lan
tun0 - vpn over eth0

нужно маршрутизировать запросы клиента к различным портам на различные интерфейсы, например 80 - через tun0, остальное - eth0

Вначале пробую маршрутизацию всего трафика через vpn:

ip route add $vpn_external_ip via $inet_gate
ip route del default gw $inet_gate
ip route add default gw $tun0_ip

работает.

Теперь пытаюсь использовать две таблицы маршрутизации:

echo 2 myinet >> /etc/iproute2/rt_tables
ip route add default gw $inet_gate table myinet
ip rule add from all fwmark 1 table myinet
iptables -A PREROUTING -t mangle -i eth1 -p tcp --dport 80 -j MARK --set-mark 1

теперь все, кроме 80 порта работает.


Допустим, у тебя на eth1 адрес 192.168.1.1/24. Тогда добавь следующий маршрут:

ip route add 192.168.1.0/24 dev eth1 table myinet
Также для всех сеток, доступных непосредственно с интерфейсов твоего шлюза.

anonymous ()
Ответ на: комментарий от anonymous

не помогло

подозреваю, что ответы идут по другому маршруту, т.к. если в обоих таблицах одинаковые маршруты по умолчанию, то проблем нет

Ower ()
Ответ на: комментарий от Ower

для tun0 делал? маршруты, которые необходимо добавить, можно узнать так:

ip route | grep -v via
за исключением тех, которые для loopback'а

anonymous ()
Ответ на: комментарий от uspen

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

Ower ()

tcpdump. Запускаете на перехват пакетов на tun0 на 80 порт и пытаетесь что-нибудь загрузить с клиента. Там будет видно, проходят ли пакеты вобще (FORWARD), уходят ли с нужным src-ip адресом, чтобы ответ шёл тоже через тунель (SNAT), или вобще даже приходят ответные, но, опять таки, могут резаться в FORWARD.

mky ★★★★★ ()
Ответ на: комментарий от Ower

iptables -A PREROUTING -t mangle -i eth1 -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -t mangle -i eth1 -p tcp --dport 80 -j CONNMARK --set-mark 1

Я, кстати, не понял, что тебе нужно. Опиши подробнее (точнее).

uspen ★★★★★ ()
Последнее исправление: uspen (всего исправлений: 1)
Ответ на: комментарий от uspen

не помогло

хочу заставить трафик на определенные порты ходить через vpn, а остальной напрямую через провайдера

вроде такого:

[my client] -> [my server] -> [provider] -> [my vpn] -> [site:80] 
[my client] -> [my server] -> [provider] -> [site:!80]
Ower ()
Ответ на: комментарий от mky

таблицы:
main - маршрутизирует через tun0
myinet - маршрутизирует через eth0

запустил:

tcpdump -i eth0 -nn -p -e "(port 80) and (host $test_vps_ip)"

tcpdump -i tun0 -nn -p -e "(port 80) and (host $test_vps_ip)"

проверяю с включенной маркировкой(направляем через myinet):

telnet $test_vps_ip 80
Trying $test_vps_ip...
telnet: Unable to connect to remote host: Connection timed out

в tun0 - пусто
в eth0:

19:09:39.833634  ethertype IPv4 (0x0800), length 74: $my_external_ip.33898 > $test_vps_ip.80: Flags [S], seq 1810718277, win 29200, options [mss 1460,sackOK,TS val 619778817 ecr 0,nop,wscale 7], length 0
19:09:39.884527  ethertype IPv4 (0x0800), length 74: $test_vps_ip.80 > $my_external_ip.33898: Flags [S.], seq 3700842918, ack 1810718278, win 28960, options [mss 1460,sackOK,TS val 1191850 ecr 619778817,nop,wscale 8], length 0
19:09:40.833251  ethertype IPv4 (0x0800), length 74: $my_external_ip.33898 > $test_vps_ip.80: Flags [S], seq 1810718277, win 29200, options [mss 1460,sackOK,TS val 619779067 ecr 0,nop,wscale 7], length 0
19:09:40.885346  ethertype IPv4 (0x0800), length 74: $test_vps_ip.80 > $my_external_ip.33898: Flags [S.], seq 3700842918, ack 1810718278, win 28960, options [mss 1460,sackOK,TS val 1192100 ecr 619778817,nop,wscale 8], length 0
...

без маркировки(через main):

telnet $test_vps_ip 80
Trying $test_vps_ip...
Connected to $test_vps_ip.
Escape character is '^]'.

в eth0 - пусто
в tun0:

19:22:11.311907 ip: $tun0_ip.33992 > $test_vps_ip.80: Flags [S], seq 1762637369, win 29200, options [mss 1460,sackOK,TS val 619966695 ecr 0,nop,wscale 7], length 0
19:22:11.363531 ip: $test_vps_ip.80 > $tun0_ip.33992: Flags [S.], seq 3911398556, ack 1762637370, win 28960, options [mss 1352,sackOK,TS val 1379720 ecr 619966695,nop,wscale 8], length 0
19:22:11.363676 ip: $tun0_ip.33992 > $test_vps_ip.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 619966708 ecr 1379720], length 0

Ower ()
Ответ на: комментарий от Ower

Ты бы хоть на мой вопрос ответил, получил бы ответ быстрее.

По поводу твоего теста с маркировкой - либо добавь правило

iptables -t mangle -A PREROUTING -i eth0 -p tcp --sport 80 -j MARK --set-mark 1
, либо отключи rp_filter на eth0. Лучше первое, т.к. решает конкретно твою задачу.

anonymous ()
Ответ на: комментарий от anonymous

так маркированные пакеты как раз идут напрямую через провайдера и не используют vpn. зачем тогда добавлять tun0 в myinet?

твое правило никак не повлияло(сейчас посмотрю насчет rp_filter)

поведение пока что меняется только правилом:

iptables -A PREROUTING -t mangle -i eth1 -p tcp --dport 80 -j MARK --set-mark 1
но почему-то ack не уходит

Ower ()
Ответ на: комментарий от Ower

так маркированные пакеты как раз идут напрямую через провайдера и не используют vpn. зачем тогда добавлять tun0 в myinet?

Я был под впечатлением, что маркированные пакеты должны уходить через туннель. Видимо не так прочитал, ок.

но почему-то ack не уходит

Точно не уходит ack? Может быть, тебе во внутреннюю сетку syn+ack не приходит? Это как раз должно исправиться при отключении rp_filter.

anonymous ()
Ответ на: комментарий от anonymous
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter

ничего не поменялось

я уже для начала хотел бы хоть на сервере маршрутизацию настроить и с клиентом потом разберусь

Ower ()
Ответ на: комментарий от Ower

0 надо не в default писать, а конкретно в нужный интерфейс.

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

anonymous ()
Ответ на: комментарий от Ower

сделал всем интерфесам

По всем прошелся, или только в all записал? Сейчас проверил - при записи в all на остальных ничего не поменялось.

anonymous ()
Ответ на: комментарий от anonymous
ip rule
0:      from all lookup local 
32762:  from all fwmark 0x1 lookup myinet
32766:  from all lookup main 
32767:  from all lookup default 
ip route show table main
default via $tun0_ip dev tun0  scope link 
$eth1_net/24 dev eth0  proto kernel  scope link  src $eth1_ip
$vpn_ip via $inet_gate dev eth0 
$eth0_net/24 dev eth1  proto kernel  scope link  src $eth0_ip
ip route show table myinet
default via $inet_gate dev eth0 
Ower ()
Ответ на: комментарий от anonymous
iptables-save
*mangle
-A PREROUTING -i eth1 -p tcp -m tcp --dport 80 -j MARK --set-xmark 0x1/0xffffffff
-A PREROUTING -i eth0 -p tcp -m tcp --sport 80 -j MARK --set-xmark 0x1/0xffffffff

*nat
-A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
-A POSTROUTING -s 192.168.1.0/24 -o tun0 -j MASQUERADE
Ower ()
Ответ на: комментарий от Ower

Я же тебе говорил, что надо добавить маршрут:

ip route add $eth1_net/24 dev eth1 table myinet
После этого с текущими настройками у тебя и с включенным rp_filter все должно работать.

anonymous ()
Ответ на: комментарий от anonymous

я его добавлял, но убрал, т.к. ничего не изменилось

и сейчас тоже (

Flags [.], ack 1, не отправляется

постоянные

$my_external_ip.33904 > $test_vps_ip.80: Flags [S]
$test_vps_ip.80 > $my_external_ip.33904: Flags [S.]

то есть пакеты то идут в обе стороны но последний не отправляется почему-то

Ower ()
Ответ на: комментарий от anonymous

сделал rp_filter 0 для all(в дополнение к каждому отдельному интерфейсу)
теперь вроде работает - буду тестировать еще

спасибо за помощь

Ower ()

может быть пригодится кому-то

routing:

#!/bin/bash

eth_inet=eth0
eth_lan=eth1
tun_vpn=tun0

inet_gate_ip=
vpn_local_ip=
vpn_inet_ip=
eth_lan_ip=

table_myinet=myinet
table_vpn=vpn

for iface in all $eth_inet $eth_lan $tun_vpn;
do
  echo "Setting rp_filter=0 for ${iface}"
  echo 0 > "/proc/sys/net/ipv4/conf/${iface}/rp_filter"
done

if [[ `grep "${table_myinet}" /etc/iproute2/rt_tables` == "" ]]; then echo 2 $table_myinet >> /etc/iproute2/rt_tables; fi
if [[ `grep "${table_vpn}"    /etc/iproute2/rt_tables` == "" ]]; then echo 3 $table_vpn    >> /etc/iproute2/rt_tables; fi

ip route flush table $table_myinet
ip route add $eth_lan_ip/24 dev eth1 table $table_myinet
ip route add default via $inet_gate_ip table $table_myinet
printf "\nip route show table ${table_myinet}:\n"
ip route show table $table_myinet

ip route flush table $table_vpn
ip route add $vpn_inet_ip via $inet_gate_ip dev eth0 table $table_vpn
ip route add default via $vpn_local_ip dev tun0  scope link table $table_vpn
ip route add $eth_lan_ip/24 dev eth1 table $table_vpn
printf "\nip route show table ${table_vpn}:\n"
ip route show table $table_vpn

ip rule del fwmark 1 lookup $table_myinet
ip rule add fwmark 1 lookup $table_myinet

ip rule del fwmark 2 lookup $table_vpn
ip rule add fwmark 2 lookup $table_vpn

printf "\nip rule show:\n"
ip rule show

ports-over-vpn:

ports=(80 443)
vpn_mark=2
eth_local=eth1

opt_delete_rules=false

while getopts "d" opt; 
do
  case "$opt" 
  in
    d)
      opt_delete_rules=true
      ;;
  esac
done

iptables-save | grep -v rule_port_over_vpn | iptables-restore

if [ $opt_delete_rules == true ]
then
  exit 0;
fi

for port in ${ports[@]}
do
  iptables -A PREROUTING -t mangle -i $eth_local -p tcp -m tcp --dport $port -j MARK --set-mark $vpn_mark -m comment --comment rule_port_over_vpn
done

Ower ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.