PostgreSQL은 클라이언트가 VPN에 있다는 사실을 알지 못합니다. 주소 하나와 자격 증명 집합으로 TCP 연결을 받고, 그것을 어떻게 처리할지 결정합니다. 따라서 터널에 따라 접근을 제어하려면 세 가지 결정을 서로 맞게 배치한 뒤, 다이어그램에 그린 주소가 아니라 서버가 실제로 보는 단 하나의 주소를 확인해야 합니다.

합쳐서는 안 되는 세 가지 결정

서버가 어디에서 수신하는지는 첫 번째 결정입니다. 어떤 트래픽이 그 주소에 도달할 수 있는지는 두 번째이며, 호스트 방화벽과 그 앞의 모든 네트워크 경계가 정합니다. 어떤 데이터베이스 신원이 어느 원본에서 인증할 수 있는지는 세 번째이며, pg_hba.conf에서 정합니다.

각각은 서로 다른 구성 요소가 적용하며, 각각 다른 메시지로 실패합니다. 이들을 논의에서 합치는 것이 사람들이 방화벽 문제를 고치려고 HBA 파일을 편집하게 되는 이유입니다. 순서를 지키세요: 바인딩되지 않은 리스너에는 도달할 수 없고, 필터된 포트에는 연결할 수 없으며, HBA 규칙은 연결이 존재한 뒤에 일어나는 일만 결정합니다. 변경이 효과가 없을 때는 세 계층 중 어느 것을 실제로 바꿨는지 확인하세요.

서버가 수신하는 위치

인터페이스 이름이 아니라 머신에 실제로 할당된 주소에 바인딩하세요:

listen_addresses = '10.20.0.30'

데이터베이스는 자체 터널 인터페이스 없이 VPN 게이트웨이 뒤에 있을 수 있으며, 바로 그래서 주소를 지정하는 것이 옳습니다. 이 설정을 바꾸려면 전체 재시작이 필요하고, 다시 로드하는 것으로는 충분하지 않습니다.

그다음 포트, 보통 5432를 호스트와 그 앞의 모든 경계에서 필터링하세요. 사설 주소에 바인딩하는 것은 공개 차단의 증거가 아니며, 포트 포워딩이나 클라우드 주소 매핑이 여전히 그 사설 리스너로 패킷을 전달할 수 있기 때문입니다.

HBA가 실제로 보는 주소

라우팅된 접근에서는 서버가 각 클라이언트의 내부 터널 주소를 봅니다. 원본 변환에서는 대신 게이트웨이의 변환된 주소를 보며, 모든 클라이언트가 그 하나의 값으로 붕괴합니다. 허용할 접두사를 고르기 전에 서버 자체의 연결 증거를 통해 원본을 검사하세요.

이미 TLS와 SCRAM을 사용하는 배포에서 의도적으로 좁힌 원격 접근 예시는 다음과 같습니다:

hostssl appdb app_login 10.8.0.0/24 scram-sha-256
host all all 0.0.0.0/0 reject
host all all ::/0 reject

이것은 지정된 풀에서 TLS를 통해 역할 하나와 데이터베이스 하나를 허용한 뒤 다른 원격 TCP 접근을 거부합니다. 완전한 HBA 파일을 대체하지는 않습니다: 로컬 관리, 복제 및 기타 승인된 서비스를 유지하고, 좁은 규칙을 더 넓은 허용보다 앞에 두세요.

변환이 개입하면 HBA는 원래 주소로 클라이언트를 구분할 수 없습니다. 네트워크 허용을 엄격하게 유지하고 실제 데이터베이스 자격 증명을 요구하며, trust 인증을 실제 계정으로 대체하지 마세요.

첫 일치가 이기며, 대체는 없습니다

PostgreSQL은 파일을 위에서 아래로 읽고 연결과 일치하는 첫 레코드를 사용합니다. 그 레코드의 인증이 실패해도 두 번째 시도는 없으므로, 앞선 넓은 허용이 뒤의 거부를 조용히 무력화합니다.

이 순서 규칙이 주의 깊게 작성한 거부가 결코 효력을 내지 못하는 가장 흔한 이유입니다. 구체적인 규칙을 먼저, 넓은 규칙을 마지막에 두고, 파일을 집합이 아니라 순서로 읽으세요. 맨 아래에 추가한 규칙은 정책이 아니라 주석입니다. 파일이 무시된다고 결론 내리기 전에 그것을 위로 옮기고 다시 로드하세요.

HBA 참조는 순서와 host 및 hostssl 레코드의 차이를 모두 정의하며, 규칙의 요점이 연결이 반드시 암호화되어야 한다는 것일 때 중요합니다.

다시 로드, 재시작, 그리고 거부된 경우

HBA 변경은 다시 로드로 적용되며, pg_hba_file_rules 뷰는 구문 분석 오류를 찾는 데 도움이 됩니다. 그 뷰는 파일의 현재 내용을 설명할 뿐 실행 중인 서버가 그것을 성공적으로 로드했는지는 알려 주지 않으므로, 깨끗한 목록이 새 규칙이 활성이라는 증거는 아닙니다.

리스너 변경에는 자체 재시작이 필요하며, 변경이 효과가 없는 것처럼 보일 때 두 작업을 혼동하기 쉽습니다.

새 세션으로 테스트하세요: 의도한 계정을 가진 승인된 클라이언트는 연결되고, 같은 계정이라도 승인되지 않은 경로에서는 연결되지 않으며, 승인되지 않은 데이터베이스 신원은 VPN 내부에서도 여전히 실패합니다. 이 세 결과가 네트워크 경계와 데이터베이스 권한을 분리하며, 결정을 따로 유지하는 이유가 바로 그것입니다.

관련 글