실행 스크립트가 PID 파일이 이미 있다는 이유로 OpenVPN 시작을 거부할 때, 어딘가에서 터널이 돌고 있다고 읽는 것은 자연스럽다. 그런 읽기는 충분히 자주 틀리므로 무언가를 지우기 전에 확인할 가치가 있다. 실행 디렉터리의 파일은 장부일 뿐이며, 장부는 프로세스를 남기지 않은 충돌과 재부팅, 중단된 종료를 견딘다. 판단을 가르는 것은 살아 있는 프로세스가 있는가, 그 프로세스가 이 인스턴스의 것인가라는 두 가지 질문이다.

파일이 아니라 서비스부터 보라

거부는 보통 OpenVPN 자체가 아니라 실행 스크립트에서 나온다. 경로를 읽고 거기서 무언가를 찾은 뒤 설정을 해석하기 전에 멈춘다. 따라서 첫 질문은 터널이 아니라 실행 스크립트의 계약에 관한 것이다.

메시지를 출력한 유닛이나 스크립트를 읽고 검사하는 경로, 선언하는 서비스 유형, 파일 쓰기를 맡고 있는지 여부라는 세 가지를 확인하라. 현대적인 유닛은 단순 감시나 알림 감시를 쓰고 PID 파일을 전혀 건드리지 않을 수 있지만, 오래된 init 스크립트는 스스로 파일을 만들 수 있다. 한 모델의 검사를 다른 모델로 복사하면 바로 이런 종류의 거부가 생긴다. 무엇이든 해석하기 전에 어느 모델이 쓰이는지 먼저 알아내라.

그때서야 질문은 인스턴스가 실제로 돌고 있는지가 된다.

그 식별자가 당신의 인스턴스 것인지 확인하라

파일 속 숫자는 숫자가 쓰였다는 것만 증명한다. 그 식별자를 가진 프로세스가 지금 존재한다는 것도, 프로세스가 당신의 것이라는 것도 증명하지 않는 것은 식별자가 재부팅 후 다시 쓰이기 때문이다.

프로세스 시작 시각을 파일의 타임스탬프와, 실행 파일을 유닛의 명령과, 서비스 소속을 유닛 이름과 비교하라. 셋 중 하나라도 어긋나면 당신은 터널이 아니라 장부를 보고 있는 것이다.

컨테이너나 여러 네임스페이스를 돌리는 호스트에서는 식별자가 한 화면에서는 의미가 있고 다른 화면에서는 없을 수 있다. 계정이 검사할 수 없다면 프로세스가 보이지 않는 것도 존재하지 않는다는 증거가 아니다. 결론을 내리기 전에 실행 스크립트가 쓰는 문맥에서 확인하라.

systemctl status [email protected]
ps -o pid,lstart,args -p "$(cat /run/openvpn/vpn.pid)"

실행 스크립트가 파일에 대해 무엇을 약속했는가

PIDFile= 은 서비스 관리자에게 주 프로세스의 식별자를 어디서 읽을지 알려 준다. 관리자는 그 파일을 쓰지 않지만 종료 후 남은 파일은 제거하므로, 중단된 종료가 파일을 남기는 이유가 바로 그것이다.

이 책임 분담은 사람들이 버그로 신고하는 두 증상을 설명한다. 결코 나타나지 않는 파일은 데몬이나 그 스크립트가 쓰지 못했다는 뜻이며, 감시가 잘못 설정되었다는 뜻이 아니다. 종료 후에도 남는 파일은 종료 경로가 끝까지 가지 않았다는 뜻이다.

또한 감시가 주 프로세스를 직접 추적할 수 있을 때 이 관행을 피하라고 현재 지침이 권하는 이유도 설명한다. 그 지침은 데몬의 포그라운드, 포크, 알림 동작이 유닛의 선언과 일치해야 하므로 패키지된 유닛의 유형을 바꿔도 된다는 허가가 아니다. 데몬을 바꾸지 않고 유형만 바꾸면 터널이 도는 동안 실패를 보고하는 유닛을 얻거나 그 반대가 된다. 둘을 맞추거나 둘 다 건드리지 마라. systemd 서비스 참조가 소유권 분담을 설명한다.

깨끗한 종료와 중단된 종료

깨끗한 종료는 데몬에게 종료를 요청하고, 그것을 기다리며, 관리자가 자기 장부를 정리하도록 둔다. 중단된 종료, 강제로 죽인 프로세스, 종료 도중의 재부팅은 그 순서의 일부를 건너뛰고, 남는 것은 파일이다. 충돌 후에 그것을 발견한다는 것은 종료가 끝나지 않았다는 뜻이지 무언가가 듣고 있다는 뜻이 아니다.

파일의 타임스탬프를 마지막 부팅과 유닛의 마지막 종료와 비교하라.

그다음 살아 있는 증거를 직접 확인하라. VPN 포트에 묶인 소켓과 주소가 있는 터널 인터페이스는 무언가가 돌고 있다는 증거이며, 실행 디렉터리의 텍스트 파일이 결코 그럴 수 없는 방식이다. 둘 다 없다면 파일이 무엇을 주장하든 아무것도 돌고 있지 않다.

습관처럼 파일을 지우는 것을 멈춰라

어떤 인스턴스도 그 파일을 소유하지 않고 실행 스크립트가 이 동작을 문서화한다고 확인한 뒤에는 삭제가 정당한 복구 단계다.

시작 전의 상시 습관으로 삼으면 당신이 우회하려는 검사 자체를 무력화한다. 깨끗한 종료마다 오래된 파일이 돌아온다면, 기록하는 쪽과 종료 수명 주기가 경로의 소유자를 두고 합의하지 못하는 것이며, 그 불일치가 고칠 가치가 있는 버그다.

호스트로 들어가는 독립적인 경로를 유지하고, 평소 관리자로 인스턴스 하나를 시작하고, 첫 결과를 읽어라. 다음 사람은 작동하거나 스스로를 설명하는 유닛을 받는다.

관련 글