지난번 생성한 프리티어 서버에 PostgreSQL 서버를 구축해보자.
서버 접속
우리는 생성한 서버에서 ssh를 설정하여 해당 값에 맞는 private key 파일이 있어야 서버에 접근이 가능하다.
터미널에서 ssh 명령어를 통해 접속하는 방식으로 사용할 것이기에 putteygen을 통해 ppk 파일을 pem 형식의 파일로 변환 시켰다.
이렇게 까지 진행 했으면 이젠 접속을 할 때,
$ ssh -i {#키파일명}.pem {#계정명}@{#IP} -p {#PORT}
해당 방식으로 접속하면 된다.
서버 설치
접속까지 완료 했으면 이제 PostgreSQL을 설치 해보자.
PostgrSQL 공식 사이트 - 설치 가이드
해당 페이지를 들어가 보면 yum 명령어를 사용한 설치 가이드가 있다.
위 이미지 처럼
- PostgreSQL 버전 선택
- 플랫폼 선택
- 아키텍쳐 선택을 하면
자동으로 설치 스크립트가 생긴다. 해당 스크립트를 하나씩 천천히 복사 - 실행을 해주면
쭈루루루룩 설치가 되며 마지막에 yum list installed *postgres*
를 입력해주면 현재 설치된 PostgreSQL 패키지가 나온다.
그리고 설치 스크립트 아래에 이런 패키지가 중요하다고 설명을 해준다.
The repository contains many different packages including third party addons.
The most common and important packages are (substitute the version number as required):
패키지 | 설명 |
postgresql-client | 라이브러리 및 클라이언트 바이너리 |
postgresql-server | 코어 데이터베이스 서버 |
postgresql-contrib | 추가 제공 모듈 |
postgresql-devel | C 언어 개발을 위한 라이브러리 헤더 |
중요한 패키지라고 하는데 우선은 나중에 설치하고… 아래 명령어를 입력해 주면?
$ su - postgres
postgres
계정으로 접속이 된다. 여기 까지되면 정상적으로 설치까진 성공이다.
접속 환경 설정
이제 해당 DB서버를 외부에서도 접속하기 위해 설정을 변경해 줘야한다. psql 버전이 13이니까 경로에 13
폴더가 더 추가 된 것 같다.
$ vi /var/lib/pgsql/13/data/pg_hba.conf
pg_hba.conf 파일부터 수정을 해야하는데 우선 인증방식의 종류부터 간단하게 확인해보고 작업을 설계해보자 여러가지 방식이 있지만 우선 설정파일에 기본적으로 설정되어있는
METHOD들만 정리하였다. 다른 방식들은 아래의 공식 문서를 참조해서 더 알아볼 수 있다.
PostgreSQL 공식 문서 - 인증 방식 참조
인증방식 | 설명 |
peer | 피어(peer) 인증 방법은 클라이언트의 운영 체제 사용자 이름을 커널로부터 획득하고, 허용된 데이터베이스 사용자 이름으로 사용함으로써 작동된다 (선택적 사용자 이름 매핑 사용 ex: all, postgres 등으로 사용자 매핑 ) 이 방법은 로컬 연결에만 지원된다. |
md5 | 암호 스니핑을 방지하고 일반 텍스트로 서버에 암호를 저장하는 것을 방지(암호화)하지만 공격자가 서버에서 암호 해시를 훔치는 경우 보호 기능을 제공하지 않는다. 또한 MD5 해시 알고리즘은 이제 더 이상 결정된 공격에 대해 안전한 것으로 간주되지 않는다. |
scram-sha-256 | 신뢰할 수없는 연결에서 암호 스니핑을 방지하고 안전한 것으로 간주되는 암호화 해시 된 형식으로 서버에 암호를 저장하는 것을 지원하는 시도 응답 체계다. 이것은 현재 제공되는 방법 중 가장 안전하지만 이전 클라이언트 라이브러리에서는 지원되지 않는다. |
정리한 것 처럼 현재 가장 안전한 scram-sha-256
방식을 사용한다. 해당 인증 방식은 PostgreSQL 버전 10부터 사용 가능하다.
1. pg_hba.conf
가장 아래쪽을 보면 인증방식 세팅 부분이 있다. 우선 로컬에서도 다른 계정으로도 psql
명렁어로 접속할 수 있게 peer 로 되어있던 부분을 scram-sha_256으로 세팅한다.
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all scram-sha-256 # peer에서 변경
# IPv4 local connections:
#host all all 127.0.0.1/32 scram-sha-256
host all all 0.0.0.0/0 scram-sha-256
# IPv6 local connections:
host all all ::1/128 scram-sha-256
# Allow replication connections from localhost, by a user with the
# replication privilege. 미사용 설정 주석 처리
#local replication all peer
#host replication all 127.0.0.1/32 scram-sha-256
#host replication all ::1/128 scram-sha-256
2. 이후에 postgresql.conf 에서 listen_address 주소값을 변경해 줘야 한다.
vi /var/lib/pgsql/13/data/postgresql.conf
들어가 보면 해당 설정값이 있는데 기존에는 IP adress 값이 있지만 난 모든것을 허용할 것이기에 ‘*‘ 로 변경해준다.
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - Connection Settings -
listen_addresses = '*' # what IP address(es) to listen on;
3. 여기 까지 설정이 완료되었으면 PostgreSQL을 재시작 한번 해준다. 정상적으로 재시작 되었는지 확인하려면 status 명령어로 확인해본다. 정상이라면 Active 에 러닝 타임이 재시작 시간을 찍힌 것을 확인할 수 있을 것이다.
$ systemctl restart postgresql-13
$ systemctl status postgresql-13
postgresql-13.service - PostgreSQL 13 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2021-07-07 04:25:19 GMT; 8s ago
Docs: https://www.postgresql.org/docs/13/static/
Process: 119391 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
Main PID: 119396 (postmaster)
Tasks: 8 (limit: 4563)
Memory: 18.0M
CGroup: /system.slice/postgresql-13.service
├─119396 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
├─119399 postgres: logger
├─119401 postgres: checkpointer
├─119402 postgres: background writer
├─119403 postgres: walwriter
├─119404 postgres: autovacuum launcher
├─119405 postgres: stats collector
└─119406 postgres: logical replication launcher
와 이제 그럼 외부에서 접속이 가능한건가 하고 해봤지만 안된다. connection timeout이 된다. 방화벽 문제였던 것이다.
방화벽 설정
1. 우선 # firewall-cmd --list-all
명렁어를 통해 현재 방화벽 설정 상태를 조회 할 수 있다. 아래는 가장 기본 상태이다.
$ firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: ens3
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
2. 방화벽 오픈할 포트를 추가 해 주자. postgresql은 5432 포트니까 5432를 열어주면 된다.
$ firewall-cmd --permanent --add-port=5432/tcp
3. 추가한 이후에는 반드시 reload 처리를 해줘야 적용이 되니 reload를 시켜준다.
$ firewall-cmd --reload
4. 그리고 다시 방화벽 상태를 조회해 보면 5432포트가 추가가 된 것을 확인 할 수 있다.
만약 잘못 추가 되었다면 firewall-cmd --zone=public --permanent --remove-port=5432/tcp
의 형식으로 PORT값을 맞춰 제거 하고 다시 reload 해준다.
$ firewall-cmd --list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client ssh
ports: 5432/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
5. 이젠 패킷에 대한 동작을 설정하기 위해 iptables
를 설정해야 한다.
iptables : 패킷에 대한 동작을 등록된 순서로 부터 검사하고, 그 규칙과 일치하는 패킷에 대하여 ACCEPT, REJECT, DROP 등의 동작을 한다.
그래서 처음 iptables --list
로 구성된 설정을 조회해 보면 아래와 같이 설정되어 있다.
$ iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
BareMetalInstanceServices all -- anywhere 169.254.0.0/16
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
Chain BareMetalInstanceServices (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere 169.254.0.2 owner UID match root tcp dpt:iscsi-target /* See the Oracle-Provided Images section in the Oracle Bare ...
여기서 내가 허용할 port를 설정하자. 옵션을 줄때는 이렇게 주었다.
- -I INPUT : 신규규칙으로 INPUT에 넣겠다.
- -p tcp : 패킷의 프로토콜은 tcp로 한다
- –dport 5432 : 포트는 5432로 설정한다.
- -j ACCEPT : 이 패킷을 어떻게 처리할 것인가 설정한다. 나는 INPUT 규칙으로 프로토콜은 TCP로 PORT는 5432로 패킷을 허용한다.
$ iptables -I INPUT -p tcp --dport 5432 -j ACCEPT
여기서 주의 할 점은 현재 설정된 list를 보면 가장 아래에 REJECT 처리로 reject-with icmp-host-prohibited 가 있다. 해당 처리 아래로 새로운 규칙을 추가하면 옵션을 추가하더라도 패킷에 대한 처리를 진행하지 않는다.
그리고 패킷 규칙을 잘못 설정 하였다면 iptables -D INPUT -p tcp --dport 5432 -j ACCEPT
의 형식으로 PORT값을 확인해서 제거 해주면 된다.
6. 그럼 이제 준비가 끝났다 외부에서 되는지 확인을 해보자 우선 간단한 테이블과 데이터를 넣는다.
CREATE TABLE member (
id bigserial null PRIMARY KEY,
name varchar(50) NULL,
phone varchar(30) NULL
);
COMMENT ON COLUMN member.id IS 'member_ID';
COMMENT ON COLUMN member.name IS '이름';
COMMENT ON COLUMN member.phone IS '전화번호';
INSERT INTO member VALUES (NEXTVAL('member_id_seq'), '테스터', '010-1234-1234');
7. 내부적으로 테스트 파일을 만들어 테스트 해본다
1 |
|
성공이다.
나만의 DB 서버까지 구축을 마무리 하였다. 앞으로 써먹을 일이 많을 것 같다.
작성자, DevInSpace