Как перенаправить на новый хост весь трафик, предназначенный для старого хоста?

Как перенаправить на новый хост весь трафик, предназначенный для старого хоста?

Мы переносим ряд сервисов, скажем, с 1.2.3.4на 5.6.7.8.

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

Конечно, такое перенаправлениемогбыть реализовано на маршрутизаторах внутри самой сети, но из соображений стабильности мы решили реализовать его непосредственно на каждой рабочей станции (все они работают под управлением OS X 10.10 Yosemite, поэтому используйте OpenBSD pf до версии 4.7).

Я добавил к /etc/pf.anchors/com.apple:

rdr-anchor "910.TestServiceMove/*"
anchor "910.TestServiceMove/*"
load anchor "910.TestServiceMove" from "/etc/pf.anchors/910.TestServiceMove"

И создал /etc/pf.anchors/910.TestServiceMove:

rdr pass log on lo0 from any to 1.2.3.4 -> 5.6.7.8
pass out log route-to lo0 from any to 1.2.3.4 keep state

После загрузки правил оба работают правильно:

$ sudo tcpdump -v -n -e -ttt -i pflog0
tcpdump: ПРЕДУПРЕЖДЕНИЕ: pflog0: адрес IPv4 не назначен
tcpdump: прослушивание pflog0, тип ссылки PFLOG (файл OpenBSD pflog), размер захвата 65535 байт
00:00:00.000000 правило 0.910.TestServiceMove.0/0(совпадение): передать на en1: (tos 0x0, ttl 64, id 40691, смещение 0, флаги [DF], proto TCP (6), длина 64)
    9.9.9.9.58029 > 1.2.3.4.22: Флаги [S], cksum 0x291a (верно), seq 3399416413, win 65535, параметры [mss 1460,nop,wscale 5,nop,nop,TS val 2063366865 ecr 0,sackOK,eol], длина 0
00:00:00.000047 правило 0/0(совпадение): rdr in on lo0: (tos 0x0, ttl 64, id 40691, смещение 0, флаги [DF], proto TCP (6), длина 64, неверная cksum 896a (->b4da)!)
    9.9.9.9.58029 > 5.6.7.8.22: Флаги [S], cksum 0xb284 (верно), seq 3399416413, win 65535, параметры [mss 1460,nop,wscale 5,nop,nop,TS val 2063366865 ecr 0,sackOK,eol], длина 0

Но TCP-рукопожатие не завершается (SYN-ACK игнорируются, а SYN повторно отправляется до тех пор, пока не истечет время соединения):

$ sudo tcpdump -v -n -e -ttt хост 5.6.7.8
tcpdump: тип канала передачи данных PKTAP
tcpdump: прослушивание pktap, тип соединения PKTAP (Packet Tap), размер захвата 65535 байт
00:00:00.000000 e8:80:2e:e7:67:bc > 84:80:2d:35:e5:43, ethertype IPv4 (0x0800), длина 78: (tos 0x0, ttl 63, id 40691, смещение 0, флаги [DF], proto TCP (6), длина 64)
    9.9.9.9.58029 > 5.6.7.8.22: Флаги [S], cksum 0xb284 (верно), seq 3399416413, win 65535, параметры [mss 1460,nop,wscale 5,nop,nop,TS val 2063366865 ecr 0,sackOK,eol], длина 0
00:00:00.015524 84:80:2d:35:e5:43 > e8:80:2e:e7:67:bc, ethertype IPv4 (0x0800), длина 74: (tos 0x0, ttl 52, id 0, смещение 0, флаги [DF], proto TCP (6), длина 60)
    5.6.7.8.22 > 9.9.9.9.58029: Флаги [S.], cksum 0x7ce4 (верно), seq 1901846890, ack 3399416414, win 14480, параметры [mss 1460,sackOK,TS val 523934721 ecr 2063366865,nop,wscale 7], длина 0
00:00:00.986946 e8:80:2e:e7:67:bc > 84:80:2d:35:e5:43, ethertype IPv4 (0x0800), длина 78: (tos 0x0, ttl 63, id 25319, смещение 0, флаги [DF], proto TCP (6), длина 64)
    9.9.9.9.58029 > 5.6.7.8.22: Флаги [S], cksum 0xae9c (правильно), seq 3399416413, win 65535, параметры [mss 1460,nop,wscale 5,nop,nop,TS val 2063367865 ecr 0,sackOK,eol], длина 0
00:00:00.014938 84:80:2d:35:e5:43 > e8:80:2e:e7:67:bc, ethertype IPv4 (0x0800), длина 74: (tos 0x0, ttl 52, id 0, смещение 0, флаги [DF], proto TCP (6), длина 60)
    5.6.7.8.22 > 9.9.9.9.58029: Флаги [S.], cksum 0x78fa (верно), seq 1901846890, ack 3399416414, win 14480, параметры [mss 1460,sackOK,TS val 523935723 ecr 2063366865,nop,wscale 7], длина 0
00:00:00.397794 84:80:2d:35:e5:43 > e8:80:2e:e7:67:bc, ethertype IPv4 (0x0800), длина 74: (tos 0x0, ttl 52, id 0, смещение 0, флаги [DF], proto TCP (6), длина 60)
    5.6.7.8.22 > 9.9.9.9.58029: Флаги [S.], cksum 0x776c (верно), seq 1901846890, ack 3399416414, win 14480, параметры [mss 1460,sackOK,TS val 523936121 ecr 2063366865,nop,wscale 7], длина 0
00:00:00.588237 e8:80:2e:e7:67:bc > 84:80:2d:35:e5:43, ethertype IPv4 (0x0800), длина 78: (tos 0x0, ttl 63, id 50201, смещение 0, флаги [DF], proto TCP (6), длина 64)
    9.9.9.9.58029 > 5.6.7.8.22: Флаги [S], cksum 0xaab4 (верно), seq 3399416413, win 65535, параметры [mss 1460,nop,wscale 5,nop,nop,TS val 2063368865 ecr 0,sackOK,eol], длина 0

Я предполагаю, что стек TCP отбрасывает SYN-ACK, которые исходят от хоста, отличного от того, на который был отправлен SYN. ​​Но разве правила перенаправления не должны переписывать трафик вобауказания — действительно, разве не следует keep stateгарантировать, что соединение отслеживается для этой цели?

Связанный контент