LINUX.ORG.RU
ФорумAdmin

Hairpin в nftables.

 ,


1

3

Есть доменное имя example.com.
У регистратора прописана DNS-запись типа А на адрес 1.2.3.4

Есть локальная сеть 192.168.1.0/24
Есть в этой локальной сети веб-сервер 192.168.1.100

Извне доступ организован правилом nft add rule ip nat chain PREROUTING iifname "eno1" tcp dport { 80, 443 } dnat to 192.168.1.100 и всё работает, но не соображу, как прописать в nftables правило чтоб можно было попасть на веб-сервер из локальной сети?

Тут описана технология Hairpin по аналогии с микротом, но видимо не пойму как это на nftables положить.

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

но мне кажется ты забыл сказать что-то важное.

Эм-м-м… Структура чуть сложнее. 192.168.1.100 - это реверспрокси, за которым веб-сервер, клауд и ещё пару хотелок. Твой пример с курлом отдаёт нот фаунд

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

Удваиваю. Никогда не понимал в чём нужность хайрпин, если на том же роутере можно поднять DNS и ему в зону прописать резольвинг имени во внутренний IP. Потому что если у тебя в сети за роутером компов больше чем один — уже имеет смысл локальный DNS на роутере поднять. Они и кешировать будет заодно... Поднимается он элементарно. А если в локалке две-три машины и поднимать категорически лень — ну пропиши им в hosts.

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

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

Стоит бинд, но опять же не совсем понимаю как должно резолвиться. в /var/lib/bind/db.forward добавил запись example.com IN A 192.168.1.100, но не сработало…=(

Shprot ★★
() автор топика

Я бы заменил в этом правиле iifname "eno1" на ip daddr 1.2.3.4

И для того чтобы обратные пакеты шли через роутер нужно добавить в postrouting/nat snat c адресом роутера при условии, что они пришли из локалки.

Получается двойной nat: dnat + snat.

Но лучше сделать split dns, чтобы в локалке сразу попадать на адрес сервера

Тема двойного nat здесь обсуждалась неоднократно.

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

но опять же не совсем понимаю как должно резолвиться

в смысле, как?…

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

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

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

Но лучше сделать split dns

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

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

на том же роутере можно поднять DNS и ему в зону прописать резольвинг имени во внутренний IP.

Немного сложнее. 192.168.1.100 - это реверс-прокси. На него извне поступают запросы типа
one.example.com -> 192.168.1.101
two.example.com -> 192.168.1.102
и т.д. Соответственно работает это всё ещё и на разных портах.

Как например сделать из описания чтоб локально ты обращался по имени example.com, который локально ссылался на 192.168.1.100, с которого уже шёл запрос на 192.168.1.103:81…?

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

Ты буддист что ли? Какой к хренам извилистый путь?

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

Вариантов два - к dnat добавить правило snat, и трафик пойдет через роутер.

Или без snat, тогда трафик после первого ответа пойдет напрямую, мимо роутера.

Другой вариант, поставить nginx на роутер и обойтись вовсе без dnat.

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

Мне тоже всегда так казалось. Но как то случайно поставил днат в свою же подсеть, смотрю, работает. Вайршарком смотрю, а первый ответ о роутера что-то типа next hop и адрес в подсети и дальше диалог напрямую пошел. Мне это как раз не нужно было, поэтому я добавил snat, но было интересно.

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

Другой вариант, поставить nginx на роутер и обойтись вовсе без dnat.

И так стоит reverse-proxy nginx -> 192.168.1.100, который в пределах лабы направляет трафик на хосты в зависимоти от имени домена. Нафига ещё один nginx ставить ещё на роутер?

Тут местный бомонд дружно рекомендует прописать в зону имя с резолвингом на хост. Взялся за это, но не совсем понимаю как.

cat /var/lib/bind/db.example.com.
$TTL 28800	; 8 hours
@ IN  SOA ns.example.com. root.example.com. (
                2024121815 ; serial
		200        ; refresh (3 minutes 20 seconds)
		1200       ; retry (20 minutes)
		172800     ; expire (2 days)
		120        ; minimum (2 minutes)
		)
@ IN  NS  ns.example.com.
ns          IN  A 192.168.1.1
exapmle.com IN  A 192.168.1.100
one         IN  A 192.168.1.100
two         IN  A 192.168.1.100

Но во-первых nslookup с другой машины в этой же локальной сети всё равно указывает на 1.2.3.4, а во-вторых как он будт работать, если зона example.com и хост example.com? Получается отдавать IP адрес он будет по имени example.com.example.com…?

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

Слушай, ну сделал я локальный dns. С такой конфигурацией зоны работает только домен третьего уровеня. Подскажи как сделать, чтоб в локалке открывался именно второй уровень -> example.com

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

или поставить в конце имени домена точку

Человечищще…!
Я прям в ноги кланюсь!
Спасибо!
Ну не знал я этого.
Теперь буду знать!
Ещё раз спаисбо!

Shprot ★★
() автор топика

С dns так себе решение и, imho, оно не правильное. У example.com должен быть именно тот ip который должен быть.
У меня сервер в локалке в dmz за роутером и все работает как нужно. При этом я могу из локалки просканировать порты именно севера и посмотреть как выглядит мой firewall из инета. Как это сделать с решением в dns хз.
Не все роутеры это умеют и что там в iptables в моем хуавей не знаю, ибо нет доступа по ssh и другими способами. :( Но то что можно сделать факт. Единственный косяк, что все из локалки в логах пишутся как приходящие с ip севера. Но это и правиильно.

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

Не все роутеры это умеют и что там в iptables в моем хуавей не знаю

У меня долго микрот стоял, решил от него отказаться и развернул всё сам. Kea+bind+ntables. На этой же железяке qemu-kvm.
Вот компетенции в резолвинге подкачали…=(

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

Как проблему свою решили? У меня конфигурация такая:

OpenWRT x86 с nftables, от него две LAN - 192.168.0.0/24 и 172.16.1.0/24. Во второй стоит вебсервер (172.16.1.2). На роутере через LuCI настроил проброс 80 и 443 на сервер. С инета все ок, но вот с соседней подсети 192.168.0.0/24 - ERR_CONNECTION_REFUSED. При этом в настройках редиректа портов есть опция «Включить NAT Loopback», которая как я понял должна обеспечивать прохождение пакетов между машинами за NAT. Но не сработало.

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

С инета все ок, но вот с соседней подсети 192.168.0.0/24 - ERR_CONNECTION_REFUSED

Если LAN 192.168.0.0/24 и 172.16.1.0/24 в разных зонах файервола то в настройках зоны для 172.16.1.0/24, в разделе «Advanced Settings» добавить 192.168.0.0/24 в поле «Covered subnets».

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

Вот результат tcpdump на 443 порту на сервере (172.16.1.2) Запрос curl доменное имя с машины 192.168.0.2

18:42:49.321610 IP 192.168.0.2.61340 > 172.16.1.2.https: Flags [S], seq 3630372925, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
18:42:51.330231 IP 192.168.0.2.61340 > 172.16.1.2.https: Flags [S], seq 3630372925, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
18:42:55.333549 IP 192.168.0.2.61340 > 172.16.1.2.https: Flags [S], seq 3630372925, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
18:43:03.335941 IP 192.168.0.2.61340 > 172.16.1.2.https: Flags [S], seq 3630372925, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
Serg_sh
()
Ответ на: комментарий от NyXzOr

Если curl из инета, то вот


19:58:12.222429 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [S], seq 652831933, win 64240, options [mss 1460,sackOK,TS val 1038651531 ecr 0,nop,wscale 7], length 0
19:58:12.222450 IP 172.16.1.2.https > 64.227.21.251.39084: Flags [S.], seq 2878854892, ack 652831934, win 65160, options [mss 1460,sackOK,TS val 1404162598 ecr 1038651531,nop,wscale 7], length 0
19:58:12.393960 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [.], ack 1, win 502, options [nop,nop,TS val 1038651700 ecr 1404162598], length 0
19:58:12.403595 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [P.], seq 1:518, ack 1, win 502, options [nop,nop,TS val 1038651708 ecr 1404162598], length 517
19:58:12.403613 IP 172.16.1.2.https > 64.227.21.251.39084: Flags [.], ack 518, win 506, options [nop,nop,TS val 1404162779 ecr 1038651708], length 0
19:58:12.405339 IP 172.16.1.2.https > 64.227.21.251.39084: Flags [P.], seq 1:2415, ack 518, win 506, options [nop,nop,TS val 1404162781 ecr 1038651708], length 2414
19:58:12.577729 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [.], ack 1449, win 493, options [nop,nop,TS val 1038651885 ecr 1404162781], length 0
19:58:12.579720 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [.], ack 2415, win 493, options [nop,nop,TS val 1038651886 ecr 1404162781], length 0
19:58:12.581569 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [P.], seq 518:598, ack 2415, win 501, options [nop,nop,TS val 1038651889 ecr 1404162781], length 80
19:58:12.581790 IP 172.16.1.2.https > 64.227.21.251.39084: Flags [P.], seq 2415:2718, ack 598, win 506, options [nop,nop,TS val 1404162957 ecr 1038651889], length 303
19:58:12.581866 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [P.], seq 598:852, ack 2415, win 501, options [nop,nop,TS val 1038651889 ecr 1404162781], length 254
19:58:12.581883 IP 172.16.1.2.https > 64.227.21.251.39084: Flags [P.], seq 2718:3005, ack 852, win 505, options [nop,nop,TS val 1404162957 ecr 1038651889], length 287
19:58:12.747014 IP 64.227.21.251.39084 > 172.16.1.2.https: Flags [.], ack 3005, win 501, options [nop,nop,TS val 1038652059 ecr 1404162957], length 0

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

iptables -vL
Chain INPUT (policy DROP 908 packets, 124K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  enp3s0 any     anywhere             anywhere             tcp dpt:http-alt
 1518  134K ACCEPT     tcp  --  enp3s0 any     anywhere             anywhere             tcp dpt:https
  859 40643 ACCEPT     tcp  --  enp3s0 any     anywhere             anywhere             tcp dpt:http
  326 23874 ACCEPT     all  --  lo     any     anywhere             anywhere            
 1268 97250 ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  enp0s25 any     anywhere             anywhere             tcp dpt:ssh

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 5611 packets, 2493K bytes)
 pkts bytes target     prot opt in     out     source               destination    

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

Не дало результата…

Совет про «Covered subnets» был неправильным.

В дополнительных настройках правила перенаправления есть поле «Advanced Settings/Reflection zones» где нужно выбрать все зоны (включая зону выбранную в «General Settings/Destination zone») для которых будет действовать отражение.

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

Ранее стоял роутер keenetik viva, по адресам и пробросам настроенный так же (то есть я могу его сейчас взять, переткнуть кабеля в него и все работает). Но - там не было таких проблем. С локальных адресов прекрасно ходил по доменному имени и по внешнему IP. Вот правила с кинетика, касающиеся локальных подсетей (192.168.0.15 - IP роутера):

== Chain _NDM_MASQ ==
src: 0.0.0.0/0, dst: 0.0.0.0/0, in: "*", out: "*", proto: "any"; jump to "_NDM_MASQ_BYPASS"
src: 192.168.0.0/24, dst: 0.0.0.0/0, in: "*", out: "*", proto: "UDP"; "udp" match; "ndmmark" match, value: 0x4/0x4, invert: 0x0; jump to "_NDM_NAT_UDP"
src: 192.168.0.0/24, dst: 0.0.0.0/0, in: "*", out: "*", proto: "any"; "ndmmark" match, value: 0x4/0x4, invert: 0x0; MASQUERADE
src: 172.16.1.0/24, dst: 0.0.0.0/0, in: "*", out: "*", proto: "UDP"; "ndmmark" match, value: 0x4/0x4, invert: 0x0; jump to "_NDM_NAT_UDP"
src: 172.16.1.0/24, dst: 0.0.0.0/0, in: "*", out: "*", proto: "any"; "ndmmark" match, value: 0x4/0x4, invert: 0x0; MASQUERADE
== Chain _NDM_STATIC_DNAT ==
src: 0.0.0.0/0, dst: здесь_внеш_IP, in: "*", out: "*", proto: "TCP"; "tcp" match, mask: , cmp: , dport: 80; DNAT, address: 172.16.1.2, port: 80
src: 0.0.0.0/0, dst: здесь_внеш_IP, in: "*", out: "*", proto: "TCP"; "tcp" match, mask: , cmp: , dport: 443; DNAT, address: 172.16.1.2, port: 443
-> Chain default policy: RETURN
== Chain _NDM_STATIC_LOOP ==
src: 192.168.0.0/24, dst: 192.168.0.0/24, in: "*", out: "br0", proto: "any"; SNAT, address: 192.168.0.15
src: 172.16.1.0/24, dst: 172.16.1.0/24, in: "*", out: "br2", proto: "any"; SNAT, address: 172.16.1.1
Serg_sh
()
Ответ на: комментарий от No

Кстати сейчас попробовал - когда ВСЁ в одной подсети, то нормально работает с включенным loopback и доступ к серверу с локальных машин есть. Можно было б оставить и так, но идея с двумя подсетями была изначально, чтобы изолировать сервер от локальной сети

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

Маскарадинг нужен только для wan.

Проверил на виртуалках, настройки OpenWrt: /etc/config/network

wan - 192.168.3.109
lan - 192.168.83.0/24
lan2 - 10.22.22.0/24
lan3 - 10.33.33.0/24

В lan есть хост 192.168.83.9, в lan2 - 10.22.22.22, в lan3 - 10.33.33.33 на котором запущен nginx слушающий порт 8080

Добавлено правило перенаправления порта 10.33.33.33:8080 - /etc/config/firewall

Команда curl http://192.168.3.109:8080 работает из всех 4-х сетей.

No ★★
()