Остановка Netflix через Linux iptables nat, ошибки контрольной суммы tcp (с обходным решением)
Я пытался отследить эту проблему в течение нескольких дней. Я до сих пор не понял, что происходит, или как это исправить, но у меня есть обходной путь.
Краткое описание проблемы
Netflix останавливается при просмотре на любом компьютере в моей внутренней сети, получая доступ к Интернету через ящик linux, действующий как маршрутизатор nat и adsl.NETflix отлично работает при просмотре непосредственно на коробке Linux, подключенной к Интернету.
подробности
Мой сервер linux box, "шимпанзе", подключен к домашней сети через один ник (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 на шимпанзе для автоматической настройки других машин и установил только прокси *.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