커널 파라메터 tcp_tw_recycle 이슈

2024. 2. 7. 16:33Network

요즘 cloud 환경을 많이 사용하는 데, cloud 환경에서 NAT를 거쳐 onPrem 같은 구 환경으로 네트웍을 연결해놓은 상태라면, 구 커널 버전 환경에서 구동 중인 서버라면 해당 이슈가 발생할 수 있다는 걸 알게 되었습니다.

 

 

1) TIME WAIT (https://docs.likejazz.com/time-wait/)

		if (tmp_opt.saw_tstamp &&
		    tcp_death_row.sysctl_tw_recycle &&
		    (dst = inet_csk_route_req(sk, req)) != NULL &&
		    (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
		    peer->v4daddr == saddr) {
			if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
			    (s32)(peer->tcp_ts - req->ts_recent) >
							TCP_PAWS_WINDOW) {
				NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
				goto drop_and_release;
			}
		}
  • 위의 로직이 문제가 되는 이유는 NAT 환경에서는 모든 Sender가 동일 IP로 들어오게 되며, Client 마다 기준 Timestamp가 각기 다르기 때문입니다. 이로인해 “goto drop_and_release” 해당 코드가 동작하게 되었으며 Client는 지속적으로 SYN에 대한 ACK를 요구하기 위해서 다시 보내오고 Server 측에서는 그냥 버리는 동작이 반복되었습니다.
  • Wireshark 레벨에서는 동일한 Source로 부터 반복해서 동일 port로 SYN이 들어온다고만 판단했기에 아래와 같은 메시지를 출력하고 있었습니다.
  • “NMIMS side 문제 발생시 TCP dump“

2) Linger option (http://egloos.zum.com/rucaus/v/237240)

  • C에서 제공되는 Socket 옵션
struct  linger
{
        int     l_onoff;                ⁄* option on⁄off *⁄
        int     l_linger;               ⁄* linger time *⁄
};
  • Socket 생성시 l_onoff를 on으로 활성화할 경우 linger time을 함께 설정하게 되고, 해당 값 동안만 TIME WAIT 역할을 수행하고 바로 RST를 이용하여 TIME WAIT STATE로 전환하지 않는 방법입니다.
  • 활성화시 socket close는 linger time동안 blocking call 이 됩니다. (Return이 되지 않음)
  • 비동기에서는 쓰지 않을 이유가 없는 방식으로 보이고 실제 Netty 기반의 Spring cloud gateway의 경우에는 TIME WAIT가 남지 않기기에 linger를 활용하고 있는 것으로 보입니다.

'Network' 카테고리의 다른 글

Connection reset by peer 이슈  (1) 2023.01.24