해결하려고 하는 문제가 있습니다. 많은 로컬 포트 전달이 소켓을 CLOSE_WAIT로 가져오고 있고, 많은 원격 포트 전달이 소켓을 FIN_WAIT2로 가져오고 있습니다.
현재로서는 왜 이런 일이 발생하는지 모르겠습니다. ssh의 버그인 것 같습니다(2009년 1월 7일 SuSE11 R4에서 OpenSSH_6.6.1p1, OpenSSL 0.9.8j-fips 실행). 그러나 나는 소켓 스매싱 프로그램을 작성할 수 있도록 이것을 시뮬레이션하고 싶습니다.
소켓을 열고 죽는 Python 스크립트를 작성해 보았고 스레드에서 열어 호출 응용 프로그램을 종료해 보았습니다. 나는 MySQL 연결을 시도하고 그것들을 매달아 두었습니다. (그것이 CLOSE_WAIT의 원인이기 때문입니다. 그러나 그것을 복제할 수는 없습니다.) 1000가지 다른 방법을 시도할 수 있지만 그 중 어느 것도 이런 일이 발생하지 않을 것입니다. 보류 중인 연결을 시작하는 두 애플리케이션 모두 비공개 소스입니다. (하나는 Science Logic 데이터베이스 연결이고 다른 하나는 Cisco CSPC 상자의 독점 연결입니다.)
그렇다면 소켓을 CLOSE_WAIT 상태로 설정하려면 어떻게 해야 하며, 소켓을 FIN_WAIT2 상태로 설정하려면 어떻게 해야 합니까?
답변1
CLOSE-WAIT는 피어 시스템(프로세스)이 TCP 연결 측을 닫을 때 발생합니다. 이는 로컬 운영 체제에서 감지되어 로컬 프로세스로 전송되었지만 로컬 프로세스는 측을 닫아 이를 아직 승인하지 않았습니다. TCP 연결. 작은 TCP 연결. 이는 일반적으로 응용 프로그램이 사용 중이거나 일부 소켓을 닫는 것을 "잊게" 하거나 정지(따라서 더 이상 닫을 수 없는) 버그가 있을 때 표시됩니다. 동시에 원격 측에는 해당 FIN-WAIT-2가 있지만 이 FIN-WAIT-2는 결국 만료됩니다.
socat
로컬 리스너와 분기된 각 하위 프로세스에 STOP 신호를 보내 "중지"하고 1초 후에 원격 연결을 포기하는 분기 된 프로세스로 재현할 수 있습니다 socat
(명령으로도 수행 가능 socat
).
로컬은 자체적으로 즉시 중지되어 CLOSE-WAIT 상태를 보장합니다. 로컬에서는 TCP 연결을 닫을 수 없기 때문입니다.
socat tcp4-listen:5555,reuseaddr,fork system:'kill -STOP $SOCAT_PID'
수신된 모든 연결에 대해
socat
하위 프로세스는 포크되고 자체적으로 하위 프로세스를 즉시 중지하는 쉘을 포크하여socat
(상속된 변수 사용$SOCAT_PID
) 해당 프로세스가 원격 끝이 닫혀 있음을 감지하고 끝의 TCP 연결을 닫는 것을 방지합니다.원격(또는 이 경우 단순하게 유지하기 위해 로컬)은 1초 동안 활동이 없으면 포기하고 피어의 CLOSE-WAIT와 함께 관련 FIN-WAIT-2 상태를 얻습니다.
for i in $(seq 1 5); do socat -T 1 -u tcp4:127.0.0.1:5555 -; echo $i; done
위 루프가 완료된 후의 결과 예:
$ ss -tn sport == 5555 or dport == 5555
State Recv-Q Send-Q Local Address:Port Peer Address:Port
FIN-WAIT-2 0 0 127.0.0.1:33836 127.0.0.1:5555
FIN-WAIT-2 0 0 127.0.0.1:33846 127.0.0.1:5555
FIN-WAIT-2 0 0 127.0.0.1:33842 127.0.0.1:5555
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33840
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33836
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33842
FIN-WAIT-2 0 0 127.0.0.1:33840 127.0.0.1:5555
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33846
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33834
FIN-WAIT-2 0 0 127.0.0.1:33834 127.0.0.1:5555
FIN-WAIT-2는 결국 만료되지만 CLOSE-WAIT는 (중지된) 프로세스가 존재하는 한 존재합니다. 기본 청취를 중단하면 socat
하위 항목이 죽고 모든 것이 정리됩니다.