在实际工作中经常碰到connection reset的报错,那么这个报错是怎么来的呢?
在tcp中正常情况都是通过四次挥手关闭连接,但现实并不总是正常情况。因此在异常情况就会通过rst直接关闭连接,而接收方这个时候一般会看到connection reset或connection refused
那么这个时候新的问题产生了
- 什么异常情况下会发送rst?
- 收到rst一定会断开连接吗?
- 如果rst丢了呢?
- connection reset和connection refused发生场景有区别吗?
- 如果伪造rst进行攻击呢?
rst发生场景
端口不可用
不可用意味着本来就没有可用过,或者原来可用但现在不可用
前者比如说根本就没有监听过端口
监听的时候就创建一个sock放入全局hash表,那么在有新数据到来时就会从表中取,如果找不到,那么就没有被监听
后者比如说服务直接崩溃了
如果通过nginx转发客户端请求,那么客户端会接收到nginx返回的502
socket提前关闭
在socket被提前关闭的情况下,意味该端拒绝与对端发送和接收数据,那么就会直接发送rst
backlog队列满之后
在设置/proc/sys/net/ipv4/tcp_abort_on_overflow情况下,如果backlog队列(全连接队列)满了就会发送rst
人为主动发送
收到rst一定会断开连接吗?
不一定,如果接收方认为rst是非法的,那么就会忽视
比如接收方在收到包后会检查seq是否在合法窗口内
如果rst丢了呢?
即使rst丢了,对于本端来说都已经彻底关闭了,最多在对端再次请求或者keepalive的时候再发送一次
connection reset vs connection refused
- connection reset: 意味着客户端可以建立连接,但服务端在数据传输前直接关闭了连接
- connection refused: 在对应端口根本没有监听的服务,或者防火墙拒绝了这个连接
如果伪造rst进行攻击呢?
rst攻击通过发送rst包去终止连接
rst必须满足(1)在序列号范围内(2)定位目标端口
对于定位序列号可以通过暴力破解,当然可以通过伪造四元组相同的包来收到challenge ack,从而得到正确的序列号。而想要得到正确的四元组,又牵扯到第二个条件
为应对rst攻击可以采用vpn进行加密连接之类的方法
Ref
- https://mp.weixin.qq.com/s/Fr6o6gRiIUIspV9-jR9snw
- https://stackoverflow.com/questions/1434451/what-does-connection-reset-by-peer-mean
- https://serverfault.com/questions/725262/what-causes-the-connection-refused-message
- https://superuser.com/questions/597987/what-is-the-difference-between-unable-to-connect-and-connection-was-reset
- https://en.wikipedia.org/wiki/TCP_reset_attack
- https://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html