Назад | Перейти на главную страницу

Почему на моем устройстве с обратной связью есть трафик, отличный от 127.x.x.x?

У меня проблема, из-за которой у меня сильно болела голова, и я нашел решение, но я не могу понять, почему проблема вообще возникла.

У меня есть обратный прокси-сервер nginx, который маршрутизирует запросы на 1 из 3 серверов. Все они являются узловыми серверами, два из них являются экспресс-серверами, а один - специально созданным.

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

Я смог сузить проблему до брандмауэра, заметив, что проблема исчезает, когда я полностью выключаю брандмауэр. На моем сервере работает FreeBSD, использующая PF в качестве брандмауэра. Вот соответствующий pf.conf:

iface = "vtnet0"
loopback = "lo0"
public_ip = "132.148.77.28/32"
localnet = "127.0.0.1"

nat on $iface from any to any -> $public_ip # added by cloud server provider
pass out quick on $iface proto { tcp udp } from port ntp keep state
block log all
pass in on $iface proto tcp from $localnet to port mail
pass in log on $iface proto tcp to $public_ip port { ssh http } keep state
pass in log on $loopback proto tcp to $localnet port { 5555 5556 5557 } keep state
pass out log all keep state

Я понимаю, что любой трафик на vtnet0 устройство будет переведено на использование public-ip.

Я запустил tcpdump с помощью следующей команды: sudo tcpdump -c 10 -vvv -t -i pflog0 -e -n tcp

Я захватил 10 пакетов с тройной детализацией, подавив временную метку, на pflog0, распечатал правило pf, которое разрешало или блокировало пакет, оставляя IP-адреса и порты как числа и только захват трафика с использованием tcp.

Вот интересные результаты первого запроса, а также результаты последующих запросов:

$ sudo tcpdump -c 10 -vvv -t -i pflog0 -e -n tcp
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 65535 bytes

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 53488, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45274 > 132.148.77.28.80: Flags [S], cksum 0x76df (correct), seq 356096480, win 29200, options [mss 1460,sackOK,TS val 63916304 ecr 0,nop,wscale 7], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2406, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.28850 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x180a), seq 2069090201, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367168 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2406, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->3354)!)
    127.0.0.1.28850 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x180a), seq 2069090201, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367168 ecr 0], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2414, offset 0, flags [DF], proto TCP (6), length 60)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0x1728), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367544 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2414, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8ded)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0x1728), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33367544 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2416, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8deb)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0x0b6a), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33370550 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2418, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de9)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xfee6), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33373753 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2420, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de7)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xf265), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33376954 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2422, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de5)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xe5c8), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33380183 ecr 0], length 0

rule 2..16777216/0(match): **block in on lo0**: (tos 0x0, ttl 64, id 2424, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->8de3)!)
    132.148.77.28.48488 > 132.148.77.28.80: Flags [S], cksum 0xa38f (incorrect -> 0xd943), seq 3973611725, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 33383388 ecr 0], length 0
10 packets captured
11 packets received by filter
0 packets dropped by kernel

$ sudo tcpdump -c 10 -vvv -t -i pflog0 -e -n tcp
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 65535 bytes

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 408, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45482 > 132.148.77.28.80: Flags [S], cksum 0x2e49 (correct), seq 3314040182, win 29200, options [mss 1460,sackOK,TS val 64109806 ecr 0,nop,wscale 7], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2446, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.19450 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x603e), seq 629617255, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141175 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2446, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->332c)!)
    127.0.0.1.19450 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x603e), seq 629617255, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141175 ecr 0], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2459, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.54320 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x8ec2), seq 2137792783, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141359 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2459, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->331f)!)
    127.0.0.1.54320 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0x8ec2), seq 2137792783, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141359 ecr 0], length 0

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 13349, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45484 > 132.148.77.28.80: Flags [S], cksum 0x9e57 (correct), seq 2310473985, win 29200, options [mss 1460,sackOK,TS val 64109860 ecr 0,nop,wscale 7], length 0

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 32739, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45486 > 132.148.77.28.80: Flags [S], cksum 0x5b67 (correct), seq 2464105159, win 29200, options [mss 1460,sackOK,TS val 64109860 ecr 0,nop,wscale 7], length 0

rule 8..16777216/0(match): pass in on vtnet0: (tos 0x0, ttl 52, id 55497, offset 0, flags [DF], proto TCP (6), length 60)
    67.197.156.119.45488 > 132.148.77.28.80: Flags [S], cksum 0x832f (correct), seq 3354322413, win 29200, options [mss 1460,sackOK,TS val 64109860 ecr 0,nop,wscale 7], length 0

rule 9..16777216/0(match): pass out on lo0: (tos 0x0, ttl 64, id 2474, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.60189 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0xe2c0), seq 1589892785, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141386 ecr 0], length 0

rule 5..16777216/0(match): pass in on lo0: (tos 0x0, ttl 64, id 2474, offset 0, flags [DF], proto TCP (6), length 60, bad cksum 0 (->3310)!)
    127.0.0.1.60189 > 127.0.0.1.5556: Flags [S], cksum 0xfe30 (incorrect -> 0xe2c0), seq 1589892785, win 65535, options [mss 16344,nop,wscale 6,sackOK,TS val 34141386 ecr 0], length 0
10 packets captured
14 packets received by filter
0 packets dropped by kernel

Я добавил новые строки между информацией о пакете для лучшей читаемости. В первом дампе вы заметите, что «правило 2» блокирует пакеты, что происходит только в самом первом запросе после перезапуска вышестоящего сервера.

Что дает? Вы также заметите, что эти заблокированные пакеты находятся на интерфейсе обратной связи, но они исходят и отправляются на общедоступный IP-адрес. Я думаю, что они не должны быть NAT, потому что они не на интерфейсе vtnet0. Тем не менее, почему последующие запросы идут по другому пути, чтобы облегчить связь от nginx к вышестоящему серверу?

Исправление, которое я нашел, заключалось в изменении следующей строки из моего pf.conf: pass in log on $iface proto tcp to $public_ip port { ssh http } keep state кому: pass in log proto tcp to $public_ip port { ssh http } keep state

Я удалил on $iface часть, поэтому межсетевой экран будет пропускать даже пакеты на порт $ public_ip 80 на интерфейсе обратной связи. У меня также есть умеренные опасения по поводу последствий для безопасности, связанных с ослаблением этого правила - они умеренные только потому, что я больше не полностью понимаю, как работает трафик между этими различными сетевыми интерфейсами.

На данный момент я даже не уверен, связана ли проблема с моим брандмауэром или с nginx, просто, когда брандмауэр отключен, проблема исчезает.

Обратите внимание, что nginx - это proxy_passзапросы в трех разных server блоки к http://127.0.0.1:[port] где порт - один из 5555, 5556 или 5557.

После долгих исследований правильное решение моей проблемы, вместо изменения упомянутой мной строки, заключалось в том, чтобы полностью удалить эту строку и добавить set skip on lo0 в блоке Параметры файла pf.conf (после макросов и перед правилами фильтрации пакетов). Это полностью защищает интерфейс обратной связи от контакта с pf.

Что касается IP-адресов, отличных от 127.x.x.x, на устройстве с обратной связью, у меня есть теория. Как предложил @Richard Smith, я запустил netstat -rn и заметил следующие две строчки:

Destination      Gateway Flags Netif
132.148.77.28    link#1  UHS   lo0 
132.148.77.28/32 link#1  U     vtnet0

Я немного покопался и обнаружил, что эти две записи были добавлены как псевдоним через ifconfig, к первому интерфейсу Ethernet, указанному в выводе ifconfig: vtnet0. Таким образом, естественно кажется, что трафик действительно может быть направлен через шлейф на 132.148.77.28, как показано на этом маршруте. Это просто означает, что он будет использовать vtnet0 в качестве шлюза для этого. Теперь я не уверен, что произошло ли то, что когда он достиг vtnet0 в качестве шлюза, он получил NAT по правилу pf, но тогда я не уверен, почему tcpdump все еще показывает старый интерфейс (lo0), из которого Оно пришло. Мне все еще кажется странным, что вышестоящий сервер, который прослушивает 127.0.0.1, решил открыть порт на 132.148.77.28, чтобы попытаться ответить прокси-серверу в первый раз, а затем при последующих запросах просто использовать 127.0.0.1. 0.1, а обратный прокси-сервер «опустится до своего уровня» для связи. Моя теория состоит в том, что алгоритм маршрутизации «запомнил», что предыдущий путь был плохим (т.е. был заблокирован), и поэтому попробовал другой подход. Я не буду отмечать свой ответ как принятый, потому что мне действительно нужен профессионал с хорошо обученным глазом, чтобы проверить, имеют ли мои легкие теории хоть какую-то силу.