프로그래밍/서버, DBMS

PostgreSQL sslcertmode 기준 정리

포도알77 2026. 8. 12. 15:26

본문 중간의 쿠팡 추천 상품 구매시 쿠팡 파트너스에서 일정액의 수수료를 제공받습니다.

PostgreSQL libpq의 sslcertmode는 클라이언트 인증서를 서버에 보낼 수 있는지, 또는 서버가 인증서를 반드시 요청해야 하는지를 정하는 연결 파라미터입니다. 서버 인증서를 검증하는 sslmode와 이름은 비슷하지만, 실제로는 보는 방향이 다릅니다.

sslmode=verify-full은 클라이언트가 서버 인증서를 얼마나 엄격하게 검증할지에 가깝습니다. 반면 sslcertmode는 서버가 클라이언트 인증서를 요청했을 때 libpq가 그 인증서를 보낼지, 그리고 그 요청 자체를 기대할지에 관한 옵션입니다.

sslcertmode는 어디에서 동작하나

PostgreSQL 클라이언트가 SSL 연결을 만들 때 서버는 필요에 따라 클라이언트 인증서를 요청할 수 있습니다. libpq는 기본 위치의 인증서와 키를 찾거나, 연결 파라미터로 지정된 sslcert, sslkey 값을 사용할 수 있습니다.

이때 sslcertmode는 인증서가 준비되어 있어도 무조건 보내는 옵션이 아닙니다. 서버가 클라이언트 인증서를 요청하는 흐름 안에서, libpq가 인증서를 보낼 수 있는지와 그 요청을 필수로 볼지를 결정합니다.

세 가지 값의 차이

동작 쓰기 좋은 상황
disable 사용 가능한 클라이언트 인증서가 있어도 서버에 보내지 않는다. 기본 인증서 파일이 우연히 전송되는 것을 막고 싶을 때 검토한다.
allow 기본값이다. 서버가 요청하고 클라이언트가 보낼 인증서를 가지고 있으면 보낼 수 있다. 일반적인 호환 동작을 유지하고 싶을 때 무난하다.
require 서버가 클라이언트 인증서를 요청해야 한다. 클라이언트가 인증서를 보내지 않았는데도 인증이 성공하면 연결은 실패한다. 복잡한 TLS 설정에서 실제 인증서 요청 흐름을 확인해야 할 때 쓸 수 있다.

공식 문서 기준으로 기본값은 allow입니다. 따라서 sslcertmode를 지정하지 않아도 서버가 인증서를 요청하고 클라이언트에 인증서와 키가 있으면 전송될 수 있습니다. 이 기본 동작이 불편한 환경에서는 disable을 명시하는 편이 더 읽기 쉽습니다.

require가 추가 보안을 뜻하지는 않는다

sslcertmode=require는 이름만 보면 클라이언트 인증서 보안을 강제하는 옵션처럼 보일 수 있습니다. 그러나 PostgreSQL 문서는 이 값이 추가 보안을 더하지 않는다고 설명합니다. 서버가 인증서를 요청했다는 사실만으로 서버가 그 인증서를 올바르게 검증했다고 보장할 수 없기 때문입니다.

즉 이 옵션은 “서버가 클라이언트 인증서를 신뢰성 있게 검증한다”를 증명하는 설정이 아닙니다. 클라이언트 인증서 인증이 실제 접근 제어로 쓰이는지는 서버의 SSL 설정, 인증 설정, 인증서 체인, 사용자 매핑 정책을 함께 봐야 합니다.

 

 

sslmode와 같이 봐야 하는 이유

sslmodesslcertmode는 같은 보안 단계를 조절하는 옵션이 아닙니다. sslmode는 SSL 사용 여부와 서버 인증서 검증 수준을 정합니다. sslcertmode는 클라이언트 인증서 전송 조건을 정합니다.

예를 들어 서버 인증서를 엄격하게 확인해야 하는 원격 연결이라면 sslmode=verify-full을 검토합니다. 반대로 클라이언트 인증서를 서버에 보내면 안 되는 환경이라면 sslcertmode=disable을 검토합니다. 두 설정은 서로 보완될 수 있지만, 하나가 다른 하나를 대신하지 않습니다.

host=db.example.com dbname=service user=app sslmode=verify-full sslcertmode=disable

위 예시는 서버 인증서는 엄격하게 검증하되, 클라이언트 인증서는 보내지 않겠다는 의도를 드러냅니다. 반대로 클라이언트 인증서를 쓰는 환경이라면 sslcert, sslkey, sslpassword까지 같이 관리해야 합니다.

클라이언트 인증서 파일 기준

libpq는 기본적으로 사용자 홈의 .postgresql 디렉터리에서 클라이언트 인증서와 개인 키를 찾습니다. 기본 인증서 파일은 postgresql.crt, 기본 키 파일은 postgresql.key입니다. 다른 위치를 쓰려면 sslcertsslkey 연결 파라미터를 지정할 수 있습니다.

Unix 계열에서는 개인 키 파일 권한도 중요합니다. 공식 문서는 개인 키 파일이 group 또는 world 접근을 허용하면 안 된다고 설명하며, 일반적인 예로 0600 권한을 제시합니다. 운영 환경에서는 키 파일 권한, 배포 방식, 백업 범위를 함께 관리해야 합니다.

개인 키가 암호화되어 있으면 sslpassword 연결 옵션으로 passphrase를 제공할 수 있습니다. 이 옵션은 환경변수 대응값이나 .pgpass 조회 기능이 없다는 점도 같이 알아두는 편이 좋습니다.

환경변수로도 지정할 수 있다

libpq 환경변수 목록에는 PGSSLCERTMODE가 있으며, 이는 sslcertmode 연결 파라미터와 같은 역할을 합니다. 인증서와 키 경로는 각각 PGSSLCERT, PGSSLKEY로 지정할 수 있습니다.

PGSSLCERTMODE=disable
PGSSLCERT=client.crt
PGSSLKEY=client.key

다만 환경변수는 실행 환경에 숨어 보이기 쉽습니다. 애플리케이션별 정책을 분명히 남겨야 한다면 연결 문자열이나 서비스 파일에 명시하는 방식이 더 추적하기 쉬울 수 있습니다.

선택 기준

  • 클라이언트 인증서를 쓰지 않는 서비스라면 sslcertmode=disable로 의도를 명확히 할 수 있다.
  • 기본 libpq 동작을 유지하면 충분한 환경에서는 allow가 기본값이라는 점을 문서화한다.
  • 서버가 실제로 인증서 요청을 하는지 확인해야 하는 TLS 문제 분석에는 require를 검토한다.
  • 서버 인증서 검증 수준은 sslcertmode가 아니라 sslmode에서 결정한다.
  • 클라이언트 인증서 인증을 접근 제어로 쓰려면 서버 쪽 인증서 검증과 사용자 매핑까지 함께 확인한다.

자주 묻는 질문

sslcertmode=require만 쓰면 클라이언트 인증서 인증이 안전해지나

아닙니다. 이 값은 서버가 인증서를 요청하는 흐름을 기대하는 옵션입니다. 서버가 인증서를 올바르게 검증하는지까지 보장하지는 않습니다.

sslmode=verify-fullsslcertmode=require는 같은가

같지 않습니다. verify-full은 클라이언트가 서버 인증서와 호스트 이름을 검증하는 설정이고, sslcertmode=require는 서버가 클라이언트 인증서를 요청해야 한다는 조건입니다.

인증서 파일이 있으면 항상 서버로 전송되나

항상 전송되는 것은 아닙니다. SSL 연결이 만들어지고 서버가 클라이언트 인증서를 요청해야 전송 흐름이 생깁니다. sslcertmode=disable이면 사용 가능한 인증서가 있어도 보내지 않습니다.

정리

sslcertmode는 PostgreSQL libpq에서 클라이언트 인증서 전송 조건을 드러내는 옵션입니다. 기본값 allow는 서버가 요청하고 인증서가 있으면 보낼 수 있게 하며, disable은 전송을 막고, require는 서버의 인증서 요청 흐름을 요구합니다.

실무에서는 이 옵션을 서버 인증서 검증 설정으로 착각하지 않는 것이 중요합니다. 서버를 검증하는 축은 sslmode, 클라이언트 인증서 전송 축은 sslcertmode로 나누어 보고, 인증서 파일과 키 권한까지 함께 관리하는 것이 안전합니다.

반응형
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사