OpenVPN이 프로필을 불러오는데도 ca.crt를 찾지 못한다
프로필 경로는 그 안에 있는 파일들의 기준이 아닙니다. 절대 --config가 왜 여전히 ca.crt에서 실패하는지, 그리고 시작 방식이 어떻게 답을 정하는지 살펴봅니다.
서비스가 시작되고 프로필을 아무 불평 없이 읽은 뒤, 무관해 보이는 줄에서 죽습니다. ca.crt 파일을 열 수 없는 것입니다. 인증서에는 아무 변화가 없고 unit 파일의 프로필 경로는 절대 경로입니다. 바로 이 조합이 단서입니다. 넘긴 경로는 파일 하나를 가리키지만, 그 파일 안의 이름들은 전혀 다른 곳에서 해석됩니다. 그래서 완전히 정규화된 것처럼 보이는 시작도 아무도 의도하지 않은 디렉터리에서 키를 읽고 있을 수 있습니다.
실패의 원인은 몇 가지뿐이며, 순서대로 나눠 볼 가치가 있습니다. 프로세스가 실제로 가진 기준 디렉터리, 서비스의 시작 컨텍스트, 그리고 경로가 맞은 뒤의 파일 주변 권한이나 샌드박스입니다. 각각은 unit에, 프로세스에, 파일 시스템에 다른 흔적을 남깁니다.
프로필 경로는 기준 디렉터리가 아니다
/tmp에서 시작해 /etc/vpn/prod/tenant-a.ovpn를 받은 프로세스를 상상해 보십시오. 그 프로필 안에서 ca ca.crt 줄은 상대 경로를 가리킵니다. 프로필을 찾은 인자 어디에도 그 이름을 다시 쓰는 부분이 없으므로, 프로세스는 /tmp/ca.crt를 찾고 파일이 없다고 보고합니다.
혼란스러운 것은 오류의 순서입니다. OpenVPN은 구성을 먼저 파싱하고 참조된 파일에 도달할 때마다 엽니다. 그래서 프로필의 오타는 어떤 키도 건드리기 전에 보고되고, 빠진 인증서는 파싱이 그 지점에 이르러서야 나타납니다. 따라서 프로필이 로드된다는 것은 문법이 맞다는 증거일 뿐, 그 프로필이 지목한 파일들이 발견되었다는 증거는 아닙니다.
매뉴얼이 구분하는 것: --config와 --cd
OpenVPN 2.6 매뉴얼은 두 가지 다른 옵션을 설명합니다. 하나는 구성 파일을 불러옵니다. 다른 하나는 구성, 키, 스크립트 및 기타 파일을 읽기 전에 프로세스 디렉터리를 바꾸며, 현재 디렉터리를 참조하지 않는 절대 디렉터리를 요구합니다.
openvpn --cd /etc/vpn/prod --config tenant-a.ovpn
그 호출은 하나의 형태일 뿐, 남의 프로필을 시작하라는 지시가 아닙니다. 그것이 주는 것은 결정성입니다. 체인의 모든 상대 이름에 대한 기준이 프로세스를 시작한 셸이나 관리자로부터 상속되는 대신 명령 안에 적힙니다. 대안도 똑같이 유효하며 서비스에는 종종 더 낫습니다. 작업 디렉터리는 그대로 두고 프로필 안의 참조 파일을 모두 절대 경로로 만드십시오.
어느 쪽을 택하든 첫 실패가 아니라 체인 전체를 감사하십시오. 프로필은 다른 구성 파일을 끌어들일 수 있고, 포함된 파일의 상대 이름은 그것을 포함한 파일의 디렉터리가 아니라 같은 프로세스 디렉터리를 기준으로 해석됩니다. 로그 경로, 인증 파일, 보조 스크립트도 같은 규칙을 따릅니다.
서비스는 다른 곳에서 시작된다
프로필 디렉터리의 대화형 셸은 패키징된 unit에 대해 아무것도 증명하지 않습니다. 관리자는 자기 작업 디렉터리를 설정하고, 래퍼 스크립트가 바이너리 실행 전에 그것을 다시 바꿀 수 있습니다. 실패하는 unit만이 추론할 가치가 있는 유일한 시작입니다.
systemctl show -p WorkingDirectory -p ExecStart --value openvpn@tenant-a
ls -l /proc/$(pgrep -n openvpn)/cwd
두 번째 명령은 살아 있는 프로세스가 실제로 쥐고 있는 디렉터리를 보여 주며, 래퍼가 관여할 때는 unit 파일보다 신뢰할 수 있습니다. 둘이 서로 다르다면 답은 래퍼이고 unit은 잘못된 단서입니다.
탐색 이후: 권한, chroot, 샌드박스
기준 디렉터리가 맞아도 같은 메시지가 나올 수 있습니다. 해석과 접근이 별개의 단계이기 때문입니다. 프로세스는 모든 상위 디렉터리에 실행 권한이, 파일에는 읽기 권한이 필요하며, 파일 시스템의 일부를 숨기는 서비스 unit은 프로세스가 애초에 볼 수 있는 것 자체를 바꿉니다.
흔한 세 가지 형태가 같은 오류를 만듭니다. 파일이 root만 읽을 수 있는데 서비스는 열기 전에 권한을 내려놓습니다. unit이 프로필 디렉터리를 포함하지 않는 보호용 파일 시스템 보기를 설정합니다. 데몬이 chroot로 실행되므로 호스트에 있는 경로가 그 보기 안에는 없습니다.
권한을 느슨하게 하는 대신 파일 소유자와 프로세스 신원으로 진단하십시오. 이 오류를 잠재우려고 개인 키를 모두가 읽을 수 있게 만드는 것은 시끄러운 실패를 조용한 실패로 바꾸는 일이며, 키는 디렉터리에서 가장 노출하고 싶지 않은 부분입니다.
직접 소유한 시작으로 수정을 증명하라
프로필과 무관한 디렉터리에서 실제 unit을 다시 시작하고 같은 시작 줄을 지켜보십시오. 그다음 프로세스가 실행 중에 의도한 디렉터리를 쥐고 있는지, 불러온 인증서가 기대한 것인지 확인하십시오.
systemctl restart openvpn@tenant-a
systemctl status openvpn@tenant-a --no-pager
journalctl -u openvpn@tenant-a -n 20 --no-pager
경로 로딩이 성공해도 인증과 라우팅은 여전히 각자의 실패를 가진 별개 단계이며, 연결이 올라오지만 트래픽이 지나지 않는 것은 다른 조사입니다. 여기서의 수정은 파일이 어느 디렉터리에서 왔는지에 관한 것뿐이며, 마지막으로 손으로 실행한 사람의 기억이 아니라 호출 안에서 보여야 합니다.
프로필을 구성 관리자로 배포한다면 기준 디렉터리나 절대 파일 이름도 거기에 두십시오. 한 호스트에서 손으로 고친 것은 다음 재구축 뒤에 다시 돌아오는 이 문제의 판본입니다.