2026년 06월 26일 | DBMS Error 가이드
이 글에서 다루는 내용
28000 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
28000 invalid authorization specification 는?
PostgreSQL 에러 코드 28000(invalid_authorization_specification)은 클라이언트가 데이터베이스에 접속을 시도할 때 인증 자격 증명이 올바르지 않거나 인증 방식 자체에 문제가 있을 때 발생합니다. 단순한 비밀번호 오류(에러 코드 28P01)와는 달리, 이 에러는 사용자 존재 여부, 접속 허용 여부, pg_hba.conf 설정 불일치 등 다양한 인증 구성 문제를 포괄합니다. 주로 애플리케이션 배포 초기, 서버 마이그레이션 후, 또는 보안 정책 변경 직후에 빈번하게 나타납니다.
주요 발생 원인
1. pg_hba.conf 설정 오류 또는 누락
pg_hba.conf(Host-Based Authentication) 파일은 PostgreSQL에서 누가, 어디서, 어떤 방법으로 접속할 수 있는지를 정의하는 핵심 설정 파일입니다. 이 파일에 클라이언트의 IP 주소, 사용자, 데이터베이스에 해당하는 규칙이 존재하지 않거나 잘못 구성된 경우, PostgreSQL은 해당 접속 시도를 거부하며 28000 에러를 반환합니다. 특히 원격 접속 허용 규칙 없이 외부에서 접속을 시도하거나, md5 대신 peer 인증 방식이 잘못 적용된 경우가 대표적입니다.
2. 존재하지 않는 사용자(Role)로 접속 시도
PostgreSQL에서 데이터베이스 사용자는 내부적으로 “Role”로 관리됩니다. 지정한 사용자 이름이 PostgreSQL 클러스터에 실제로 존재하지 않을 경우, 시스템은 인증 자체를 진행할 수 없어 28000 에러가 발생합니다. 이는 오타, 대소문자 불일치, 또는 해당 사용자가 아직 생성되지 않은 경우에 자주 발생하며, 특히 여러 환경(개발/스테이징/운영)을 다루는 팀에서 흔히 겪는 문제입니다.
3. SSL/TLS 인증 설정 불일치
pg_hba.conf에서 특정 접속에 대해 hostssl 방식을 요구하도록 설정했는데, 클라이언트가 SSL 없이 접속을 시도하거나, 반대로 클라이언트가 SSL을 강제하는데 서버에서 SSL이 비활성화되어 있는 경우에도 28000 에러가 발생할 수 있습니다. 인증서 기반 인증(cert)을 사용할 때 클라이언트 인증서가 유효하지 않거나 서버의 CA와 매칭되지 않아도 동일한 에러가 반환됩니다.
해결 방법
원인 1 해결: pg_hba.conf 점검 및 수정
먼저 현재 적용된 pg_hba.conf 내용을 확인합니다.
-- PostgreSQL 내부에서 pg_hba.conf 위치 확인
SHOW hba_file;
-- 현재 적용된 pg_hba 규칙 조회 (PostgreSQL 10 이상)
SELECT type, database, user_name, address, auth_method
FROM pg_hba_file_rules;
pg_hba.conf 파일에 적절한 규칙을 추가합니다. 예를 들어, 특정 IP 대역에서 myuser가 mydb에 md5 방식으로 접속하도록 허용하려면 아래와 같이 설정합니다.
# TYPE DATABASE USER ADDRESS METHOD
host mydb myuser 192.168.1.0/24 md5
host mydb myuser 0.0.0.0/0 scram-sha-256
설정 변경 후 반드시 PostgreSQL에 재로드를 적용합니다.
-- 설정 재로드 (서비스 재시작 없이 적용)
SELECT pg_reload_conf();
또는 OS 레벨에서 아래 명령어를 사용합니다.
# Linux systemd 환경
sudo systemctl reload postgresql
# 또는 pg_ctl 사용
pg_ctl reload -D /var/lib/postgresql/data
원인 2 해결: 사용자(Role) 존재 여부 확인 및 생성
-- 현재 존재하는 모든 Role 목록 조회
SELECT rolname, rolcanlogin, rolsuper, rolcreatedb
FROM pg_roles
ORDER BY rolname;
-- 특정 사용자 존재 여부 확인
SELECT EXISTS (
SELECT 1 FROM pg_roles WHERE rolname = 'myuser'
) AS user_exists;
-- 사용자가 없다면 생성
CREATE ROLE myuser WITH LOGIN PASSWORD 'SecureP@ssword!2024';
-- 특정 데이터베이스에 대한 접속 권한 부여
GRANT CONNECT ON DATABASE mydb TO myuser;
-- 스키마 사용 권한 부여
GRANT USAGE ON SCHEMA public TO myuser;
-- 필요한 테이블 권한 부여
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO myuser;
이미 사용자가 존재하지만 로그인이 비활성화된 경우:
-- 로그인 권한 확인
SELECT rolname, rolcanlogin FROM pg_roles WHERE rolname = 'myuser';
-- 로그인 권한 활성화
ALTER ROLE myuser LOGIN;
-- 비밀번호 재설정 (만료된 경우)
ALTER ROLE myuser PASSWORD 'NewSecureP@ssword!2024' VALID UNTIL 'infinity';
원인 3 해결: SSL 설정 점검
-- 서버의 SSL 활성화 여부 확인
SHOW ssl;
-- SSL 관련 설정 전체 확인
SELECT name, setting
FROM pg_settings
WHERE name LIKE 'ssl%';
pg_hba.conf에서 SSL 요구 방식을 클라이언트 환경에 맞게 조정합니다.
# SSL 연결만 허용 (클라이언트가 SSL을 지원할 때)
hostssl mydb myuser 0.0.0.0/0 scram-sha-256
# SSL 비연결만 허용
hostnossl mydb myuser 127.0.0.1/32 md5
# SSL 여부 무관하게 허용 (개발 환경 등)
host mydb myuser 0.0.0.0/0 scram-sha-256
클라이언트 접속 시 SSL 옵션을 명시적으로 지정하는 방법:
# SSL 비활성화로 접속 테스트
psql "host=myserver dbname=mydb user=myuser sslmode=disable"
# SSL 필수로 접속 테스트
psql "host=myserver dbname=mydb user=myuser sslmode=require"
# SSL 선호(가능하면 사용) 모드
psql "host=myserver dbname=mydb user=myuser sslmode=prefer"
예방 방법
1. pg_hba.conf 변경 관리 및 검증 자동화
pg_hba.conf는 운영 환경에서 가장 중요한 보안 파일 중 하나이므로, Git 등 버전 관리 시스템으로 모든 변경 이력을 추적해야 합니다. 또한 변경 사항을 적용하기 전에 pg_hba_file_rules 뷰를 활용한 사전 검증 스크립트를 CI/CD 파이프라인에 포함시켜, 잘못된 설정이 운영 환경에 반영되는 것을 원천 차단하는 것이 Best Practice입니다.
-- pg_hba.conf 적용 후 규칙 검증 쿼리 예시
SELECT
line_number,
type,
database,
user_name,
address,
netmask,
auth_method,
options,
error
FROM pg_hba_file_rules
WHERE error IS NOT NULL; -- 에러가 있는 규칙만 필터링
2. 사용자 및 권한 생성 표준화 (IaC 적용)
데이터베이스 사용자 생성과 권한 부여를 Terraform, Ansible, 또는 사내 표준 SQL 스크립트로 코드화하여 환경 간 일관성을 유지해야 합니다. 수동으로 사용자를 생성하다 보면 환경별 불일치가 발생하여 28000 에러를 비롯한 다양한 인증 문제가 생기므로, 모든 Role 관리는 자동화된 프로세스를 통해 수행하고 주기적으로 pg_roles를 감사(Audit)하는 것이 좋습니다.
관련 에러
- 28P01 (
invalid_password): 사용자는 존재하고 접속 조건도 충족되지만, 비밀번호 자체가 틀렸을 때 발생합니다. 28000보다 더 구체적인 인증 실패 에러입니다. - 42501 (
insufficient_privilege): 인증에는 성공했지만 해당 데이터베이스 객체에 대한 권한이 없을 때 발생합니다. 28000과 혼동하기 쉬우나 발생 시점이 다릅니다. - 08001 (
sqlclient_unable_to_establish_sqlconnection): 네트워크 수준에서 서버에 아예 접근하지 못하는 경우로, 방화벽 또는listen_addresses설정과 관련이 있습니다. - 3D000 (
invalid_catalog_name): 접속하려는 데이터베이스 자체가 존재하지 않을 때 발생하며, 28000과 함께 접속 초기 단계에서 자주 동반 발생합니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.