问题描述
在通过网络地址转换(NAT)访问一台Linux实例时,遇到以下异常情况:
无法通过SSH正常连接到Linux实例。
访问该实例上部署的HTTP服务时出现连接超时或被重置的现象。
使用telnet命令对实例端口进行测试时,发现连接被重置(
Connection reset by peer)。
问题原因
问题的根源在于Linux内核中与TCP协议相关的参数配置不当:
net.ipv4.tcp_tw_recycle:用于快速回收TIME_WAIT状态的TCP连接。然而,它依赖于远端主机的时间戳必须是单调递增的。在NAT环境中,多个
客户端共享同一个公网IP,它们各自的时间戳并非同步递增,这会导致服务器错误地丢弃来自同一个NAT网关下不同客户端的合法连接请求数据包。
net.ipv4.tcp_timestamps:用于启用或禁用RFC 1323中定义的TCP时间戳。时间戳有助于更精确地计算往返时间(RTT)和防止序列号回绕
(PAWS)。虽然在现代内核中,时间戳的生成包含了随机偏移量以增强安全性,但在某些情况下,当tcp_tw_recycle被启用时,时间戳的验证机制会与
NAT环境产生冲突,导致连接失败。
当服务器开启了tcp_tw_recycle和tcp_timestamps后,对于来自NAT环境的访问,服务器可能会因为时间戳验证失败而拒绝新的TCP连接,从而导致访问异常。
解决方案
调整服务器的内核参数,禁用上述引发冲突的功能。
检查当前的内核参数配置
执行以下命令,确认tcp_tw_recycle和tcp_timestamps的当前值。在问题场景下,这两个参数的值通常为
1(启用状态)。sudo cat /proc/sys/net/ipv4/tcp_tw_recycle sudo cat /proc/sys/net/ipv4/tcp_timestamps修改sysctl配置文件
为了确保系统重启后配置依然生效,建议修改/etc/sysctl.conf文件。使用vi或其他文本编辑器打开该文件:
sudo vi /etc/sysctl.conf在文件末尾添加或修改以下内容,将两个参数的值设置为
0(禁用)。net.ipv4.tcp_tw_recycle=0 net.ipv4.tcp_timestamps=0退出编辑,执行
sudo sysctl -p使配置文件中的修改生效。验证问题是否解决
尝试通过SSH或HTTP再次访问实例,确认连接和访问均已恢复正常。