PostgreSQL 28000 오류 원인과 해결 방법 완벽 가이드

28000
2026년 08월 30일 | DBMS Error 가이드

이 글에서 다루는 내용

28000 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

28000 invalid authorization specification 는?

PostgreSQL 에러 코드 28000 (invalid_authorization_specification) 은 클라이언트가 데이터베이스 서버에 접속을 시도할 때 인증 자격 증명(Authorization Specification)이 유효하지 않거나 허용되지 않은 경우 발생하는 에러입니다. 단순히 비밀번호가 틀린 경우(에러 코드 28P01)와는 구별되며, 인증 방식 자체가 맞지 않거나 접속 규칙이 거부한 경우에 주로 발생합니다. 예를 들어 pg_hba.conf 설정이 해당 클라이언트의 접속 요청을 허용하지 않거나, 존재하지 않는 사용자로 접속을 시도하거나, 인증 방식(md5, scram, trust, peer 등)이 서버 기대값과 일치하지 않을 때 이 에러가 트리거됩니다.


주요 발생 원인

1. pg_hba.conf 설정 불일치 또는 누락

pg_hba.conf(Host-Based Authentication 설정 파일)는 PostgreSQL에서 “누가, 어디서, 어떤 방법으로” 접속할 수 있는지를 정의하는 핵심 파일입니다. 클라이언트의 IP 주소, 데이터베이스 이름, 사용자 이름, 인증 방식 중 하나라도 파일에 정의된 규칙과 일치하지 않으면 서버는 즉시 연결을 거부하고 28000 에러를 반환합니다. 특히 신규 서버 구성 후 원격 접속 허용 설정을 빠뜨리거나, 새로운 사용자/데이터베이스 추가 후 해당 항목을 pg_hba.conf에 등록하지 않은 경우 자주 발생합니다.

2. 존재하지 않는 사용자 또는 데이터베이스로 접속 시도

PostgreSQL은 접속 요청 시 지정된 사용자(Role)와 데이터베이스가 실제로 존재하는지 확인합니다. 존재하지 않는 Role 이름이나 데이터베이스 이름으로 접속을 시도하면, 인증 단계에서 실패하여 28000 에러가 발생할 수 있습니다. 개발 환경과 운영 환경 사이에서 사용자명이나 DB명을 혼용하거나, 배포 스크립트에서 Role 생성 단계를 생략했을 때 이 문제가 자주 나타납니다.

3. peer 인증 방식에서 OS 사용자와 DB 사용자 불일치

peer 인증은 리눅스/유닉스 환경에서 OS(운영체제) 사용자 이름과 PostgreSQL 사용자 이름이 동일한지를 비교하여 인증하는 방식입니다. 예를 들어 OS 사용자가 ubuntu인데 psql -U postgres로 접속을 시도하면, peer 인증 규칙에 의해 OS 사용자명(ubuntu)과 DB 사용자명(postgres)이 다르기 때문에 28000 에러가 발생합니다. 로컬 환경에서 처음 PostgreSQL을 설치한 후 postgres 수퍼유저로 접속하려 할 때 이 문제가 매우 빈번하게 발생합니다.


해결 방법

1. pg_hba.conf 수정 및 재로드

현재 pg_hba.conf 파일 위치를 확인하고 편집합니다.

-- pg_hba.conf 파일 경로 확인
SHOW hba_file;

파일을 열어 적절한 접속 규칙을 추가합니다. 아래는 외부 IP에서 특정 사용자가 특정 DB에 접속할 수 있도록 허용하는 예시입니다.

# TYPE  DATABASE        USER            ADDRESS                 METHOD
# 로컬 소켓 접속 - peer 인증
local   all             postgres                                peer

# 특정 IP 대역에서 scram-sha-256 인증으로 접속 허용
host    mydb            myuser          192.168.1.0/24          scram-sha-256

# 모든 IP에서 md5 인증으로 접속 허용 (보안상 주의 필요)
host    all             all             0.0.0.0/0               md5

파일 수정 후 PostgreSQL 서비스를 재시작하지 않고 설정을 바로 반영할 수 있습니다.

-- 설정 재로드 (서비스 재시작 불필요)
SELECT pg_reload_conf();

-- 또는 OS 명령어로 재로드
-- sudo systemctl reload postgresql
-- sudo pg_ctlcluster 15 main reload

2. 존재하지 않는 사용자/데이터베이스 생성

접속하려는 사용자(Role)와 데이터베이스가 실제로 존재하는지 확인하고 없다면 생성합니다.

-- 기존 Role 목록 확인
SELECT rolname, rolcanlogin, rolsuper FROM pg_roles ORDER BY rolname;

-- 기존 데이터베이스 목록 확인
SELECT datname, datdba FROM pg_database;

-- 새 사용자(Role) 생성 (로그인 가능, 비밀번호 설정)
CREATE ROLE myuser WITH LOGIN PASSWORD 'SecureP@ssw0rd!' CREATEDB;

-- 새 데이터베이스 생성 및 소유자 지정
CREATE DATABASE mydb OWNER myuser;

-- 필요한 권한 부여
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;

-- 향후 생성될 테이블에 대한 기본 권한 설정
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO myuser;

3. peer 인증 문제 해결

peer 인증 문제가 발생한 경우, OS 사용자를 전환하거나 인증 방식을 변경합니다.

# 방법 1: OS 사용자를 postgres로 전환 후 접속
sudo -i -u postgres
psql
-- 방법 2: pg_hba.conf에서 peer를 md5 또는 scram-sha-256으로 변경 후
-- 비밀번호를 설정하고 재접속
ALTER ROLE postgres WITH PASSWORD 'NewSecurePassword!';
# pg_hba.conf 수정 예시 (peer → scram-sha-256)
# 수정 전
local   all   postgres   peer

# 수정 후
local   all   postgres   scram-sha-256

예방 방법

1. pg_hba.conf 변경 이력 관리 및 검증 자동화

pg_hba.conf는 PostgreSQL 보안의 1차 방어선입니다. 이 파일을 Git 등 버전 관리 시스템으로 관리하고, 변경 시 반드시 코드 리뷰 프로세스를 거치도록 팀 정책을 수립하세요. 또한 새로운 사용자나 데이터베이스를 추가하는 배포 스크립트에 pg_hba.conf 업데이트 단계를 반드시 포함시키고, 배포 후 접속 테스트를 자동화하는 스크립트를 운영하면 사전에 문제를 예방할 수 있습니다.

-- 현재 pg_hba.conf 설정 내용 확인 (PostgreSQL 10+)
SELECT type, database, user_name, address, auth_method
FROM pg_hba_file_rules
ORDER BY line_number;

2. 최소 권한 원칙(Least Privilege)에 따른 Role 설계

애플리케이션마다 전용 Role을 생성하고, 해당 Role에는 필요한 최소한의 권한만 부여하는 원칙을 항상 지키세요. 수퍼유저(postgres)를 애플리케이션 접속 계정으로 절대 사용하지 않으며, 환경별(개발/스테이징/운영)로 별도의 Role과 비밀번호를 관리하면 인증 오류와 보안 사고를 동시에 예방할 수 있습니다.

-- 애플리케이션 전용 Role 생성 예시 (수퍼유저 권한 없음)
CREATE ROLE app_readonly WITH LOGIN PASSWORD 'ReadOnlyPass!';
CREATE ROLE app_readwrite WITH LOGIN PASSWORD 'ReadWritePass!';

-- 읽기 전용 권한 부여
GRANT CONNECT ON DATABASE mydb TO app_readonly;
GRANT USAGE ON SCHEMA public TO app_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;

-- 읽기/쓰기 권한 부여
GRANT CONNECT ON DATABASE mydb TO app_readwrite;
GRANT USAGE ON SCHEMA public TO app_readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_readwrite;

관련 에러

  • 28P01 (invalid_password): 사용자는 존재하지만 비밀번호가 틀린 경우 발생하는 에러로, 28000과 혼동되기 쉽습니다. 28000은 인증 방식/규칙 자체의 문제이고, 28P01은 순수하게 비밀번호 불일치입니다.
  • 3D000 (invalid_catalog_name): 접속하려는 데이터베이스 자체가 존재하지 않을 때 발생하며, 28000과 함께 나타나는 경우가 있습니다.
  • 42501 (insufficient_privilege): 접속은 성공했지만 특정 객체에 대한 권한이 없을 때 발생하는 에러로, 권한 설계가 잘못된 경우 28000 해결 후 연이어 마주칠 수 있습니다.
  • 08001 (sqlclient_unable_to_establish_sqlconnection): 네트워크 레벨에서 연결 자체가 실패한 경우로, pg_hba.conf 수정 전에 네트워크/방화벽 문제와 구분이 필요합니다.
DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기