Как перенаправить на новый хост весь трафик, предназначенный для старого хоста?
Мы перемещаем кучу услуг, скажем из 1.2.3.4
в 5.6.7.8
,
Чтобы проверить, правильно ли настроены новые сервисы, мы хотели бы перенаправить (на новый хост) весь трафик, предназначенный для исходного хоста, который исходит от наших тестовых рабочих станций.
Конечно, такое перенаправление может быть реализовано на маршрутизаторах внутри самой сети, но по соображениям стабильности мы решили реализовать его на каждой рабочей станции напрямую (все это OS X 10.10 Yosemite, поэтому используйте pre-v4.7 OpenBSD pf).
Я добавил к /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 типа ссылки (файл pflog OpenBSD), размер захвата 65535 байт. 00: 00: 00.000000 правило 0.910.TestServiceMove.0/0(match): пройти на en1: (tos 0x0, ttl 64, id 40691, смещение 0, флаги [DF], проток 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 (соответствует): вход в очередь на lo0: (tos 0x0, ttl 64, id 40691, смещение 0, флаги [DF], протокол 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 host 5.6.7.8 tcpdump: тип канала передачи данных PKTAP tcpdump: прослушивание на pktap, PKTAP типа Link (Tapet 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, flags [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], прото 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, flags [DF], proto TCP (6), длина 64) 9.9.9.9.58029 > 5.6.7.8.22: флаги [S], cksum 0xae9c (правильно), seq 3399416413, выигрыш 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], прото 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], прото 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, flags [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
быть уверенным, что соединение отслеживается для этой цели?