Прямо сейчас у меня появляются дополнительные седые волосы, борющиеся с феноменом потери пакетов между машинами в Интернете.
Проверьте диаграмму ниже. Обратите внимание, что всякий раз, когда я использую «SSH», я могу использовать «HTTPS»; то же явление происходит и для этого протокола.
Сервер SSH, на котором работает Fedora 22, находится на «Сайте A» (красный цвет). До недавнего времени проблем с подключением не было.
Соединения SSH с «Сайтом A» с компьютеров Amazon EC2, работающих под управлением Fedora 22 или Fedora 23, работают отлично (хосты показаны зеленым в поле «Amazon EC2»)
SSH-подключения к «сайту A» с «сайта B», который находится в той же AS, не работают ни в одной из протестированных мной систем Fedora (оранжевые поля). Однако они делать работать из системы Windows 7, используя Putty
. В обоих случаях используется одно и то же оборудование (с двойной загрузкой). «Сайт B» также имеет брандмауэр, но он, похоже, не играет никакой роли: я попытался установить соединение напрямую с маршрутизатора FritzBox, и он все еще не работал для Fedora, но работал для Windows.
Как проявляется проблема:
Когда вы подключаетесь с использованием SSH, происходит начальный обмен пакетами (как показано tcpdump). Однако после 20 пакетов или около того исходящие пакеты больше никуда не уходят; подтверждения не приходят с сайта A. Вы никогда не получите запрос пароля. CTRL-C правильно сбрасывает соединение, после чего Linux все еще пытается отправить пакеты, которые никогда не были подтверждены на некоторое время.
Я подозреваю, что у моего интернет-провайдера есть какая-то проблема, в частности, я подозреваю, что интернет-провайдер выполняет подозрительную магию, чтобы реализовать «фиксированный IP-адрес» на сайте B, который является единственной вещью, которая изменилась «недавно».
Однако я не могу понять, что может объяснить тот факт, что SSH-соединение работает из Windows, но не из Linux в тех же условиях, с точки зрения сети. Что я должен искать?
Трассировка вашего пакета показывает:
22:29:22.180852 IP (tos 0x0, ttl 64, id 52989, offset 0, flags [DF], proto TCP (6), length 1900)
SITE_B_LAN_ADDR.54358 > SITE_A.SSH_PORT: Flags [P.], cksum 0x05c4 (incorrect -> 0xadce), seq 22:1870, ack 22, win 229, options [nop,nop,TS val 4294917498 ecr 71539420], length 1848
Обратите внимание, что его длина составляет 1900 байтов, и в пакете установлена опция dont fragment. Обычно MTU составляет 1400-1500 байтов.
Вы, вероятно, получаете обратно слишком большие сообщения ICMP, но отбрасываете весь входящий трафик ICMP на брандмауэре сайта A.
Чтобы проверить это, вам нужно будет выполнить трассировку пакетов на вашем брандмауэре для icmp и tcp 22.
Убедитесь, что вы разрешаете входящие сообщения ICMP слишком большого размера на сайте A.
В качестве альтернативы вы можете попробовать установить MTU на своих Linux-компьютерах на сайте A на значение, меньшее размера MTU вашей сети. Я рискую предположить, что в Fedora у вас включены пакеты jumbo, а в Windows - нет.
После предложений уважаемых комментаторов я посмотрел, может ли быть причиной проблемы с MTU.
Следующее было обнаружено при попытке подключиться с «сайта A» к «сайту B» из системы Fedora. В системе Windows все работает отлично - wirehark указывает, что длина исходящих пакетов никогда не превышает 1158 байт, поэтому проблема не возникает.
Короче, если я правильно прочитал:
Похоже, мне придется открыть тикет у интернет-провайдера (который, кстати, является POST Telecom Luxembourg, на случай, если кто-то поищет в Google похожие проблемы).
Это также предлагает исправление. Установите для MTU SITE_A значение 1000:
ip route add $SITE_A_IP via $GATEWAY_IP dev $ETHDEV mtu lock 1000
Действительно, это решает проблему.
Использовать ping
для проверки поведения MTU:
ping -c $COUNT -M $MTUDS -s $PPLSZ $HOST
где
COUNT=1
: "Только один пинг"MTUDS=do
: Стратегия обнаружения MTU - «запретить фрагментацию, даже локальную», т.е. установить бит DF (не фрагментировать) (почему это «делать»? Не знаю). ИСПОЛЬЗОВАТЬ ЭТО.MTUDS=want
: Стратегия обнаружения MTU: "выполнить обнаружение PMTU, фрагментировать локально, когда размер пакета большой", т.е. установить бит 'DF' и фрагментировать локальноMTUDS=dont
: Стратегия обнаружения MTU - "не устанавливать бит DF", т.е. фрагментировать по мере необходимостиPPLSZ=1464
: Размер полезной нагрузки пакета ping ICMP в байтах.Использовать tcpdump
для мониторинга всех пакетов ICMP и пакетов от и до «Сайта A»:
tcpdump -vvv -n -nn icmp or '(' host $SITE_A_IP ')'
Однако это немного сложно читать.
Посмотрите, что думает ядро о MTU для «Site A».
watch ip route get to $SITE_A_IP
Обратите внимание, что MTU ниже, чем значение по умолчанию, будет кэшироваться с TTL 600 секунд после первого неудачного пинга.
Сценарий
Предположим, что максимальный размер IP-пакета в байтах (то есть размер полезной нагрузки Ethernet) составляет 1492 (это случай на Amazon EC2), тогда интересный размер полезной нагрузки ping будет 1465, потому что 28 байтов, используемых для заголовков IP и ICMP информация даст 1493, максимум один байт.
затем ping -c 1 -M want -s 1465 $HOST_IP
делает следующее:
При первом эхо-запросе вы получите сообщение «Требуется фрагмент и установлен DF (mtu = 1492) 100% потеря пакетов». tcpdump
показывает выход части 1 эхо-запроса (длина 1493) и маршрутизатор целевой сети, отправляющий обратно сообщение «ICMP недоступен» с запросом фрагментации до MTU 1492. Кэшированная запись с MTU = 1492 появляется в кэше маршрутов ядра.
При последующих эхо-запросах вы получаете «1 пакет передан, 1 получен». tcpdump
показывает часть 1 эхо-запроса (длина 1492) и часть 2 эхо-запроса (длина 21, смещение 1472) и соответствующий эхо-ответ (длина 1493).
Или вы можете использовать traceroute
# traceroute --mtu SITE_A 1500
Размер пакета 1500. Traceroute сообщает нам, что маршрут 10.10.80.7 имеет MTU 1492.
traceroute to SITE_A (SITE_A_IP), 30 hops max, 1500 byte packets
1 gateway (192.168.10.1) 0.550 ms 0.536 ms 0.393 ms
2 192.168.178.1 (192.168.178.1) 1.458 ms 1.485 ms 1.344 ms
3 10.10.80.7 (10.10.80.7) 4.889 ms F=1492 2.968 ms 4.854 ms
4 10.10.80.7 (10.10.80.7) 4.955 ms !F-1492 3.559 ms !F-1492 5.022 ms !F-1492
Попробуйте с 1492: та же проблема!
traceroute to SITE_A (SITE_A_IP), 30 hops max, 1492 byte packets
1 gateway (192.168.10.1) 0.635 ms 0.554 ms 0.483 ms
2 192.168.178.1 (192.168.178.1) 1.510 ms 1.504 ms 1.311 ms
3 10.10.80.7 (10.10.80.7) 48.305 ms 17.436 ms 5.496 ms
4 10.10.80.7 (10.10.80.7) 5.963 ms !F-1492 6.865 ms !F-1492 4.887 ms !F-1492
Попробуйте с 1491: та же проблема!
traceroute to SITE_A (SITE_A_IP), 30 hops max, 1491 byte packets
1 gateway (192.168.10.1) 0.594 ms 0.650 ms 0.492 ms
2 192.168.178.1 (192.168.178.1) 1.716 ms 1.782 ms 1.580 ms
3 10.10.80.7 (10.10.80.7) 7.327 ms 7.385 ms 4.775 ms
4 10.10.80.7 (10.10.80.7) 5.210 ms !F-1492 5.624 ms !F-1492 4.841 ms !F-1492
Попробуйте с 1490: мы проходим. Там обязательно должна быть какая-то ошибка.
traceroute to SITE_A (SITE_A_IP), 30 hops max, 1490 byte packets
1 gateway (192.168.10.1) 0.616 ms 0.688 ms 0.484 ms
2 192.168.178.1 (192.168.178.1) 1.712 ms 1.853 ms 1.611 ms
3 10.10.80.7 (10.10.80.7) 6.248 ms 7.008 ms 4.995 ms
4 SITE_A_IP.dyn.luxdsl.pt.lu (SITE_A_IP) 12.441 ms !X 9.641 ms !X 9.576 ms !X
Дополнительная интересная информация: