NGINX SSL无法通过IPv6进行响应


10

在具有nginx的Debian服务器上,没有Web服务器通过HTTPS和IPv6做出响应。HTTP工作正常。

  • netstat报告端口443正在侦听IPv6地址
  • 防火墙已打开,ipv6scanner.com报告端口443已打开
  • 在本地(通过终端)wget和curl收到正确的响应,因此nginx配置正常
  • 没有来自nginx error.log的错误迹象
  • 失败时access.log中没有记录,因此通信可能未到达Web服务器
  • DNS很好。翻译有效,即使直接访问IP地址也无法建立连接

每次从“外部”(意味着在网络外部,从Internet)进行连接的尝试都将失败(Web浏览器,telnet,ipv6-test.com,curl ...)。完全没有回应。

可以在www.ekasparova.eu上对其进行测试。我无能为力。我还能检查什么?

编辑:

的输出traceroute6 --mtu www.google.com如下:

traceroute to www.google.com (2a00:1450:4014:800::2004), 30 hops max, 65000 byte packets
1  * F=1500 * *
2  * * *
~
30  * * *

所以它永远不会结束...

编辑2:

我的ip6tables-save输出(本地防火墙):

# Generated by ip6tables-save v1.6.0 on Wed Oct 17 06:25:40 2018
*filter
:INPUT DROP [32:9320]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:ufw6-after-forward - [0:0]
:ufw6-after-input - [0:0]
:ufw6-after-logging-forward - [0:0]
:ufw6-after-logging-input - [0:0]
:ufw6-after-logging-output - [0:0]
:ufw6-after-output - [0:0]
:ufw6-before-forward - [0:0]
:ufw6-before-input - [0:0]
:ufw6-before-logging-forward - [0:0]
:ufw6-before-logging-input - [0:0]
:ufw6-before-logging-output - [0:0]
:ufw6-before-output - [0:0]
:ufw6-logging-allow - [0:0]
:ufw6-logging-deny - [0:0]
:ufw6-reject-forward - [0:0]
:ufw6-reject-input - [0:0]
:ufw6-reject-output - [0:0]
:ufw6-skip-to-policy-forward - [0:0]
:ufw6-skip-to-policy-input - [0:0]
:ufw6-skip-to-policy-output - [0:0]
:ufw6-track-forward - [0:0]
:ufw6-track-input - [0:0]
:ufw6-track-output - [0:0]
:ufw6-user-forward - [0:0]
:ufw6-user-input - [0:0]
:ufw6-user-limit - [0:0]
:ufw6-user-limit-accept - [0:0]
:ufw6-user-logging-forward - [0:0]
:ufw6-user-logging-input - [0:0]
:ufw6-user-logging-output - [0:0]
:ufw6-user-output - [0:0]
-A INPUT -j ufw6-before-logging-input
-A INPUT -j ufw6-before-input
-A INPUT -j ufw6-after-input
-A INPUT -j ufw6-after-logging-input
-A INPUT -j ufw6-reject-input
-A INPUT -j ufw6-track-input
-A INPUT -j LOG --log-prefix "[IPTABLES] " --log-tcp-options
-A INPUT -j LOG --log-prefix "[IPTABLES] " --log-tcp-options
-A FORWARD -j ufw6-before-logging-forward
-A FORWARD -j ufw6-before-forward
-A FORWARD -j ufw6-after-forward
-A FORWARD -j ufw6-after-logging-forward
-A FORWARD -j ufw6-reject-forward
-A FORWARD -j ufw6-track-forward
-A FORWARD -j LOG --log-prefix "[IPTABLES] " --log-tcp-options
-A FORWARD -j LOG --log-prefix "[IPTABLES] " --log-tcp-options
-A OUTPUT -j ufw6-before-logging-output
-A OUTPUT -j ufw6-before-output
-A OUTPUT -j ufw6-after-output
-A OUTPUT -j ufw6-after-logging-output
-A OUTPUT -j ufw6-reject-output
-A OUTPUT -j ufw6-track-output
-A ufw6-after-input -p udp -m udp --dport 137 -j ufw6-skip-to-policy-input
-A ufw6-after-input -p udp -m udp --dport 138 -j ufw6-skip-to-policy-input
-A ufw6-after-input -p tcp -m tcp --dport 139 -j ufw6-skip-to-policy-input
-A ufw6-after-input -p tcp -m tcp --dport 445 -j ufw6-skip-to-policy-input
-A ufw6-after-input -p udp -m udp --dport 546 -j ufw6-skip-to-policy-input
-A ufw6-after-input -p udp -m udp --dport 547 -j ufw6-skip-to-policy-input
-A ufw6-after-logging-forward -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] "
-A ufw6-after-logging-input -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] "
-A ufw6-before-forward -m rt --rt-type 0 -j DROP
-A ufw6-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw6-before-forward -p ipv6-icmp -m icmp6 --icmpv6-type 1 -j ACCEPT
-A ufw6-before-forward -p ipv6-icmp -m icmp6 --icmpv6-type 2 -j ACCEPT
-A ufw6-before-forward -p ipv6-icmp -m icmp6 --icmpv6-type 3 -j ACCEPT
-A ufw6-before-forward -p ipv6-icmp -m icmp6 --icmpv6-type 4 -j ACCEPT
-A ufw6-before-forward -p ipv6-icmp -m icmp6 --icmpv6-type 128 -j ACCEPT
-A ufw6-before-forward -p ipv6-icmp -m icmp6 --icmpv6-type 129 -j ACCEPT
-A ufw6-before-forward -j ufw6-user-forward
-A ufw6-before-input -i lo -j ACCEPT
-A ufw6-before-input -m rt --rt-type 0 -j DROP
-A ufw6-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw6-before-input -m conntrack --ctstate INVALID -j ufw6-logging-deny
-A ufw6-before-input -m conntrack --ctstate INVALID -j DROP
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 1 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 2 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 3 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 4 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 128 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 129 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 141 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 142 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 130 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 131 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 132 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 143 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 151 -m hl --hl-eq 1 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 152 -m hl --hl-eq 1 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 153 -m hl --hl-eq 1 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 144 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 145 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 146 -j ACCEPT
-A ufw6-before-input -p ipv6-icmp -m icmp6 --icmpv6-type 147 -j ACCEPT
-A ufw6-before-input -s fe80::/10 -d fe80::/10 -p udp -m udp --sport 547 --dport 546 -j ACCEPT
-A ufw6-before-input -d ff02::fb/128 -p udp -m udp --dport 5353 -j ACCEPT
-A ufw6-before-input -d ff02::f/128 -p udp -m udp --dport 1900 -j ACCEPT
-A ufw6-before-input -j ufw6-user-input
-A ufw6-before-output -o lo -j ACCEPT
-A ufw6-before-output -m rt --rt-type 0 -j DROP
-A ufw6-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 1 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 2 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 3 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 4 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 128 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 129 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 133 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 136 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 135 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 134 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 141 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 142 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 130 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 131 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 132 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 143 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 148 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -p ipv6-icmp -m icmp6 --icmpv6-type 149 -m hl --hl-eq 255 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 151 -m hl --hl-eq 1 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 152 -m hl --hl-eq 1 -j ACCEPT
-A ufw6-before-output -s fe80::/10 -p ipv6-icmp -m icmp6 --icmpv6-type 153 -m hl --hl-eq 1 -j ACCEPT
-A ufw6-before-output -j ufw6-user-output
-A ufw6-logging-allow -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW ALLOW] "
-A ufw6-logging-deny -m conntrack --ctstate INVALID -m limit --limit 3/min --limit-burst 10 -j RETURN
-A ufw6-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW BLOCK] "
-A ufw6-skip-to-policy-forward -j DROP
-A ufw6-skip-to-policy-input -j DROP
-A ufw6-skip-to-policy-output -j ACCEPT
-A ufw6-track-output -p tcp -m conntrack --ctstate NEW -j ACCEPT
-A ufw6-track-output -p udp -m conntrack --ctstate NEW -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 20 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 21 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 25 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 53 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 80 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 110 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 143 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 587 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 993 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 995 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 8080 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 8081 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 10000 -j ACCEPT
-A ufw6-user-input -p udp -m udp --dport 53 -j ACCEPT
-A ufw6-user-input -p tcp -m multiport --dports 29799:29899 -j ACCEPT
-A ufw6-user-input -p udp -m udp --dport 25 -j ACCEPT
-A ufw6-user-input -p tcp -m tcp --dport 8082 -j ACCEPT
-A ufw6-user-limit -m limit --limit 3/min -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw6-user-limit -j REJECT --reject-with icmp6-port-unreachable
-A ufw6-user-limit-accept -j ACCEPT
COMMIT
# Completed on Wed Oct 17 06:25:40 2018

编辑3:

多亏了每个人的帮助,我才能够说服数据中心操作员问题出在他们的基础架构中。问题确实出在通往互联网的虚拟路由器上的MTU设置中。


外部=位于单独的LAN网段上的网络之外,还是位于同一LAN网段上的计算机之外?
IceMage

1
@IceMage在外面意味着来自互联网。在网络外部。我将编辑问题进行澄清
j.kaspar

您是否在服务器上配置了防火墙?如果服务器运行的是Linux,则输出ip6table-save将是相关的。
kasperd

@kasperd我在问题中添加了所有与icmp相关的规则
j.kaspar

@ j.kaspar这是ip6tables-save我想看到的输出。该命令将输出完整规则。
卡巴斯德(Kasperd),

Answers:


19

您有MTU问题。

wget -O /dev/null https://www.ekasparova.eu在观察的同时进行了测试tcpdump。这是我看到的:

19:56:57.048361 IP6 2001:db8::1.47386 > 2a04:f310:100:3:f816:3eff:fea3:4553.443: Flags [S], seq 262121609, win 28800, options [mss 1440,sackOK,TS val 298423713 ecr 0,nop,wscale 7], length 0
19:56:57.087457 IP6 2a04:f310:100:3:f816:3eff:fea3:4553.443 > 2001:db8::1.47386: Flags [S.], seq 2396216876, ack 262121610, win 28560, options [mss 1440,sackOK,TS val 82836580 ecr 298423713,nop,wscale 7], length 0
19:56:57.087490 IP6 2001:db8::1.47386 > 2a04:f310:100:3:f816:3eff:fea3:4553.443: Flags [.], ack 1, win 225, options [nop,nop,TS val 298423723 ecr 82836580], length 0
19:56:57.087692 IP6 2001:db8::1.47386 > 2a04:f310:100:3:f816:3eff:fea3:4553.443: Flags [P.], seq 1:322, ack 1, win 225, options [nop,nop,TS val 298423723 ecr 82836580], length 321
19:56:57.126190 IP6 2a04:f310:100:3:f816:3eff:fea3:4553.443 > 2001:db8::1.47386: Flags [.], ack 322, win 232, options [nop,nop,TS val 82836590 ecr 298423723], length 0
19:56:57.141224 IP6 2a04:f310:100:3:f816:3eff:fea3:4553.443 > 2001:db8::1.47386: Flags [P.], seq 2857:3678, ack 322, win 232, options [nop,nop,TS val 82836594 ecr 298423723], length 821
19:56:57.141301 IP6 2001:db8::1.47386 > 2a04:f310:100:3:f816:3eff:fea3:4553.443: Flags [.], ack 1, win 248, options [nop,nop,TS val 298423736 ecr 82836590,nop,nop,sack 1 {2857:3678}], length 0

前三个数据包是握手。两端宣布mss 1440,这意味着它们能够接收带1440字节TCP有效负载的数据包,同时还对报头进行计数,总计达到1500字节IP流量,这正是以太网通常支持的流量。

接下来的2个数据包是客户端问候,并确认服务器已收到该数据包。

最后2个数据包是使事情变得有趣的地方。默认情况下tcpdump显示相对序列号,在这种情况下,使捕获更易于阅读。在来自服务器的数据包中,这是有趣的部分seq 2857:3678。我们看到从跳转到12857这意味着客户端尚未收到2856字节的间隙。2856字节对应于两个1428字节的数据包。1440和1428之间的差异是时间戳选项的大小。

因此,服务器向服务器发送了3个数据包的问候。但是前两个对于网络而言太大,因此无法交付给客户端。

在从客户端到服务器的最后一个数据包中,我们看到了这一点sack 1 {2857:3678}。这是客户端发送的选择性确认,通知服务器到目前为止已接收到的数据中存在间隙。

服务器可能会不断重复发送两个丢失的数据包。但是,无论它重传相同的两个数据包多少次,它们对于网络来说仍然太大。路径上的路由器可能将错误消息发送回服务器,通知它数据包太大,需要以较小的数据包重传。

如果服务器收到这些错误消息,它将根据需要重新传输较小的数据包。而且它会记住较小的PMTU,因此在后续请求中,不必重复此发现步骤。

所有这一切的可能解释是您的防火墙配置错误,该防火墙丢弃了所有错误消息,通知您的服务器需要以较小的数据包重新传输数据。


1
有趣。谢谢!这些错误消息-我猜这是ICMP协议...有没有测试的方法?服务器上的防火墙以及服务器和Internet之间的防火墙应为所有ICMP通信打开。
j.kaspar

@ j.kaspar什么是防火墙?如何配置?您是如何测试它们的?
迈克尔·汉普顿

@MichaelHampton在服务器上直接安装了iptables防火墙。第二个属于数据中心,我能够管理它的规则。我真的不知道如何测试ICMP。但两者的规则都设置为ICMP允许的任何地方<->任何地方
j.kaspar

1
@ j.kaspar在Linux服务器上,尝试traceroute6 --mtu www.google.com查找是否F=####插入到输出行中,或者寻找根本没有响应返回的输出行。再次考虑,只需运行它并用输出编辑您的问题。
迈克尔·汉普顿

@MichaelHampton完成。但是我不确定如何解释结果。这是否意味着通信根本没有通过第二跳?
j.kaspar

1

我同意@kasperd,这是MTU问题。例如,默认情况下wget -6 -O/dev/null http://www.ekasparova.eu将不起作用(它将短时重定向到https://www.babysoul.cz/同一IP,但随后将挂在下一个更大的数据包上)。然后,我为您的主机强制降低了MSS:

ip -6 ro add 2a04:f310:100:3:f816:3eff:fea3:4553 advmss 1000 via $MY_GW

然后wget正常工作。因此,这是MTU问题。与mtr -6 -n --psize 1410 www.ekasparova.eu(有效)的输出进行比较mtr -6 -n --psize 1411 www.ekasparova.eu将表明该问题是在您的主机上 2a04:f310:100:3:f816:3eff:fea3:4553还是在其上游2a04:f310:100::125

解决方法您可以做些什么(除了联系上游):

测试它中断的数据包大小(即wget -6 -O/dev/null http://v6.testmyipv6.com/MTUtest/1500.dat,虽然应该对您不起作用,但wget -6 -O/dev/null http://v6.testmyipv6.com/MTUtest/1000.dat可以正常工作),然后执行以下任一操作:

  • (更糟糕)将您的MSS限制为默认IPv6路由(如我上面所做的那样)。请注意,仅适用于TCP;例如UDP DNS数据包仍然会损坏,或者
  • (更好)减少您的界面MTU(例如 ifconfig eth0 mtu 1200)。这应该适用于所有数据包。问题是,如果正在处理的某些东西的MTU更低,您将无法与它们通信。降低MTU会导致性能降低(除非您通常是大型站点,否则这没什么大不了的)
  • (最好)尝试删除IPv6防火墙(您自己,并由您自己决定)是否有帮助;当您发现问题所在时,请尝试逐步将其放回原处,而不会破坏PMTU的发现,直到发现有问题的线路为止。问题在于它需要您的ISP进行更多的工作和合作(打开防火墙可能会使您暂时处于脆弱状态)。

减少默认路由上的MSS并不是一个坏建议。我在生产环境中一直在努力解决其他人网络中的MTU问题。不过我还没有低到1000。1220足够小,可以将完整的数据包保留在1280字节以内,IPv6保证端到端工作。但是,通过减少默认路由上的MSS并不能解决问题,因为它只会影响一个方向上的数据包大小。
kasperd

可以篡改传输中的MSS(应该可以使用ip6tables)。您不应该这样做,但是事实证明,将传输中的MSS限制为最大1220是解决MTU问题的非常有效的解决方法。它可以在端点或路由器之间的任何一端完成,这将减轻双向TCP的MTU问题。
kasperd

降低端点上的MTU将影响传出MSS,并且即使您收到较高的MSS,也将限制您发送的数据包。因此,端点处的较低MTU可以减轻双向TCP的MTU问题。但是,它仅在一个方向上对UDP有帮助。减少路由器之间的MTU可以缓解MTU问题或根据情况引入新的MTU问题。因此,减少MSS是可以缓解而又不会带来新的MTU问题的缓解措施。
kasperd

@kasperd是否不应该从一侧降低MSS来双向处理流量,因为它是在3way握手期间为整个TCP会话协商的(作为较低的MSS)?至于降低MTU并破坏传入的UDP,虽然确实不能解决问题,但它不会造成其他问题,因为那些太大的UDP仍然无法工作(因为他坏掉的上游仍然会丢弃它们) 。
Matija Nalis

1
不可以。MSS是为两个方向独立协商的。双方都知道他们愿意发送的最大值,并告诉另一端他们愿意接收的最大值。设置后,advmss您只会影响将要接收的段的大小,而不会影响将要发送的段的大小。您愿意发送的最大值不会传达-因为不需要这样做。两者都从MTU导出其默认值,可以用覆盖其中之一advmss。我不知道路由条目替代其他路由条目的方法,但是如果有一种方法,我想学习。
卡巴斯德(Kasperd),
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.