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

Linux Advanced Routing: DNAT пакетов, отправленных на локальный адрес

 , , ,


1

1

ЛОР, побудь моим личным LARTC[2].

Вообще всё перерыл, даже на serverfault спросил, бестолку.

Есть линуксовый роутер (4.14), интерфейсы wan0 и lan0, адреса 1.2.3.4 и 10.0.0.1 соответственно.

# ip -4 addr
11: lan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 34:ce:00:66:f0:56 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/24 brd 10.0.0.255 scope global lan0
       valid_lft forever preferred_lft forever
13: wan0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc cake state UP group default qlen 1000
    link/ether 78:11:dc:01:32:70 brd ff:ff:ff:ff:ff:ff
    inet 1.2.3.4/24 brd 1.2.3.255 scope global wan0
       valid_lft forever preferred_lft forever

Внутри сети есть машина 10.0.0.2 с веб-сервером, который слушает на 10.0.0.2:443. Есть доменное имя domain.tld, которое ресолвится в 1.2.3.4. На роутере настроен DNAT (порт форвардинг) 1.2.3.4:443 в 10.0.0.2:443:

# iptables -t nat -S | egrep 'wan0|lan0|443'
-A PREROUTING -i wan0 -j zone_wan_prerouting
-A POSTROUTING -o lan0 -j zone_lan_postrouting
-A zone_lan_postrouting -s 10.0.0.0/24 -d 10.0.0.2/32 -p tcp -m tcp --dport 443 -j SNAT --to-source 10.0.0.1
-A zone_lan_prerouting -s 10.0.0.0/24 -d 1.2.3.4/32 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.0.2:443
-A zone_wan_prerouting -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.0.2:443

Проблема: если с роутера сделать curl https://domain.tld, то DNAT его не поймает.

Попробовал написать правило в OUTPUT, но это не сработало:

iptables -t nat -A OUTPUT -p tcp -d 1.2.3.4 --dport 443 -j DNAT --to-destination 10.0.0.2:443

Судя по tcpdump, DNAT срабатывает, но пакет (с подменённым адресом назначения) продолжает уходить с внешнего интерфейса.

Куда копать?

P. S.: без использования split DNS и прочих хаков (настоящий сетап гораздо более сложный, вкорячивать туда ещё и split DNS я хочу в последнюю очередь)

★★★★★

Последнее исправление: intelfx (всего исправлений: 2)

Ответ на: комментарий от Mike_RM

SNAT|MASQUERADE используется?

Ну, где-то (для lan->wan) — используется.

Тогда и должно уходить с внешнего интерфейса.

Так ведь не должно же :) Как бы там ни было, суть задачи (и суть вопроса) в том, чтобы уходило с внутреннего.

И если честно, вообще не вижу связи.

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

Поменяйте

-A POSTROUTING -o lan0 -j zone_lan_postrouting

На

-I POSTROUTING -o lan0 -j zone_lan_postrouting
Mike_RM
()
Последнее исправление: Mike_RM (всего исправлений: 1)

По этим документированным граблям ходим давно :)

http://inai.de/images/nf-packet-flow.svg

reroute check происходит после output/mangle, так что в output/nat уже нельзя сменить интерфейс.

IMHO Маркируй в output/mangle и роути через отдельную таблицу.

vel ★★★★★
()

настоящий сетап гораздо более сложный, вкорячивать туда ещё и split DNS я хочу в последнюю очередь

Чем сложнее реальный сетап, тем нужнее split DNS, настраивается один раз, потом легко изменяется и сопровождается, в отличии от наворотов с роутингом по таблицам.

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

Блин, а я сюда смотрю — https://en.wikipedia.org/wiki/Iptables#/media/File:Netfilter-packet-flow.svg — найдите десять отличий…

IMHO Маркируй в output/mangle и роути через отдельную таблицу.

Погоди, а как я роутить-то буду? После mangle у него адрес назначения всё ещё из wan будет, мне что, фейковую таблицу делать с default dev lan0?

UPD: ааа, понятно, табличка из википедии слишком новая для моего ядра, она для 5.1, а у меня 4.14 :)

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 2)

iptables -t nat -A OUTPUT -p tcp -d 1.2.3.4 --dport 443 -j DNAT --to-destination 10.0.0.2:443

Судя по tcpdump, DNAT срабатывает, но пакет (с подменённым адресом назначения) продолжает уходить с внешнего интерфейса.

Правило правильное, просто добавьте:

ip route add 10.0.0.2 dev lan0
Все должно заработать.

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

Почему фейковую? Специальную!

ip ro add default via 10.0.0.2 dev lan0 src 10.0.0.1 table 100

В википедии схема совсем старая.

Уже давно появилась input/nat, а в этих схемах ее до сих пон нет...

https://habr.com/ru/post/108690/ в конце

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

ip ro add default via 10.0.0.2 dev lan0 src 10.0.0.1 table 100

Какой кошмар. Уж лучше split DNS, чем это.

Других идей совсем нет? Как-нибудь обхачить внутри mangle нельзя?

В википедии схема совсем старая.

На ней написано, что она обновлена в мае 2019 и соответствует ядру 5.1. На твоей написано, что она от 2014 года и соответствует 2.6.36. Так кто же прав и где всё-таки reroute check?

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

Год или два назад здесь была аналогичная тема. Я специально тогда в исходниках смотрел и сейчас не поленился!

3.0, 3.4, 3.14, 3.18, 4.4, 4.9, 4.14, 4.19, 5.0, 5.1, 5.2

Практически буква в букву.

net/ipv4/netfilter/iptable_mangle.c:ipt_mangle_out()

        /* Save things which could affect route */
        mark = skb->mark;
        iph = ip_hdr(skb);
        saddr = iph->saddr;
        daddr = iph->daddr;
        tos = iph->tos;

        ret = ipt_do_table(skb, state, state->net->ipv4.iptable_mangle);
        /* Reroute for ANY change. */
        if (ret != NF_DROP && ret != NF_STOLEN) {
                iph = ip_hdr(skb);
                            
                if (iph->saddr != saddr ||
                    iph->daddr != daddr ||
                    skb->mark != mark ||
                    iph->tos != tos) {
                        err = ip_route_me_harder(state->net, skb, RTN_UNSPEC);
                        if (err < 0)
                                ret = NF_DROP_ERR(err);
                }
        }
Интересно? Этот код времен очакова и покорения крыма :)

интересно, чем бы штатным сменить daddr в mangle/output?

Какой кошмар. Уж лучше split DNS, чем это.

Ну не знаю. Если у тебя 1.5 зоны, то может быть и проще.

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

IlyaBobyr который правил картинку - чудак на букву му!

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

ip_route_me_harder

Восхитительно :)

интересно, чем бы штатным сменить daddr в mangle/output?

Тот же вопрос.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от anc

Так у меня и не пятое, а 4.14.

А что и как конкретно ты проверял?

Для протокола попробовал с -I, ничего не изменилось (и не должно было):

# iptables -t nat -F OUTPUT
# iptables -t nat -I OUTPUT -d 1.2.3.4 -p tcp --dport 4433 -j DNAT --to-destination 10.0.0.2
# iptables -t nat -S OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -d 1.2.3.4/32 -p tcp -m tcp --dport 4433 -j DNAT --to-destination 10.0.0.2
root@router:~# curl https://domain.tld:4433
^C

Параллельно:

# tcpdump -vvv -i wan0 'dst port 4433'
tcpdump: listening on wan0, link-type EN10MB (Ethernet), capture size 262144 bytes
04:49:05.285304 IP (tos 0x0, ttl 64, id 65247, offset 0, flags [DF], proto TCP (6), length 60)
    1.2.3.4.37946 > 10.0.0.2.4433: Flags [S], cksum 0x0c75 (incorrect -> 0xafe7), seq 2404737296, win 43690, options [mss 65495,sackOK,TS val 1569780611 ecr 0,nop,wscale 5], length 0
04:49:06.328403 IP (tos 0x0, ttl 64, id 65248, offset 0, flags [DF], proto TCP (6), length 60)
    1.2.3.4.37946 > 10.0.0.2.4433: Flags [S], cksum 0x0c75 (incorrect -> 0xabd4), seq 2404737296, win 43690, options [mss 65495,sackOK,TS val 1569781654 ecr 0,nop,wscale 5], length 0
04:49:08.408302 IP (tos 0x0, ttl 64, id 65249, offset 0, flags [DF], proto TCP (6), length 60)
    1.2.3.4.37946 > 10.0.0.2.4433: Flags [S], cksum 0x0c75 (incorrect -> 0xa3b4), seq 2404737296, win 43690, options [mss 65495,sackOK,TS val 1569783734 ecr 0,nop,wscale 5], length 0
04:49:12.488294 IP (tos 0x0, ttl 64, id 65250, offset 0, flags [DF], proto TCP (6), length 60)
    1.2.3.4.37946 > 10.0.0.2.4433: Flags [S], cksum 0x0c75 (incorrect -> 0x93c4), seq 2404737296, win 43690, options [mss 65495,sackOK,TS val 1569787814 ecr 0,nop,wscale 5], length 0
^C
4 packets captured
208 packets received by filter
137 packets dropped by kernel
# tcpdump -vvv -i lan0 'dst port 4433'
tcpdump: listening on lan0, link-type EN10MB (Ethernet), capture size 262144 bytes
^C
0 packets captured
17 packets received by filter
0 packets dropped by kernel

Как бы корень проблемы понятен (@vel выше привёл код — reroute check происходит до nat/OUTPUT). Непонятно только, что с этим можно сделать без банальных хаков с поддельными таблицами маршрутизации или поддельным DNS.

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

У меня тоже PBR :) Только PBR, очевидно, бывает разный.

А что конкретно сделано, что оно работает без дополнительных костылей?

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

Получать от dns правильный адрес

сплит-днс ради одного хоста - слишком жирно. В /etc/hosts прописать и не мучаться :)

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

В /etc/hosts прописать и не мучаться

Ну это тоже своеобразный split DNS… А что прописывать? Сразу адрес машины с сервером (10.0.0.2)? Не выйдет, у меня таких серверов несколько и на них DNAT с разных портов.

Вообще, пока это всё обсуждали, придумался обобщённый хак на таблицах роутинга:

iptables -t mangle -A OUTPUT -m addrtype --dst-type local -j MARK --set-mark 0x100/0x100
iptables -t nat -A OUTPUT -m mark --mark 0x100/0x100 -j zone_wan_prerouting  # zone_wan_prerouting — цепочка со всеми DNAT-ами
ip rule add priority 1000 fwmark 0x100/0x100 lookup 100
ip route add default dev lan0 table 100

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

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

у меня таких серверов несколько и на них DNAT с разных портов.

То есть DNS уже есть.

(и это вроде бы даже почти семантически верно)

Зато неверно идеологически, делать nat там, где он нафиг не сдался.

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

То есть DNS уже есть.

Ну что значит «уже есть»? Где-то, конечно, есть. Как-то же domain.tld ресолвится в 1.2.3.4.

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

Зато неверно идеологически, делать nat там, где он нафиг не сдался.

Да как бы раз уж IPv4 — натом больше, натом меньше, да какая собственно разница?

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

Ну что значит «уже есть»?

Там выше был квотинг, где ключевое слово - несколько серверов.

натом больше, натом меньше, да какая собственно разница?

Большая, он не бесплатен, как в работе, так и в обслуживании.

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

iptables -t mangle -A OUTPUT -m addrtype --dst-type local -j MARK --set-mark 0x100/0x100

ты уверен про "-m addrtype --dst-type local" ?

IMHO local - это все адреса хоста ( ip ro ls type local table local )

ip route add default dev lan0 table 100

На мой взгляд это плохо. У тебя через lan0 доступен только определенный диапазон адресов ?

Я бы туда скопировал маршруты из main

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

ты уверен про «-m addrtype –dst-type local» ?

Нет, не уверен, это как раз та часть, которая мне больше всего не нравится (потому что это семантически неверно). Но на практике это работает, т. к. других запросов с роутера к своему же внешнему адресу в принципе не производится.

А у тебя есть идеи, как это можно сделать, не хардкодя 1.2.3.4?

На мой взгляд это плохо. У тебя через lan0 доступен только определенный диапазон адресов ?

Естественно. Только 10.0.0.0/24.

Я бы туда скопировал маршруты из main

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

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

А у тебя есть идеи, как это можно сделать, не хардкодя 1.2.3.4?

В ipset загнать список.

ipset create dnat_list hash:ip,port skbinfo
ipset add dnat_list 1.2.3.4,tcp:443 skbmark 0x100

iptables -t mangle -A OUTPUT -j SET --map-set dnat_list dst,dst --map-mark

iptables -t nat -N dst_map

iptables -t nat -A dst_map -d 1.2.3.4 -p tcp --dport 443 -j DNAT  --to-destination 10.0.0.2

iptables -t nat -A OUTPUT -m set --match-set dnat_list dst,dst -j dst_map
Каждый доп. редирект - 2 действия: добавить в ipset и добавить правило в dst_map

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

Естественно. Только 10.0.0.0/24.

Только этот маршрут скопировать

можно выполнить ip ro add `ip ro ls dev lan0 proto kernel scope link` table 100 если адрес на lan0 только 1

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

В ipset загнать список.

Только ты захардкодил 1.2.3.4 аж два раза на каждое такое правило.

Говорю, ты знаешь способ сматчить пакеты, которые уходят на локальный адрес интерфейса wan0, не упоминая нигде в правиле этот адрес?

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

Только этот маршрут скопировать

Какой маршрут?

ip ro add `ip ro ls dev lan0 proto kernel scope link` table 100

Ээээ… А смысл? Этот маршрут у меня и в main есть. Только он не срабатывает, потому что во время прохождения пакета по таблице маршрутов у него daddr всё ещё 1.2.3.4. Толку от того, что я добавлю маршрут для 10.0.0.0/24? Он не сматчится и пакет пойдёт дальше по таблице правил. Возвращаемся к исходной проблеме топика.

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

Так он именно там и есть:

ip route add default dev lan0 table 100

Ладно, оставлю тогда как написал. Посмотрю, будет ли глючить из-за -m addrtype --dst-addr local, если вдруг будет — захардкожу -d 1.2.3.4.

Спасибо за помощь :)

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

Если не рассматривать дополнительные извраты, то вроде ничего сверхестественного. Таблица main идет в начале, defgw прописаны в отдельных таблицах, правила from $MY_ISP_IP (у меня два прова) заворачивают в соответствующие таблицы, потом правила для маркируемых пакетов, потом для всего остального from all в таблицы где defgw.

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

Если не рассматривать дополнительные извраты, то вроде ничего сверхестественного.... (у меня два прова)

Ну для multihome без полиси-рутинга никак. А для одного иногда и простой прокси-редиректор даже удобнее. От упрощения фильтрации до балансинга.

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

Дополню. Провы у меня pppoe и l2tp. От них же изначально получаю адреса и на eth*. Фактически эти адреса находятся в main, то есть второе правило после local. Всё работает и на них. Без всяких извратов. Точнее так, пофигу какой я пропишу адрес в цепочке OUTPUT в параметре -d робит на всех четырех (два eth* два ppp*). Предупреждая вопрос. Да, я это реально проверил, работает.

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

Таблица main идет в начале, defgw прописаны в отдельных таблицах, правила from $MY_ISP_IP (у меня два прова) заворачивают в соответствующие таблицы, потом правила для маркируемых пакетов, потом для всего остального from all в таблицы где defgw.

Так блин, у меня примерно такой же мультихоминг на PBR:

# ip rule
0:      from all lookup local
1000:   from all fwmark 0x100/0x100 lookup localnat
10000:  from 1.2.3.4 lookup isp1
20000:  from all to 1.2.3.4/24 lookup isp1
32766:  from all lookup main
32767:  from all lookup default
40000:  from all fwmark 0x11/0x1f lookup isp1
40002:  from all fwmark 0/0x1f lookup isp1
90013:  from all iif lo lookup isp1
90013:  from all iif lo lookup isp1
# ip route show table main
10.0.0.0/24 dev lan0 proto kernel scope link src 10.0.0.1
# ip route show table isp1
default via 1.2.3.1 dev wan0 proto static src 1.2.3.4
1.2.3.0/24 dev wan0 proto static scope link
# cat /etc/firewall.user
iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -N PREROUTING-NEW
iptables -t mangle -N POSTROUTING-NEW

iptables -t mangle -A PREROUTING -m conntrack --ctstate NEW -m connmark --mark 0x00/0x10 -j PREROUTING-NEW
iptables -t mangle -A PREROUTING-NEW -i wan0 -j CONNMARK --set-mark 0x11 # isp1
#iptables -t mangle -A PREROUTING-NEW -i wan1 -j CONNMARK --set-mark 0x12 # isp2

iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -m connmark --mark 0x00/0x10 -j POSTROUTING-NEW
iptables -t mangle -A POSTROUTING-NEW -o wan0 -j CONNMARK --set-mark 0x11 # isp1
#iptables -t mangle -A POSTROUTING-NEW -o wan1 -j CONNMARK --set-mark 0x12 # isp2

iptables -t mangle -A PREROUTING -m connmark --mark 0x10/0x10 -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -m connmark --mark 0x10/0x10 -j CONNMARK --restore-mark

iptables -t mangle -A OUTPUT -m addrtype --dst-type local -j MARK --set-mark 0x100/0x100 # localnat
iptables -t nat -A OUTPUT -m mark --mark 0x100/0x100 -j zone_wan_prerouting

Только сейчас он слегка вырожденный — я дропнул второго провайдера, нового ещё не нашёл, а PBR остался. «localnat» — это сабжевый хак.

В чём тогда разница? Можешь всё-таки привести свой полный конфиг с решением этой проблемы?

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

Специально смоделировал ещё раз совсем простой вариант

0:	from all lookup local
100:	from all lookup main
5100:	from all fwmark 0x5100 lookup ISP1
5200:	from all fwmark 0x5100 lookup ISP2
10200:	from all fwmark 0x2 lookup ISP1
10210:	from $IP_ISP1 lookup ISP1
10300:	from all fwmark 0x3 lookup ISP2
10310:	from $IP_ISP2 lookup ISP2
11200:	from all lookup ISP2
11300:	from all lookup ISP1
32766:	from all lookup main
32767:	from all lookup default

Убрал только правила для пустых на текущий момент таблиц. Они для различных vpn.

iptables очистил, т.е. выше указанные правила с fwmark тут вообще не участвуют.

Добавил два правила iptables в OUTPUT одно для внутреннего IP ISP1 (10.192.51.34) который на eth висит, второе на внешний IP_ISP2 висит на ppp (xl2tp)
172.17.0.85 - машинка в локалке
# Generated by iptables-save v1.6.0 on Thu Oct 17 18:59:10 2019
*raw
:PREROUTING ACCEPT [166:22598]
:OUTPUT ACCEPT [66:13266]
COMMIT
# Completed on Thu Oct 17 18:59:10 2019
# Generated by iptables-save v1.6.0 on Thu Oct 17 18:59:10 2019
*mangle
:PREROUTING ACCEPT [166:22598]
:INPUT ACCEPT [137:14719]
:FORWARD ACCEPT [29:7879]
:OUTPUT ACCEPT [66:13266]
:POSTROUTING ACCEPT [95:21145]
COMMIT
# Completed on Thu Oct 17 18:59:10 2019
# Generated by iptables-save v1.6.0 on Thu Oct 17 18:59:10 2019
*nat
:PREROUTING ACCEPT [12:825]
:INPUT ACCEPT [11:767]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [1:58]
-A OUTPUT -d $IP_ISP2/32 -p tcp -m tcp --dport 22 -j DNAT --to-destination 172.17.0.85
-A OUTPUT -d 10.192.51.34/32 -p tcp -m tcp --dport 22 -j DNAT --to-destination 172.17.0.85
COMMIT
# Completed on Thu Oct 17 18:59:10 2019
# Generated by iptables-save v1.6.0 on Thu Oct 17 18:59:10 2019
*filter
:INPUT ACCEPT [142:14979]
:FORWARD ACCEPT [29:7879]
:OUTPUT ACCEPT [71:14410]
COMMIT
# Completed on Thu Oct 17 18:59:10 2019


Захожу с роутера ssh anc@10.192.51.34 попадаю на 172.17.0.85 аналогично если сделать на IP_ISP2
На всякий случай ещё и это проверил: tcpdump на соответствующих внешних интерфейсах ничего не показывает.

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

UPD Так вот же оно

10000:  from 1.2.3.4 lookup isp1
20000:  from all to 1.2.3.4/24 lookup isp1
32766:  from all lookup main
я писал что у меня main в начале, а у вас в конце.

UPD2 Когда-то на мой вопрос vel очень хорошо описал про таблицу main, я эту ссылку в закладки положил, что бы приводить другим наступающим на грабли как и я когда-то Маршрутизация маркированных iptables пакетов. (комментарий)

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

Действительно, с from all lookup main в самом начале — всё работает без хаков.

Вот только я совершенно не понимаю, как это работает.

# ip rule
0:      from all lookup local
1:      from all lookup main
5000:   from all fwmark 0x11/0x1f lookup isp1
6000:   from all fwmark 0/0x1f lookup isp1
10000:  from 1.2.3.4 lookup isp1
20000:  from all to 1.2.3.4/24 lookup isp1
32766:  from all lookup main
32767:  from all lookup default
90028:  from all iif lo lookup isp1
90028:  from all iif lo lookup isp1

# iptables -t nat -S OUTPUT
-P OUTPUT ACCEPT
-A OUTPUT -m addrtype --dst-type LOCAL -j zone_wan_prerouting

И мне не нравится, что OpenWRT добавляет правила для лукапов в кастомные таблицы до lookup main. Вот эти правила с приоритетами 10000 и больше (численно) — они создаются автоматически и я никак не могу на них повлиять. Пришлось вручную добавить ещё одно from all lookup main в самое начало таблицы.

А ещё да, маршрут 1.2.3.0/24 dev wan0 — у меня не в таблице main, а в таблице isp1. Опять же его туда добавляет OpenWRT и я ничего не могу с этим сделать.

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

Вот только я совершенно не понимаю, как это работает.

Я вам привел ссылку на описание от vel. Мне кажется там все подробно расписано.

И мне не нравится, что OpenWRT добавляет правила для лукапов в кастомные таблицы до lookup main.

Все так делают :) Кстати есть адепты оспаривающие идею main первый. Но как по мне, после того как перенастроил, «волосы стали шелковистее». Недостатки не использования main первой так же описаны в посте vel, чем больше линков/сетей тем все сложнее аккуратно маркировать/прописывать-правила, это конечно возможно, я так и делал ранее, но на каждый «чих»(изменения) приходиться ещё больше колхозить, сорок раз проверь что ничего не забыл. А после перенастройки убрал кучу нафиг ненужных правил, в результате все стало в разы лаконичнее и понятнее.

Пришлось вручную добавить ещё одно from all lookup main в самое начало таблицы.

Обратите внимание у меня так же, оно 100 вручную добавлено, то которое ниже 32766 оно от ведра автоматом.
100: from all lookup main
32766: from all lookup main

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

Я вам привел ссылку на описание от vel. Мне кажется там все подробно расписано.

Нене, как работает роутинг и зачем ставить main первой — я в принципе понял. Не понял только, почему это вообще как-то связано с моей проблемой (и тем более почему это её решает).

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

Смотрите когда вы локально обращаетесь на 1.2.3.4 у вас в пакете адреса src и dst установлены в 1.2.3.4. DNAT меняет адрес dst на 10.0.0.2 но src у нас остался 1.2.3.4. Теперь смотрим ваши правила, данный пакет попадает вот под это

10000:  from 1.2.3.4 lookup isp1
и благополучно улетает с интерфейса смотрящего в инет.

В случае с «main первой» в которой прописан роутинг до 10.0.0.0/24 срабатывает на ней и улетает с правильного интерфейса.

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

Ах блин!

Во я дятел. Всё, теперь понятно.

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

С другой стороны ничерта не понятно, потому что в таблице (которую привёл @vel) написано, что в цепочках OUTPUT роутинг выполняется до nat’а (и rerouting check тоже).

Получается, это всё-таки неправда?

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

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

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

Не вижу противоречий. Имхо все правильно. rerouting check там и не должно быть, получаем на выходе то что получили в соответствии с адресами прописанными в пакетах. И рулим в соответствии таблиц и правил роутинга.

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

DNAT меняет адрес dst на 10.0.0.2 но src у нас остался 1.2.3.4. Теперь смотрим ваши правила

В твоём объяснении сначала DNAT, потом роутинг.

Если бы роутинг был до DNAT, правило в main про 10.0.0.0/24 dev lan0 не сработало бы (потому что на момент роутинга пакет всё ещё src 1.2.3.4 dst 1.2.3.4), и не было бы никакой разницы, ставить main до isp1 или после.

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.