터널은 올라오고 클라이언트도 접속하지만, 고정 주소와 그 한 사용자에게 정의한 푸시 경로가 빠져 있습니다. 로그에는 “file not found”라고 나오지 않으며, 바로 이것 때문에 사람들이 인증서를 다시 만들러 갑니다. 이런 경우 대부분 데몬은 테스트한 셸과 다른 디렉터리에서 실행되고, client-config-dir 는 가정한 방식으로 해석된 적이 없습니다. 고칠 것은 경로 수정이지 자격 증명 재설정이 아닙니다.

설정을 건드리기 전에 유닛을 읽어라

편집한 파일이 아니라 실제로 도는 프로세스에서 시작하십시오. systemd에 실행 줄, 작업 디렉터리, 권한을 내리는 계정을 물으십시오. 이 세 답이 이 부류의 장애 대부분을 설명합니다:

systemctl show openvpn-server@server -p ExecStart -p WorkingDirectory -p User -p RootDirectory

빈 WorkingDirectory 은 유닛이 / 에서 시작한다는 뜻이므로, 상대 경로 client-config-dir ccd 는 /ccd 에서 찾습니다. 그 디렉터리는 거의 존재하지 않고, 데몬은 그 부재를 치명적으로 보지 않습니다.

테스트할 때 쓴 대화식 실행과 비교해 보십시오. 그때는 셸의 현재 디렉터리가 설정 디렉터리였을 것입니다. 같은 파일, 같은 키워드, 다른 결과 둘.

상대 경로는 무엇을 기준으로 해석되는가

키워드는 옵션이 사용되는 시점의 프로세스 작업 디렉터리를 기준으로 해석됩니다. “--config 로 넘긴 설정 파일 옆”이라는 뜻이 아닙니다. OpenVPN은 절대 경로의 설정을 거리낌 없이 읽고도 상대 값은 다른 곳에서 해석하며, 여기서 바로 그 함정이 생깁니다. OpenVPN 2.6 설명서는 그 규칙을 --client-config-dir 항목과 --cd 항목에서 밝힙니다.

cd 키워드는 다른 파일을 읽기 전에 그 문맥을 바꾸므로, cd /etc/openvpn/server 을 설정한 뒤 client-config-dir ccd 을 두는 유닛은 /etc/openvpn/server/ccd 로 해석됩니다. cd 을 더한다면 지시문 순서를 확인하고, 같은 파일의 다른 모든 상대 참조에 영향을 준다는 점을 기억하십시오.

데몬의 계정으로 경로를 따라가라

경로가 맞아도 읽히지 않을 수 있습니다. 권한을 내린 뒤 데몬은 더 이상 root가 아니므로, 모든 상위 디렉터리에 그 계정의 검색 권한이 필요하고 클라이언트 파일 자체에는 읽기 권한이 필요합니다. 상위 디렉터리 하나에서 실행 비트가 빠지면 파일이 숨겨지고, 증상은 조용히 기본 풀을 받는 클라이언트로만 나타납니다.

namei 는 각 구성 요소의 권한을 순서대로 출력하므로 디렉터리를 하나씩 확인하는 것보다 빠릅니다:

namei -l /etc/openvpn/server/ccd/client1

다음으로 자신이 아니라 서비스 계정으로 읽기를 시험하십시오:

runuser -u openvpn -- test -r /etc/openvpn/server/ccd/client1 && echo readable

유닛이 chroot 을 쓰면 디렉터리는 감옥 안에 있어야 하고, 설정의 경로는 chroot가 적용된 뒤 해석됩니다. 감옥 밖 호스트에 있는 파일은 안에서 보이지 않습니다.

추측하지 말고 조회를 확인하라

재시작 한 번을 위해 로그 수준을 올리고, 클라이언트별 옵션에 대해 서버가 무엇을 말하는지 읽으십시오. verb 4 에서 데몬은 가져온 클라이언트별 설정을 보고하므로, 줄이 없다면 그 연결에 어떤 파일도 읽히지 않았다는 직접 증거입니다.

openvpn --config /etc/openvpn/server.conf --verb 4 --client-config-dir /etc/openvpn/server/ccd

여분 포트에서 포그라운드로 실행하고 클라이언트 하나를 붙이십시오. 그러면 systemd가 그림에서 완전히 빠집니다. 여기서는 재정의가 나타나고 서비스 아래에서는 나타나지 않는다면, 차이는 파일이 아니라 유닛의 문맥입니다.

일치하는 파일이 없을 때 어떻게 할지 정하십시오. ccd-exclusive 이 없으면 클라이언트는 전역 풀 설정만으로 허용되며, 그것이 위에서 말한 조용한 실패입니다. 이것이 있으면 파일 부재가 거부된 연결이 되고, 그 거부는 알아채기 쉽지만 부하 아래에서는 디버깅이 어렵습니다.

고치고, 재시작하고, 검증하라

설정에서 디렉터리를 절대 경로로 만들고 그대로 두십시오. 상대 경로는 유닛이 작업 디렉터리를 고정할 때만 안전하고, 고정은 나중에 누군가 걷어낼 여분의 가동 부품입니다.

client-config-dir /etc/openvpn/server/ccd
ccd-exclusive

인스턴스를 재시작하고 알려진 클라이언트 하나를 다시 연결한 뒤, 받은 주소와 그쪽으로 푸시된 경로를 함께 읽으십시오. 주소가 그 클라이언트 파일의 ifconfig-push 줄과 일치하면 조회가 동작한 것입니다. 클라이언트가 여전히 일반 풀로 떨어진다면 로그 줄 수로 돌아가십시오. 가져오기가 하나도 없으면 경로나 신원이 틀린 것이고, 내용이 잘못된 가져오기가 하나 있으면 데몬이 읽는 것과 다른 파일을 편집하는 것입니다.

이전 유닛과 설정을 함께 되돌려 롤백한 뒤 재시작하십시오. 이 일 때문에 인증서를 다시 발급할 필요는 없고, 디렉터리 문제를 자격 증명 문제로 다루는 것이 오 분짜리 수정을 유지보수 창으로 바꾸는 길입니다.

관련 글