이전글
이전 글에서 PostgreSQL을 사용하는데에 있어서 필요한 설정 중, 데이터베이스 서버측 설정을 진행했었다.
따라서 이번 글에서는 데이터베이스 서버 측이 아닌 서버에 접속하는 클라이언트 관련 설정들 중 인증(authentication)에 관한 설정을 진행한다.
일반적으로 이 작업은 외부에서 특정 애플리케이션을 사용해 PostgreSQL 서버에 접속하기 위해 처음 접하게 될 것이다.
(나 또한 그렇고)
예) DBeaver로 접속, pgAdmin/Web으로 접속 등
Client Authentication
이번 글에서는 ph_hba.conf 라는 파일 하나에 대해서만 다루게 되므로 아래 공식 문서 전체를 '가볍게' 읽어보는게 나쁘지 않을 것이다.
https://www.postgresql.org/docs/14/client-authentication.html
클라이언트 애플리케이션이 데이터베이스 서버에 연결할 때, 어떤 사용자 이름(username)으로 연결할 것인지를 지정하게 된다.
이는 Unix 기반의 컴퓨터에 특정 사용자로 로그인 하는 것과 매우 유사한 방식이다.
SQL 환경 내에서 사용중인 데이터베이스 사용자 이름은 데이터베이스 개체에 대한 액세스 권한을 결정한다.
자세한 정보는 22장을 참조할 것.
따라서 어떤 데이터베이스 사용자가 연결할 수 있는지를 제한하는 것이 매우 중요하다.
Note
22장에서 설명한 바와 같이, PostgreSQL은 실제로 "role"의 관점에서 권한을 관리한다. 해당 챕터에서는 사용자가 "LOGIN 권한이 있는 role"이라는 의미로 일관되게 사용한다.
인증(authentication)은 데이터베이스 서버가 클라이언트의 신원(ID: Identity)을 확인하고 이를 통해 클라이언트 애플리케이션(또는 클라이언트 애플리케이션을 실행하는 사용자)이 요청한 데이터베이스 사용자 이름으로 연결할 수 있는지의 여부를 결정하는 프로세스다.
PostgreSQL은 다양한 클라이언트 인증 방법을 제공한다.
특정 클라이언트 연결을 인증하는 방법은 (클라이언트의)호스트 주소, 데이터베이스, 사용자를 기준으로 선택 가능하다.
PostgreSQL 데이터베이스 사용자 이름은 서버가 실행되는 운영 체제의 사용자 이름과 논리적으로 분리되어 있다.
특정 서버의 모든 사용자가 서버의 기기에 계정을 가지고 있다면, 운영 체제 사용자 이름과 일치하는 데이터베이스 사용자 이름을 할당하는 것이 이치에 맞다.
하지만 원격 연결을 수락하는 서버는 로컬 운영 체제 계정이 없는 많은 데이터베이스 사용자를 가질 수 있다.
이러한 경우에는 데이터베이스 사용자 이름과 운영 체제 사용자 이름 사이에 연결성이 없어도 된다.
즉, 서버 OS의 username과 PostgreSQL DB의 username 이름을 일치시킬지 말지는 사용 환경 및 운영 환경에 따라 사용자가 직접 판단해야 한다.
pg_hba.conf
https://www.postgresql.org/docs/14/auth-pg-hba-conf.html
클라이언트 인증(= 호스트 기반 인증)은 전통적으로 pg_hba.conf라는 이름의 설정 파일에 의해 제어되며 해당 파일은 데이터베이스 클러스터의 데이터 디렉터리에 저장된다.
이 설정 파일은 누가 데이터베이스에 접속할 수 있는지, 어떤 IP 주소에서 접근이 허용되는지, 어떤 인증 방법이 사용되어야 하는지 등을 설정하는데 사용된다.
- HBA(Host-based Authentication) : 호스트 기반 인증
- 경로 : 일반적으로 /etc/postgresql/$VERSION/main에 위치
해당 파일은 다른 경로에 배치할 수도 있으며 데이터 디렉터리가 initdb에 의해 초기화될 때 설치된다.
Record Format
pg_hba.conf 파일에는 여러 행이 있으며, 각 행은 하나의 인증 설정 정보를 기록하고 있다.
각 행은 다음과 같은 포맷을 갖는다.
연결유형 데이터베이스 사용자 주소 인증 방법
local database user auth-method [auth-options]
host database user address auth-method [auth-options]
hostssl database user address auth-method [auth-options]
hostnossl database user address auth-method [auth-options]
hostgssenc database user address auth-method [auth-options]
hostnogssenc database user address auth-method [auth-options]
host database user IP-address IP-mask auth-method [auth-options]
hostssl database user IP-address IP-mask auth-method [auth-options]
hostnossl database user IP-address IP-mask auth-method [auth-options]
hostgssenc database user IP-address IP-mask auth-method [auth-options]
hostnogssenc database user IP-address IP-mask auth-method [auth-options]
- TYPE (연결 유형)
- local : Unix 도메인 소켓을 통한 연결을 의미.
- host : TCP/IP를 통한 연결을 의미.
- DATABASE (데이터베이스)
- 접근 권한이 부여되는 데이터베이스를 지정.
- 여러 데이터베이스를 콤마(,)로 구분하여 나열하거나 all을 사용해 모든 데이터베이스를 지정할 수 있음.
- USER (사용자)
- 접근 권한이 부여되는 사용자를 지정.
- 여러 사용자를 콤마(,)로 구분하여 나열하거나 all을 사용해 모든 사용자를 지정할 수 있음.
- ADDRESS (주소)
- CIDR(Class Inter-Domain Routing) 표기법을 사용해 클라이언트의 IP 주소를 지정.
- Unix 도메인 소켓을 통한 연결의 경우(=local), 해당 필드를 비워 놓음.
- METHOD (인증 방법)
- 사용할 인증 방법을 지정.
- trust : 클라이언트를 비밀번호 또는 기타 인증 수단 없이 무조건 신뢰. 보안상 문제가 될 수 있으며, 로컬 개발 환경에서만 사용할 것.
- peer : 운영 체제의 인증 메커니즘을 사용. Unix 도메인 소켓을 통한 로컬 연결에 대해서만 사용 가능함.
- scram-sha-256 : SCRAM(Salted Challenge Response Authentication Mechanism)을 사용. SCRAM은 비밀번호를 안전하게 저장, 인증하는 방법을 제공하며 SHA-256 해시 함수를 사용함. 이는 비밀번호의 안정성을 크게 향상시키며 중간자 공격을 방지할 수 있음.
Allow External Connection
일반적으로 PostgreSQL 서버는 처음 설치될 때 로컬로부터의 접속은 모두 허용하게끔 설정되어 있다.
따라서 pg_hba.conf 파일에 다음과 같은 행이 존재하면 된다.
# 1. 모든 외부 연결을 허용
host all all 0.0.0.0/0 scram-sha-256
# 2. 특정 IP 주소 대역의 연결을 허용
host all all 172.17.0.0/16 scram-sha-256
IP 주소와 인증 방법은 자신의 환경에 맞게 설정하면 된다.
(만약 테스트 목적이라면 0.0.0.0/0에 trust로 설정해도 무방하다)
Etc.
딱히 분류를 하기 어려워 알고 있으면 좋을, 혹은 알고 있어야 하는 내용을 적어 놓는다.
postgresql.conf
외부 연결을 허용하려면 이전 글에서 다룬 postgresql.conf 파일의 listen_address가 *로 설정되어 있어야 한다.
즉, postgresql.conf와 pg_hba.conf 파일 모두가 준비되어야 한다.
만약 PostgreSQL 서버가 설치된 PC(서버 컴퓨터)의 앞단에 라우터나 방화벽 같은 네트워크 장비가 존재한다면, DMZ나 포트포워딩 된 내용도 알고 있어야 할 것이다.
Apply the rules on pg_hba.conf
pg_hba.conf 파일을 수정하였다면 파일을 저장한 후 어떻게 해야 해당 내용이 PostgreSQL 서버에 반영될까?
postgresql.conf의 경우 수정한 항목에 따라 postgresql을 재기동(restart)해야하는 항목이 존재했지만, pg_hba.conf의 경우 reload 명령어를 사용해 서버가 설정 파일을 다시 읽어들이게만 하면 된다.
# Ubuntu Linux : PostgreSQL Reload
sudo systemctl reload postgresql
The pg_hba.conf file is read on start-up and when the main server process receives a SIGHUP signal.
If you edit the file on an active system, you will need to signal the postmaster (using pg_ctl reload, calling the SQL function pg_reload_conf(), or using kill -HUP) to make it re-read the file.
Priority of records
각 클라이언트 연결 시도에 대해 pg_hba.conf 파일에 명시된 레코드를 순차적으로 검사한다.
즉, 같은 레벨에 대한 설정이더라도 위에 명시된 레코드가 먼저 적용되는 우선 순위가 존재한다.
Connect and Control Access to Particular Database
사용자가 특정 데이터베이스에 연결하려면 pg_hba.conf 검사만 통과할 것이 아니라, 그 데이터베이스에 대한 CONNECT 권한이 있는지도 확인해야 한다.
데이터베이스에 연결 가능한 사용자를 제한하고 싶으면 pg_hba.conf 항목에 rule을 입력하는 것 보다 CONNECT 권한을 부여(grant) 또는 취소(revoke)하는 것이 일반적으로 더 쉽다.
Example of pg_hba.conf
다음은 공식 문서에 존재하는 pg_hba.conf 파일의 예시다.
# Allow any user on the local system to connect to any database with
# any database user name using Unix-domain sockets (the default for local
# connections).
#
# TYPE DATABASE USER ADDRESS METHOD
local all all trust
# The same using local loopback TCP/IP connections.
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 trust
# The same as the previous line, but using a separate netmask column
#
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
host all all 127.0.0.1 255.255.255.255 trust
# The same over IPv6.
#
# TYPE DATABASE USER ADDRESS METHOD
host all all ::1/128 trust
# The same using a host name (would typically cover both IPv4 and IPv6).
#
# TYPE DATABASE USER ADDRESS METHOD
host all all localhost trust
# Allow any user from any host with IP address 192.168.93.x to connect
# to database "postgres" as the same user name that ident reports for
# the connection (typically the operating system user name).
#
# TYPE DATABASE USER ADDRESS METHOD
host postgres all 192.168.93.0/24 ident
# Allow any user from host 192.168.12.10 to connect to database
# "postgres" if the user's password is correctly supplied.
#
# TYPE DATABASE USER ADDRESS METHOD
host postgres all 192.168.12.10/32 scram-sha-256
# Allow any user from hosts in the example.com domain to connect to
# any database if the user's password is correctly supplied.
#
# Require SCRAM authentication for most users, but make an exception
# for user 'mike', who uses an older client that doesn't support SCRAM
# authentication.
#
# TYPE DATABASE USER ADDRESS METHOD
host all mike .example.com md5
host all all .example.com scram-sha-256
# In the absence of preceding "host" lines, these three lines will
# reject all connections from 192.168.54.1 (since that entry will be
# matched first), but allow GSSAPI-encrypted connections from anywhere else
# on the Internet. The zero mask causes no bits of the host IP address to
# be considered, so it matches any host. Unencrypted GSSAPI connections
# (which "fall through" to the third line since "hostgssenc" only matches
# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10.
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 192.168.54.1/32 reject
hostgssenc all all 0.0.0.0/0 gss
host all all 192.168.12.10/32 gss
# Allow users from 192.168.x.x hosts to connect to any database, if
# they pass the ident check. If, for example, ident says the user is
# "bryanh" and he requests to connect as PostgreSQL user "guest1", the
# connection is allowed if there is an entry in pg_ident.conf for map
# "omicron" that says "bryanh" is allowed to connect as "guest1".
#
# TYPE DATABASE USER ADDRESS METHOD
host all all 192.168.0.0/16 ident map=omicron
# If these are the only three lines for local connections, they will
# allow local users to connect only to their own databases (databases
# with the same name as their database user name) except for administrators
# and members of role "support", who can connect to all databases. The file
# $PGDATA/admins contains a list of names of administrators. Passwords
# are required in all cases.
#
# TYPE DATABASE USER ADDRESS METHOD
local sameuser all md5
local all @admins md5
local all +support md5
# The last two lines above can be combined into a single line:
local all @admins,+support md5
# The database column can also use lists and file names:
local db1,db2,@demodbs all md5
이번 포스팅에서는 외부 접속 허용을 위한 클라이언트 인증 규칙을 생성했다.
다음 포스팅에서는 pgAdmin 또는 DBeaver와 같은 클라이언트 애플리케이션을 사용해 외부에서 서버에 접속하는 방법을 간단하게 다룬다.