수정: OpenVPN이 표준 입력에서 Auth 사용자 이름을 읽지 못함
OpenVPN의 «could not read Auth username from stdin» 오류는 로컬 입력 실패입니다. 서비스에 읽을 수 있는 자격 증명 소스를 제공하세요. script-security와는 관련이 없습니다.
could not read Auth username from stdin 인증 문제처럼 보이지만 그렇지 않습니다. OpenVPN이 표준 입력에서 사용자 이름을 요구하려 했지만 읽을 수 있는 것이 없었고, 서버에 연결하기도 전에 멈췄습니다. 계정은 충분히 유효할 수 있으며, 프로세스에 물어볼 대상이 없을 뿐입니다.
따라서 첫 번째 유용한 단계는 클라이언트가 무엇을 읽는지 확인하는 것이지, 연결을 다시 시도하거나 서버 쪽 설정을 바꾸는 것이 아닙니다. 아래 검사를 순서대로 진행하고 처음 실패하는 지점에서 멈추세요.
오류를 로컬 입력 실패로 읽기
auth-user-pass가 파일 인수 없이 나타나면, 클라이언트는 묻기를 기대합니다. 대화형 셸에서는 프로세스가 터미널을 소유하므로 그 프롬프트가 동작합니다. systemd, cron 작업 또는 컨테이너 아래에서는 표준 입력이 보통 비어 있고, 읽기는 보고 있는 오류와 함께 즉시 반환됩니다.
메시지는 실패한 필드, 즉 사용자 이름이나 비밀번호도 알려 주므로 읽기가 어디까지 진행되었는지 알 수 있습니다. 사용자 이름이 없으면 프로세스가 아무것도 읽지 못한 것입니다. 사용자 이름이 성공한 뒤 비밀번호가 없으면 두 번의 읽기 사이에 입력 스트림이 끝난 것이며, 이는 절반만 기록된 파일이나 닫힌 파이프에서 흔합니다.
다른 무엇을 바꾸기 전에 클라이언트 자체의 관점을 확인하세요. 같은 구성과 같은 사용자로 포그라운드에서 실행하고 프롬프트가 나타나는지 보세요. 셸에서는 나타나지만 서비스 관리자 아래에서는 나타나지 않는다면 차이는 입력 소스에 있고 자격 증명에 있지 않습니다. unit 파일과 셸 환경을 빠르게 비교하면 보통 어느 쪽이 터미널을 제공하는지 알 수 있습니다.
서비스에 지원되는 자격 증명 소스 제공
무인 실행에 지원되는 소스는 인수로 전달하는 자격 증명 파일입니다: auth-user-pass. 파일은 일반 텍스트로 읽히며 첫 줄이 사용자 이름, 둘째 줄이 비밀번호입니다. 다음과 같은 절대 경로로 지정하세요: /etc/openvpn/client/creds, 그러면 서비스 계정의 작업 디렉터리가 지시문의 의미를 바꿀 수 없습니다.
권한은 경로만큼 중요합니다. 파일은 클라이언트를 실행하는 계정이 읽을 수 있어야 하고 다른 모든 사람은 읽을 수 없어야 하며, 서비스 계정 또는 서비스를 포함하는 그룹을 가진 root가 소유해야 합니다. 내용을 출력하지 않고 해당 계정으로 읽기 가능 여부를 확인하세요.
상대 경로는 조용한 실패 유형입니다. 프로필이 한 디렉터리에 있는데 systemd가 프로세스를 다른 곳에서 시작하면 셸에서 해석되는 파일이 서비스에서는 해석되지 않습니다. 자격 증명을 고정된 위치로 옮기고 절대 경로로 참조하세요. 그런 다음 서비스를 한 번 시작해 프로필 편집기의 보기를 믿는 대신 같은 경로가 사용되는지 확인하세요.
배포에 일회용 코드나 다른 대화형 과제가 필요하다면 클라이언트의 워크플로가 정말 무인으로 지원하는지 결정하세요. 정적 비밀번호가 있는 파일은 회전하는 코드에 답할 수 없고, 답할 수 없는 프롬프트를 다시 시도해도 정보가 늘지 않습니다.
script-security가 도움이 되지 않는 이유
script-security 는 클라이언트가 스크립트를 실행할 수 있는지, 얼마나 전달할 수 있는지, 환경 변수로 스크립트에 비밀번호를 넘길 수 있는지까지 제어합니다. 사용자 이름과 비밀번호가 애초에 어디서 오는지에 대해서는 아무 말도 하지 않습니다.
메시지에 Auth가 언급되어 수준을 올리는 것은 흔한 반사이지만, 입력 소스가 아니라 스크립트 권한을 바꾸고 클라이언트가 실행할 수 있는 범위를 넓힙니다. 보조 스크립트가 설계의 일부라면 먼저 입력 소스를 고치고 보안 수준은 배포에 필요한 최솟값으로 유지하세요.
관리 인터페이스는 합법적인 대안입니다. 프런트엔드가 연결해 자격 증명 요청을 받고 사용자 이름과 비밀번호로 응답할 수 있으며, 일부 GUI가 이렇게 동작합니다. 사용자의 제어 채널이기에 필요하다면 로컬 주소에 바인딩하고 관리 비밀번호 파일로 보호하며 연결할 수 있는 대상을 제한하세요.
클라이언트가 파일을 읽은 뒤 다음 단계 확인
클라이언트가 자격 증명을 읽을 수 있게 되면 다음 실패는 서버와의 실제 교환이며 그 메시지의 의미는 다릅니다. 그 단계의 인증 실패는 서버가 계정을 거부했다는 뜻이고, 과제 응답은 서버가 다른 요소를 원한다는 뜻입니다. 같은 문제의 반복이 아니라 새 문제로 다루세요.
서비스가 실행할 방식 그대로 전체 경로를 시험하세요: 같은 계정, 같은 작업 디렉터리, 같은 unit 환경. 셸에서 시작할 때만 동작하는 연결은 환경 변수나 터미널이 아직 흐름의 일부라는 신호입니다.
그다음 비밀을 있어야 할 곳에 두세요. 명령줄 인수의 비밀번호는 프로세스 표에 나타나고, 디버그 출력의 비밀번호는 티켓에 남습니다. 보호된 파일이나 관리 인터페이스를 사용하고, 자격 증명을 반복하지 않는 수준으로 로그를 유지하며, 접근 권한이 있는 사람이 떠나면 파일을 교체하세요.
체크리스트: 절대 자격 증명 경로, 서비스 계정으로 읽을 수 있음, 터미널 불필요, script-security는 최솟값 유지, 관리 인터페이스는 바인딩과 인증이 있을 때만, 그리고 결과 서버 응답은 별도 사건으로 취급.