플러그인은 아직도 현재 빌드보다 오래된 스레드에서 권장되며, 어제 컴파일한 서버에서는 로드할 때 실패합니다. 이것은 경로로 고칠 수 있는 구성 오류가 아닙니다. 플러그인과 스크립트 훅은 같은 문제를 다른 계층에서 해결하며, 하나에서 다른 것으로 옮기면 무엇을 설치해야 하는지, 무엇이 서버 권한으로 실행되는지, 실패한 로그인이 실제로 무엇을 말하는지가 달라집니다.

신화: 플러그인이 지원되는 경로다

플러그인은 OpenVPN 프로세스에 로드되는 공유 객체이므로, 그 프로세스가 노출하는 인터페이스와 일치해야 합니다. 빌드는 바뀌고 패키징도 바뀌며, 이전 인터페이스용으로 컴파일된 라이브러리는 로드를 거부합니다. 서버 구성으로는 그 격차를 메울 수 없어서 "그냥 radiusplugin을 설치하라"는 조언은 시작되지 않는 서버로 끝납니다.

스크립트 훅은 대신 프로세스 밖에 있습니다. OpenVPN은 프로그램을 실행하고 자격 증명을 넘기며 판정을 읽습니다. 그 분리가 업그레이드를 견디게 하고, 동시에 플러그인에는 없던 방식으로 그것을 당신의 책임으로 만듭니다.

어느 접근도 구조상 더 안전하지 않습니다. 하나는 데몬 안에서 외부 코드를 실행하고, 다른 하나는 자격 증명을 손에 쥔 채 당신의 코드를 옆에서 실행합니다. 올바른 질문은 이 두 위험 중 어느 것을 실제로 운영할 수 있느냐입니다.

플러그인이 묶어 두었던 것

플러그인은 RADIUS 호스트, 공유 비밀, 재시도 횟수, 시간 제한이 담긴 자체 구성 파일을 가졌고, 서버 구성은 한 줄로 그것을 참조했습니다. 자격 증명 처리는 서버 프로세스 안에 남았으므로, 비밀번호가 관리자가 보호해야 할 프로세스 경계를 넘는 일은 없었습니다.

대가는 결합이었습니다. 모든 OpenVPN 업그레이드가 호환되지 않는 인터페이스 위험을 안았고, 패키지를 다시 빌드하는 모든 배포판이 더는 맞지 않는 라이브러리를 만들 위험을 안았습니다. 그런 일이 생기면 실패는 크고 즉각적이며, 그것이 이 설계의 유일한 자비입니다.

그런 플러그인이 아직 당신의 빌드에 로드된다면, 더 작은 운영 표면일 수 있습니다. 어떤 인터페이스용으로 만들어졌는지 확인하고, 시험한 빌드에 고정하며, 모든 업그레이드를 일상적인 패키지 업데이트가 아니라 전체 로그인 시험이 필요한 변경으로 다루십시오.

스크립트 훅이 실제로 신뢰하는 것

훅은 auth-user-pass-verify와 전달 방식, 즉 환경 변수나 임시 파일로 구성합니다. 환경 변수 방식에서는 OpenVPN이 script-security 3을 요구하며, 이는 스크립트에 비밀번호 노출을 허용하는 문서화된 수준입니다. 그 수준은 기본값의 의도적 약화이며, 근거가 첨부된 허가로 다루어야 합니다.

스크립트가 만지는 모든 것이 그 신뢰를 물려받습니다. root 소유여야 하고, 그룹이나 다른 이가 쓸 수 없어야 하며, 절대 경로로 참조되고, 신뢰할 수 없는 값이 셸에 도달하는 곳이 없어야 합니다. 모든 변수를 인용하고, 예상치 못한 문자를 거부하며, 주어진 사용자 이름으로 명령을 만들지 마십시오. 모든 로그인 시도에서 root로 실행되는 스크립트는 바로 그 네 가지 속성 때문에 한 번 검토할 가치가 있습니다.

ls -l /usr/local/sbin/radius-auth.sh
stat -c '%U %a' /usr/local/sbin/radius-auth.sh

파일 전달 방식은 환경 상속 문제를 피하고 제한된 권한의 임시 파일로 스크립트에 자격 증명을 넘깁니다. 클라이언트가 지원한다면 보통 더 나은 기본값이며, 실패 시 정리할 객체가 하나 더 늘어날 뿐입니다.

종료 코드가 열린 실패가 될지를 결정한다

스크립트의 종료 상태가 판정입니다: 영은 수락, 영이 아니면 거부. 문제를 일으키는 패턴은 RADIUS 응답에 특정 수락 토큰이 있을 때만 수락하고 나머지 모두에 실패를 돌려주는 셸 스크립트인데, 그것은 세 가지 다른 사건을 하나의 답으로 뭉개기 때문입니다. 잘못된 비밀번호, 도달할 수 없는 서버, 망가진 응답이 모두 같은 거부가 됩니다.

훅이 수락이나 거부만 돌려줄 수 있어도 그 경우들을 스크립트에서 분리하십시오. 백엔드 결과를 따로 기록하고, 시간 초과와 전송 오류에 경보를 걸며, 서비스가 죽어서 인증이 실패하는지 사용자가 잘못 입력해서인지를 모니터링에서 분명히 하십시오.

두 가지 습관이 나머지를 온전하게 지킵니다. RADIUS가 권위라면 비밀번호를 확인하는 유일한 곳이어야 하는데, 그림자 테이블은 같은 질문에 두 개의 답을 만들고 두 번째는 아무도 지켜보지 않는 공격 표면이기 때문입니다. 그리고 훅은 재시도마다 다시 호출되므로, 느린 스크립트와 성급한 클라이언트가 만나면 RADIUS 쪽에 지연이나 정책을 더하지 않는 한 비밀번호 추측의 증폭기가 됩니다.

인증서가 사라질 때 포기하는 것

이 형태의 많은 배포는 클라이언트 인증서 검사를 완전히 끄고 사용자 이름과 비밀번호를 클라이언트의 주장 전부로 남깁니다. 그 설정에서 사라지는 것은 인증서 기반 신원입니다. 채널은 암호화된 채로 남지만, 클라이언트를 지명하는 유일한 것은 RADIUS 판정입니다. 예전에 인증서 주체에 기대던 하위의 모든 것은 이제 사용자 이름에 기대야 합니다.

제어 채널 보호를 유지해 인증되지 않은 피어가 핸드셰이크를 탐색하거나 범람할 수 없게 하고, 사용자별 구성이 공통 이름에 의존할 때는 username-as-common-name을 사용하십시오. 관리형 게이트웨이는 흔히 다르게 해결하여 RADIUS와 EAP-TLS로 대화하는 게이트웨이에서 인증서 인증을 종료하며, 그 경우 이 서버 지시문은 어느 것도 적용되지 않습니다. 이웃 제품의 모델이 아니라 자신의 플랫폼이 문서화한 모델을 복사하십시오. 중요한 지시문들은 서로 충분히 달라서 섞으면 구문 분석은 되지만 아무도 인증하지 않는 구성이 됩니다.

관련 글