Я пытался отследить эту проблему в течение нескольких дней. Я до сих пор не понял, что происходит, или как это исправить, но у меня есть обходной путь.
Краткое описание проблемы
Netflix останавливается при просмотре на любом компьютере в моей внутренней сети, получая доступ к Интернету через окно linux, действующее как nat router и adsl. Netflix отлично работает при просмотре непосредственно на коробке Linux, подключенной к Интернету.
подробности
Мой сервер Linux, "шимпанзе", подключен к внутренней сети дома через один ник (eth0) и к модему adsl через другой ник (eth3). Он запускает pppoe для модема adsl, и интернет-связь работает нормально, со скоростью 15 Мбит / с и 1 Мбит / с. Chimp работает под управлением Debian Jessie 8.6.0 (ядро 3.16.0-4-amd64), хотя это был Debian Wheezy 7.1.0, пока я не обновил его, как часть исследования этой проблемы.
Другие компьютеры в домашней сети получают доступ к Интернету через правила iptables для шимпанзе, которые используют маскировку (я также пробовал snat) для пересылки с eth0 на ppp0.
Смотрю netflix на самого шимпанзе работает нормально. Просмотр BBC iplayer (я в Великобритании) на любом компьютере в сети работает нормально. Смотрю netflix на любом компьютере, кроме шимпанзе, хотя я полагаю, что это сработало примерно в начале ноября 2016 года. Компьютеры, показывающие проблему, включают пару маков (сафари) плюс еще одну коробку Debian Jessie (Chrome).
Глядя на рисунок "RX bytes" из «/sbin/ifconfig ppp0», видно, что он загружался в течение нескольких секунд, а затем практически остановился.
Я нашел в Интернете что-то, что мои правила iptables должны отбрасывать пакеты, которые помечаются как недействительные. Я добавил правила для удаления недействительных пакетов, но это не улучшило ситуацию. Я также попытался войти в систему и увидел, что получаю кучу таких пакетов от netflix, но только при просмотре на машине, отличной от шимпанзе.
Я попытался "echo 255>/proc/sys/net/netfilter/nf_conntrack_log_invalid" и увидел, что неверные пакеты были из-за неправильных контрольных сумм TCP:
Dec 30 20:16:40 chimp kernel: [185803.594182] nf_ct_tcp: bad TCP checksum IN= OUT= SRC=78.146.119.61 DST=<my_public_ip_address> LEN=1500 TOS=0x00 PREC=0x00 TTL=59 ID=0 PROTO=TCP SPT=443 DPT=56711 SEQ=92431783 ACK=3940029300 WINDOW=2050 RES=0x00 ACK URGP=0 OPT (0101080AC67B959B27E48AC7)
Dec 30 20:16:40 chimp kernel: [185803.594200] input invalid: IN=ppp0 OUT= MAC= SRC=78.146.119.61 DST=<my_public_ip_address> LEN=1500 TOS=0x00 PREC=0x00 TTL=59 ID=0 PROTO=TCP SPT=443 DPT=56711 WINDOW=2050 RES=0x00 ACK URGP=0
(Префикс "неверный ввод" показывает, что из моего правила iptables записывается неверный пакет во входной цепочке непосредственно перед его удалением.)
Я попытался отключить проверку контрольной суммы в conntrack с помощью "sysctl -w net.netfilter.nf_conntrack_checksum = 0". Это сделало остановку вышеупомянутых строк журнала, но не устранило проблему.
Так что мое лучшее предположение:
- Что-то сломано вверх по течению от меня, посылающего мне поток netflix, поэтому я получаю ошибки контрольной суммы TCP.
- При просмотре netflix на chimp, ошибочный пакет поступает на уровень tcp chimp, и он может восстановиться, возможно, снова запросив пакет.
- При просмотре на другом компьютере, даже если проверка контрольной суммы tcp отключена, conntrack не может связать пакет с соединением, поэтому он никогда не достигнет уровня tcp клиентского компьютера. Уровень tcp клиента восстанавливается более радикальным образом, возможно, с более длительным таймаутом или ошибкой всего соединения.
Актуальный вопрос наконец
Имеет ли это какой-то смысл для тех, кто знает больше о tcp, conntrack и nat, чем я? Или я что-то не так делаю?
Временное решение
Я вроде как выдохся, расследуя это. Но, возможно, этот обходной путь будет полезен для всех, кто сталкивается с той же проблемой.
Обходной путь - настроить всю домашнюю сеть, используя прокси-сервер http/https, работающий на шимпанзе (машине, подключенной к Интернету). Я использовал wpad.dat на chimp для автоматической настройки других машин и настроил его только для прокси * .netflix.com и * .nflxvideo.net.
Каждому клиентскому компьютеру требуется немного конфигурации для использования автообнаружения прокси, только один флажок в настройках сети как на Mac, так и на GNOME (и я предполагаю, что то же самое в Windows)
Вывод из iptables -L -xvn
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID LOG flags 0 level 4 prefix "input invalid: "
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
347 19177 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
259 33840 ACCEPT all -- eth+ * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpts:1024:5999
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpts:6010:65535
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:123
0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:500
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:143
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:993
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8443
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02
0 0 ACCEPT 47 -- * * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT esp -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID LOG flags 0 level 4 prefix "forward invalid: "
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 state INVALID
0 0 ACCEPT tcp -- eth0 ppp+ 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp flags:!0x17/0x02
0 0 ACCEPT udp -- eth0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
0 0 ACCEPT udp -- * eth0 0.0.0.0/0 0.0.0.0/0 udp spt:53
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 639 packets, 103120 bytes)
pkts bytes target prot opt in out source destination
Вывод из iptables-save
# Generated by iptables-save v1.4.21 on Mon Jan 2 13:24:22 2017
*nat
:PREROUTING ACCEPT [115:43215]
:INPUT ACCEPT [43:4146]
:OUTPUT ACCEPT [2:606]
:POSTROUTING ACCEPT [2:606]
-A POSTROUTING -o ppp+ -j MASQUERADE
COMMIT
# Completed on Mon Jan 2 13:24:22 2017
# Generated by iptables-save v1.4.21 on Mon Jan 2 13:24:22 2017
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [692:108312]
-A INPUT -m state --state INVALID -j LOG --log-prefix "input invalid: "
-A INPUT -m state --state INVALID -j DROP
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth+ -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -p udp -m udp --dport 1024:5999 -j ACCEPT
-A INPUT -p udp -m udp --dport 6010:65535 -j ACCEPT
-A INPUT -p udp -m udp --dport 123 -j ACCEPT
-A INPUT -p udp -m udp --dport 500 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8443 -j ACCEPT
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT
-A INPUT -p gre -j ACCEPT
-A INPUT -p esp -j ACCEPT
-A INPUT -j DROP
-A FORWARD -i lo -j ACCEPT
-A FORWARD -m state --state INVALID -j LOG --log-prefix "forward invalid: "
-A FORWARD -m state --state INVALID -j DROP
-A FORWARD -i eth0 -o ppp+ -p tcp -j ACCEPT
-A FORWARD -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT
-A FORWARD -i eth0 -p udp -m udp --dport 53 -j ACCEPT
-A FORWARD -o eth0 -p udp -m udp --sport 53 -j ACCEPT
-A FORWARD -j DROP
COMMIT
# Completed on Mon Jan 2 13:24:22 2017