PAM 인증은 수동으로는 되지만 OpenVPN 서비스로는 실패한다
root 셸에서는 되고 systemd 아래에서는 실패하는 PAM 로그인은 비밀번호가 아니라 헬퍼를 가리킵니다. 권한, 파일 접근, SELinux를 분리하십시오.
PAM을 통한 인증은 클라이언트를 수동으로 실행하면 성공하고, systemd가 같은 프로필을 시작하면 AUTH_FAILED와 함께 실패할 수 있습니다. 이 두 실행 사이에 비밀번호는 바뀌지 않습니다. 바뀌는 것은 PAM에 질문하는 프로세스를 둘러싼 제약의 집합입니다. PAM은 자체 자격 증명을 변경하는 능력을 가진 헬퍼를 통해 응답하며, 강화된 unit이 제거하는 것이 바로 그 능력입니다. 능력 목록을 건드리기 전에 그 헬퍼와 필요한 경계를 찾으십시오.
unix_chkpwd는 PAM 질문에 답하는 바이너리입니다
로컬 비밀번호 인증에서는 pam_unix가 해시 파일 자체를 거의 읽지 않습니다. 그것은 unix_chkpwd를 실행하며, 배포판은 이를 setuid root 또는 setgid shadow로 설치해 /etc/shadow를 읽을 일이 없는 프로세스를 대신해 하나의 비밀번호를 검사할 수 있게 합니다. 그 정체성을 얻을 능력을 제거하면 헬퍼가 검사를 완료할 수 없으므로 모듈은 단순한 인증 실패를 반환합니다.
그러면 실패는 클라이언트가 볼 수 있는 모든 로그에서 자격 증명 문제처럼 보입니다. 이것이 함정입니다. 클라이언트는 PAM이 자신에게 말한 것을 보고하고, PAM은 스택이 아니라고 했다는 것만 보고합니다. 헬퍼를 root로 수동 실행하는 것도 아무것도 증명하지 못합니다. 서비스가 절대 사용하지 않는 권한 경로를 시험할 뿐이기 때문입니다. systemd가 실제로 로드한 unit을 읽고, 그다음 시도에 대한 시스템 로그를 읽으십시오. 이 두 관점이 샌드박스 문제와 잘못된 비밀번호 문제를 구분합니다.
비밀번호 로그를 읽기 전에 unit을 읽으십시오
패키지된 unit에는 직접 작성하지 않은 drop-in이 포함될 수 있으며, 실효 구성은 병합된 결과입니다. systemd가 보는 그대로 unit을 출력하고, 헬퍼가 스스로 권한을 높일 수 있는지를 결정하는 샌드박스 설정도 함께 보십시오. 이 단계에서는 읽기 전용 점검으로 충분합니다.
systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -b
첫 번째 명령은 unit과 그 drop-in이 어디에서 오는지 보여 줍니다. 몇 달 전에 추가된 재정의가 왜 존재하는지에 대한 기억보다 오래 살아남기 때문에 중요합니다. 두 번째는 다음 두 절이 의존하는 샌드박스 값을 출력합니다.
보이는 것을 같은 배포판과 버전의 정상 호스트와 비교하십시오. User, CapabilityBoundingSet, NoNewPrivileges의 차이는 구체적인 단서입니다. 산문 주석의 차이는 단서가 아닙니다. 무엇이든 바꾸기 전에 값을 적어 두십시오. 움직이는 목표와의 나중 비교는 아무것도 증명하지 못합니다. 서비스가 권한 없는 계정과 빈 bounding 집합으로 실행된다면 헬퍼가 쓸 수 있는 것이 거의 없습니다.
자격 증명 변환, 파일 접근, 정책은 세 가지 경계입니다
exec 중에 일어나는 일부터 시작하십시오. setuid 바이너리나 파일 능력을 가진 파일은 자격 증명 변환을 일으키므로 결과 정체성은 호출자의 연속이 아닙니다. bounding 집합은 그러한 파일이 얻을 수 있는 것을 제한하고, NoNewPrivileges는 setuid, setgid, 파일 능력 획득을 완전히 차단합니다. 이 셋 중 어느 하나라도 헬퍼를 멈출 수 있으며 다른 모든 서비스 기능은 그대로 남습니다.
다음으로 넓은 재량 우회와 좁은 읽기 접근을 분리하십시오. CAP_DAC_OVERRIDE는 거의 모든 곳에서 재량 검사를 건너뛰고, CAP_DAC_READ_SEARCH는 자체 추가 권한으로 읽기와 디렉터리 순회를 처리합니다. 둘은 영향 범위가 다른 서로 다른 도구이며, 어느 것도 PAM이 shadow 파일을 읽게 하라라는 문장의 철자가 아닙니다.
마지막으로 강제 정책이 그 행위를 허용하는지 물으십시오. Linux 능력은 SELinux를 무시하지 못하며, 하나를 보유한다고 해서 type enforcement 규칙에 대해 증명되는 것은 없습니다. 파일 접근 거부와 능력 거부를 서로 다른 증거로 다루십시오. 서로 다른 수정과 종종 서로 다른 담당자를 가리키기 때문입니다. denied라는 한 단어가 아니라 레코드의 모든 필드를 읽으십시오. 어느 실행 파일이 행위를 했는지, 어느 도메인에서 실행되었는지, 어떤 유형의 대상에 닿았는지, 어떤 객체 클래스가 관련되었는지, 정책이 어떤 권한을 거부했는지가 각각 다른 방식으로 답을 좁힙니다.
감사 로그에서 거부를 끌어내십시오
강제 모드 호스트에서 거부를 기록하는 곳은 감사 추적뿐입니다. 최근 이벤트를 조회하고 실패한 로그인의 타임스탬프를 기준으로 읽으십시오. 조사를 시작한 시각이 아닙니다.
ausearch -m AVC,USER_AVC -ts recent
빈 결과는 무죄의 증거가 아닙니다. 감사가 수집하지 않거나, 당신의 시간 창이 시도를 놓쳤다는 뜻이며, 정책을 배제하기 전에 두 가능성을 모두 배제해야 합니다.
Red Hat의 SELinux 문제 해결 안내서는 라벨과 구성 검사를 allow 규칙 생성보다 앞에 둡니다. 이 문제에도 올바른 순서입니다. 잘못 라벨이 붙은 헬퍼 바이너리와 정책의 틈은 비슷한 거부를 만들지만 다른 수리가 필요합니다. 라벨 오류에 대해 allow 규칙을 생성하면 결함을 숨기고 다음 패키지 업데이트가 다시 들여오게 합니다. 어떤 정책이든 작성하기 전에 설치된 헬퍼의 라벨을 확인하십시오.
수락되는 로그인 하나와 거부되는 로그인 하나로 변경을 증명하십시오
시연한 경계만 변경하고 두 결과를 모두 시험하십시오. 인증되어야 하는 계정은 성공해야 하고, 잘못된 비밀번호의 계정은 여전히 실패해야 합니다. 모든 시도를 성공시키는 변경은 인증을 수리한 것이 아니라 제거한 것입니다.
실제 연결 시도를 하고 바로 그 뒤에 저널을 읽으십시오. 수정을 증명하는 줄은 그 시도의 pam_unix(openvpn:auth) 항목입니다. 인증 성공이라고 적혀 있어야 하고, 어떤 AVC 레코드도 같은 초를 가져서는 안 됩니다.
journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpn
정상 터널에는 재연결도 필요합니다. 샌드박스 변경은 첫 번째 연결보다 두 번째 연결을 더 자주 끊기 때문입니다. 재연결 후 수립된 소켓을 확인하고 같은 unit이 여전히 그것을 서비스하는지 확인하십시오.