VPN 릴레이가 SSH 수락을 멈춤: 파일 디스크립터 한도
터널 트래픽은 계속 흐르는데 그 뒤의 socat 릴레이가 새 세션을 거부합니다. 경로를 추적한 다음 살아 있는 PID에서 상속된 한도를 읽으십시오.
WireGuard 핸드셰이크는 여전히 완료되고 피어는 여전히 최근 엔드포인트를 보여 주지만, 그 뒤의 릴레이를 통한 새 SSH 세션은 배너 없이 멈춰 있습니다. 이 조합은 터널이 아니라 소켓을 받아들이는 프로세스를 가리킵니다. socat 같은 릴레이는 자체 디스크립터 예산, 자체 자식, 자체 상속 한도를 가지고 애플리케이션 경로에 자리합니다. 아래의 추적은 클라이언트에서 시작해 더 이상 소켓을 열 수 없는 첫 구성 요소에서 멈춥니다.
숫자를 바꾸기 전에 경로를 추적하십시오
터널 전체를 논하기보다 실패한 요청 하나를 추적하십시오. 클라이언트는 터널에 쓰고, VPN 데몬은 복호화하고 라우팅하며, 릴레이는 반대편에서 받아들입니다. 각 단계는 디스크립터를 소비하며, 보통 고갈되는 것은 마지막 단계입니다.
재현할 수 있는 요청으로 시작해 시간을 측정하십시오. TCP 핸드셰이크는 끝나는데 애플리케이션 배너가 오지 않는다면, 릴레이가 소켓을 가져간 뒤 자식이나 업스트림 쪽에서 막힌 것입니다. 핸드셰이크 자체가 끝나지 않는다면 원인은 라우팅, 방화벽 또는 리스너 상태이지 디스크립터 상한이 아닙니다. 관찰한 것이 두 형태 중 어느 쪽인지 기록하십시오. 서로 다른 프로세스를 가리키기 때문입니다.
작업을 중복하는 홉도 세십시오. 포크하는 리스너는 받아들인 각 소켓을 자체 사본을 유지하는 자식에게 넘기므로, 실제 합계는 부모만이 아니라 트리 전체의 속성입니다.
릴레이가 상속한 한도를 읽으십시오
중요한 유일한 한도는 실행 중인 프로세스의 것이며, 그 프로세스를 시작한 것이 정했습니다. 셸에서 ulimit -n를 입력하면 셸을 설명할 뿐입니다. 서비스 관리자에게 무엇을 적용했는지 물은 다음 PID에서 확인하십시오.
systemctl show -p MainPID -p LimitNOFILE vpn-relay.service
cat /proc/$(systemctl show -p MainPID --value vpn-relay.service)/limits
limits 파일은 프로세스가 보는 소프트 및 하드 상한을 인쇄합니다. 넉넉한 하드 값 아래의 낮은 소프트 값은 데몬이 자체 상한을 올릴 수 있음을 뜻하고, 일부는 시작 시 그렇게 합니다. 소프트 값이 같고 낮다면 unit 파일이 출처입니다.
drop-in은 사전순으로 로드되고 나중 파일이 이깁니다. 따라서 systemctl cat vpn-relay.service이 무엇이 적용되는지에 대한 권위 있는 보기입니다. 관리자가 절대 읽지 않는 파일을 편집하는 것이 올린 숫자가 효과가 없는 가장 흔한 이유입니다.
안정적인 동시성을 유지된 상태와 분리하십시오
두 프로세스가 무관한 이유로 같은 상한에 부딪힐 수 있고 해결책은 다릅니다. 유용한 동시 세션을 따르는 수요는 용량 문제입니다. 작업이 끝난 뒤에도 계속되는 증가는 누출이거나 아무도 닫지 않은 세션 집합입니다.
유휴 상태, 평소 피크, 부하가 멈춘 몇 분 뒤에 다시 측정하십시오. ls /proc/PID/fd | wc -l로 열린 항목을 소프트 한도와 비교해 세면 차이가 드러나고, 상한보다 하나나 둘 낮은 수는 느린 경로가 아니라 확실한 정지입니다.
수가 줄지 않으면 합계가 아니라 소켓 상태를 보십시오. CLOSE_WAIT에 머무는 디스크립터는 피어가 닫았는데 이쪽은 닫지 않았다는 뜻이며, 더 큰 한도는 이를 미룰 뿐인 애플리케이션 수명 주기 결함입니다. 자식 모델도 제한하십시오. 동시 자식에 상한이 없는 포크형 릴레이는 디스크립터, 프로세스 슬롯, 메모리를 함께 소진합니다.
살아 있는 프로세스에서 새 값을 확인하십시오
unit을 편집한 뒤 관리자를 다시 로드하고 서비스를 재시작하십시오. 다시 로드만으로는 실행 중인 프로세스가 이미 상속한 한도를 결코 바꾸지 않습니다. 실제로 트래픽을 처리하는 프로세스에서 확인하십시오.
systemctl daemon-reload
systemctl restart vpn-relay.service
awk '/Max open files/ {print}' /proc/$(systemctl show -p MainPID --value vpn-relay.service)/limits
ss -tnp state established '( sport = :2222 )' | wc -l
awk 줄은 새 쌍을 돌려줍니다. 여전히 이전 쌍이 나온다면 편집한 drop-in이 로드되는 것이 아닙니다. ss 수는 작업 부하 점검이므로 예상하는 세션 수를 열고 오르는지 보십시오. 그 세션을 닫은 뒤에도 계속 오르는 수는 한도가 문제의 전부가 아니었음을 뜻합니다.
큰 증가에는 항상 주의가 따릅니다. select()로 폴링하는 애플리케이션은 FD_SETSIZE 위의 디스크립터를 감시할 수 없으며, 이는 일반 빌드에서 1024이므로 그 위로 올린 상한은 무관해 보이는 실패를 낳을 수 있습니다. systemd 실행 참조도 시작하는 서비스에 같은 경고를 담고 있습니다.
재시작을 터널 가용성에서 멀리 두십시오
릴레이를 재시작하면 활성 세션이 끊기며, 이는 VPN 중단과 별개의 사건입니다. 릴레이가 순환하는 동안 터널이 유지되도록 변경을 정렬하고, 장기 세션이 이를 가로지르는 사람에게 경고하십시오.
롤백은 이전 unit 파일에 재시작 한 번을 더한 것이며, 새 값이 하루 근무를 견딜 때까지 그 파일을 그대로 둡니다. 그런 다음 처음 실패한 요청으로 루프를 닫으십시오. 릴레이를 통한 새 SSH 세션 하나, 의미 있을 만큼 긴 전송 하나, 유휴 수준으로 돌아오는 디스크립터 수입니다.