1. ๊ฐ์ (Incident Overview)
์ด ๊ธ์ Proxmox VE ํ๊ฒฝ์ LXC(Linux Container)์ PostgreSQL์ ์ค์นํ ์งํ, Spring Boot ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ DB๋ฅผ ์ฐ๋ํ๋ ค๋ ๊ณผ์ ์์ ๋ฐ์ํ ์ ์ ๊ฑฐ๋ถ ์ฅ์ ์ ๋ํ ์ฌํ ๋ถ์(Postmortem) ๋ฌธ์์ ๋๋ค.
์ด๊ธฐ ์ค์น๋ฅผ ๋ฌด์ฌํ ๋ง์น๊ณ ์ ์์ ์๋ํ์ ๋, ์๋์ ๊ฐ์ ์น๋ช ์ ์ธ(FATAL) ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉฐ DB ์ฐ๋์ด ์ ๋ฉด ์ฐจ๋จ๋์์ต๋๋ค.
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: Peer authentication failed for user "<DB_USERNAME>"
๋จ์ํ ๋น๋ฐ๋ฒํธ ๋๋ฝ์ธ ์ค ์์๋ ์ด ์๋ฌ๋, PostgreSQL์ ๊ณ ์ ํ โ์ธ์ฆ ๋ฐฉ์(Authentication) ๋ฉ์ปค๋์ฆโ ๊ณผ โ์ ์ ํ๋กํ ์ฝ(Socket vs TCP/IP)โ ์ ๋ํ ์ดํด ๋ถ์กฑ์์ ๋น๋กฏ๋์์ต๋๋ค. ๋ณธ ํ๊ณ ๋ก์ ๋น์์ ๋ฌธ์ ํด๊ฒฐ ํ๋ฆ, ์์ธ ๋ถ์, ๊ทธ๋ฆฌ๊ณ ๋ณด์์ ๊ณ ๋ คํ ์ต์ข ํ์๋ผ์ธ์ ์์ธํ ๊ธฐ๋กํฉ๋๋ค.
2. ํต์ฌ ๋ด์ฉ ๋ฐ ์์ธ ๋ถ์ (Root Cause Analysis)
2-1. โPeer Authenticationโ์ ๊ณต์์ ์ธ ์๋ฏธ
PostgreSQL ๊ณต์ ๋ฌธ์(Chapter 20. Client Authentication)์ ๋ฐ๋ฅด๋ฉด, Peer ์ธ์ฆ์ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ฉ๋๋ค.
โThe peer authentication method works by obtaining the clientโs operating system user name from the kernel and using it as the allowed database user name.โ
Peer ์ธ์ฆ ๋ฐฉ๋ฒ์ ํด๋ผ์ด์ธํธ ์์คํ ์ปค๋๋ก๋ถํฐ ํ์ฌ ๋ก๊ทธ์ธํ OS ์ฌ์ฉ์ ์ด๋ฆ์ ์ป์ด์, ์ด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ฉ์ ์ด๋ฆ์ผ๋ก ํ์ฉํ ์ง ๊ฒ์ฌํ๋ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค.
์ด ์ํฉ์ ๋ณด์์์(์ธ์ฆ ์์คํ
) ์ ๋น์ ํ ์ ์์ต๋๋ค. PostgreSQL์ ๋ณด์ ์ง์นจ์ ์ญํ ์ ํ๋ ๋ฉ์ธ ์ค์ ํ์ผ์ pg_hba.conf ์
๋๋ค.
-
๋์ ์๋: โ๋ณด์์์๋! ์ ํผํผํ ๋น๋ฐ๋ฒํธ ๋ง๋ค์์ด์! ๋ค์ฌ๋ณด๋ด ์ฃผ์ธ์!โ
-
๋ณด์์์ (
pg_hba.conf์ Peer ๋ฃฐ): โ์๋, ์ ํฌ ํด๋ฝ โ๋๋ณด ์ ๋ฌธโ์ ๋น๋ฐ๋ฒํธ๋ ์ ๋ด ๋๋ค. ์ค์ง ์๋ ๊ฐ์ด์ ๋ฌ๋ฆฐ ๋ฆฌ๋ ์ค OS ๋ช ์ฐฐ(ํ์ฌ ๋ก๊ทธ์ธํ ์ปค๋ ๊ณ์ ๋ช ) ์ด<DB_USERNAME>๊ณผ ์ ํํ ์ผ์นํ๋์ง๋ง ๊ฒ์ฌํฉ๋๋ค. ๋ช ์ฐฐ์ด ๋ค๋ฅด๋ฉด ์ ์ฅ ๋ถ๊ฐ์ ๋๋ค.โ
์ฆ, ์ฐ๋ถํฌ์ ๊ธฐ๋ณธ ๋ก๊ทธ์ธ ์ ์ (์: <OS_USERNAME>) ์ํ, ํน์ ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์คํํ๋ ๋ฐ๋ชฌ ์ ์ ์ํ์์ ๋ก์ปฌ ์ ์์ ์๋ํ๋ฉด, ๋ฆฌ๋
์ค ๋ช
์ฐฐ๊ณผ DB ๋ช
์ฐฐ์ด ๋ถ์ผ์นํ๋ฏ๋ก ์ธ์ฆ์ ์ฆ์ ์คํจํ๋ ๊ตฌ์กฐ์์ต๋๋ค.
2-2. ์ฝ์ง์ ๊ธฐ๋ก (What Went Wrong)
์ด ์๋ฆฌ๋ฅผ ์ ํํ ์ธ์งํ์ง ๋ชปํด ๋ฐ์ํ๋ ๋ ๊ฐ์ง ๋ ผ๋ฆฌ์ ์ค๋ฅ์ ๋๋ค.
-
์ค๋ฅ 1: ๋ฌด์์ ๋น๋ฐ๋ฒํธ๋ง ๊ฐ์ ๋ก ๋ถ์ฌํ๊ธฐ
-
โ๋น๋ฐ๋ฒํธ๊ฐ ์์ด์ ํ๊ฒจ๋๊ฒ ์ง?โ๋ผ๊ณ ์คํํ์ฌ ์๋ ๋ช ๋ น์ด๋ก ๊ฐ์ ์ํธํ๋ฅผ ์๋ํ์ต๋๋ค.
-
ALTER USER <DB_USERNAME> with encrypted password '<SECURE_PASSWORD>'; -
๊ฒฐ๊ณผ: ๋ณด์์์์ ์ ์ด์ ์ ๋ฌธ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฒ์ฌํ ๊ถํ(์ค์ )์ด ์์๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ ์ ์ฅ์ด ๊ฑฐ๋ถ๋์์ต๋๋ค.
-
-
์ค๋ฅ 2: ์๋ฑํ ๋ฒ์ ์ ์ค์ ํ์ผ ๋งคํ (
pg_ident.conf)-
OS ์ ์ ์ DB ์ ์ ์ด๋ฆ์ด ๋ค๋ฅด๋ฉด ๋งคํํด์ฃผ๋ฉด ๋๋ค๋ ๋จํธ์ ์ธ ์ง์์ผ๋ก
pg_ident.confํ์ผ์ ์ด์ด<OS_USERNAME> <DB_USERNAME>ํํ์ ์ฅ๋ถ๋ฅผ ์์ฑํ์ต๋๋ค. -
๊ฒฐ๊ณผ: ๋ฉ์ธ ํ์ผ์ธ
pg_hba.conf์map=<MAP_NAME>์ต์ ์ ์ฃผ์ด โ์ด ์ฅ๋ถ๋ฅผ ์ฐธ๊ณ ํด๋ผ!โ๋ผ๊ณ ์ง์ํ์ง ์์ ์คํจํ์ต๋๋ค.
-
3. ์๋ฒฝ ํด๊ฒฐ ๋ฐฉ๋ฒ 3๊ฐ์ง ๋ฐ ๋ณด์์ฑ ํ๊ฐ
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๊ฒํ ํ๋ 3๊ฐ์ง ์ ๊ทผ ๋ฐฉ์๊ณผ ๋ณด์ ๊ด์ ์ ํ๊ฐ์ ๋๋ค.
๋ฐฉ๋ฒ A. ์ธ์ฆ ๋ฐฉ์์ ๋น๋ฐ๋ฒํธ(scram-sha-256)๋ก ์ ๋ฉด ์์ (์ ๊ณต๋ฒ)
๋ณด์์์์ ์ ๋ฌธ ๊ฒ์ฌ ๊ท์น ์์ฒด๋ฅผ โ๋ช ์ฐฐ(OS ์ ์ ๋ช )โ์์ โ๋น๋ฐ๋ฒํธโ๋ก ๋ฐ๊ฟ์ฃผ๋ ์ ์์ ๋๋ค.
/etc/postgresql/<VERSION>/main/pg_hba.conf ํ์ผ์ ์ด์ด local ์ ์ ์ค์ ์ ๋ณ๊ฒฝํฉ๋๋ค.
# ๋ณ๊ฒฝ ์ (์ ๋ฌธ: ๋ช
์ฐฐ ๊ฒ์ฌ)
local all all peer
# ๋ณ๊ฒฝ ํ (์ ๋ฌธ: ์ต์ ์ํธํ ๋น๋ฐ๋ฒํธ ๊ฒ์ฌ)
local all all scram-sha-256
๐ก๏ธ [๋ณด์ ํ๊ฐ]: ์ ๊ทน ๊ถ์ฅ
scram-sha-256์ ํจํท ์ค๋ํ ๋ฐฉ์ด๊ฐ ๊ฐ๋ฅํ ๊ฐ๋ ฅํ ์ฑ๋ฆฐ์ง-๋ฆฌ์คํฐ์ค ๋ฐฉ์์
๋๋ค.
๋ฐฉ๋ฒ B. ๋ก์ปฌ ์์ผ ๋์ TCP/IP ๋คํธ์ํฌ(LXC IP)๋ก ์ ์ํ๊ธฐ (๋์ ์ค์ ํด๊ฒฐ์ฑ )
pg_hba.conf์ ๋ก์ปฌ ์ค์ ์ ๋ฏ์ด๊ณ ์น์ง ์๊ณ , ์ ์ ํ๋กํ ์ฝ ์์ฒด๋ฅผ ๋คํธ์ํฌ(TCP/IP) ๋ฃฐ์ ํ๊ฒ ํ๋ ์ฐํ ๋ฐฉ์์
๋๋ค.
# ๋ฐฑ์๋ ์ค์ (์: application.yml) ์, LXC์ IP๋ฅผ ๋ช
์
spring:
datasource:
url: jdbc:postgresql://<LXC_IP>:5432/<DB_NAME>
username: <DB_USERNAME>
password: <SECURE_PASSWORD>
[์ค์ ํด๊ฒฐ์ ๋น๋ฐ]:
์ฌ์ค ์ ๊ฐ ์ด ์ฅ์ ๋ฅผ ๋ํํ๋ ์ง์ง ๋ฐฉ๋ฒ์ด ๋ฐ๋ก ์ด๊ฒ์ด์์ต๋๋ค. ์ ๋ฌธ(Unix Socket, local)์์ ๋ช
์ฐฐ ๊ฒ์ฌ์ ๊ฑธ๋ ค ๋ฒ๋ฒ์ด ํ๊ฒจ ๋๊ฐ์ง๋ง, ๋ฐฑ์๋ ์ ํ๋ฆฌ์ผ์ด์
(application.yml)์ DB ์ฃผ์๋ก LXC ์ปจํ
์ด๋์ ํ ๋น๋ ์ค์ IP๋ฅผ ๊ธฐ์ฌํ์ต๋๋ค.
LXC IP๋ฅผ ๋ช
์ํ๋ ์๊ฐ, ํต์ ๋ฐฉ์์ด ์์ผ(๋๋ณด)์์ TCP/IP(์ฐจ๋)๋ก ๋ณ๊ฒฝ๋ฉ๋๋ค. ์ฐจ๋ฅผ ํ๊ณ โ์ธ๋ถ ์ฃผ์ฐจ์ฅ ๊ฒ์ดํธ(host ๋ฃฐ)โ๋ก ์ง์
ํ์, DB๊ฐ ์ ์์ ์ผ๋ก โ๋น๋ฐ๋ฒํธ๋ฅผ ๋์์ค(md5 ๋๋ scram-sha-256)โ๋ผ๊ณ ์๊ตฌํ๊ณ , ๋ฏธ๋ฆฌ ์ธํ
ํด ๋ ํผํผํ ๋น๋ฐ๋ฒํธ๊ฐ ์๋ํ์ฌ ์ฐ๋์ ์ฑ๊ณตํ ๊ฒ์
๋๋ค.
๐ก๏ธ [๋ณด์ ํ๊ฐ]: ๊ถ์ฅ (์ค๋ฌด ํ์ค ๊ตฌ์ฑ)
๋ก์ปฌ ํ๊ฒฝ(127.0.0.1)์ด๋ ์ธ๋ถ ํ๊ฒฝ(LXC IP)์ด๋ IP ์ฃผ์๋ฅผ ๋ช
์ํ๋ฉด โUnix ์์ผ(local)โ ์ด ์๋ โ๋คํธ์ํฌ(host)โ ๋ฃฐ์ ํ๋๋ค. ๋คํธ์ํฌ ์ ์์ ๋น๋ฐ๋ฒํธ ์ธ์ฆ์ ์๊ตฌํ๋๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก, ๋ฐฑ์๋ ์๋ฒ์ DB ์๋ฒ๋ฅผ ๋ถ๋ฆฌํ๋ ์ค๋ฌด ์ํคํ
์ฒ์์ ๊ฐ์ฅ ์ ์์ ์ธ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ํฉ๋๋ค.
๋ฐฉ๋ฒ C. ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ๋ด ๋ช ์ฐฐ์ ์์ฅํ๊ธฐ (๊ธด๊ธ ์ ์ง๋ณด์์ฉ)
sudo -u <DB_USERNAME> psql
๐จ [๋ณด์ ํ๊ฐ]: ์ ํ๋ฆฌ์ผ์ด์ ๋จ์์ ์ ๋ ์ฌ์ฉ ๊ธ์ง
์ด์์ฒด์ ์ต๊ณ ๊ถํ(root ๋ฑ)์ ์ด์ฉํด ๋ช
์ฐฐ์ ์์กฐํ๋ ํ์์
๋๋ค. ํดํน ์ DB๋ฟ ์๋๋ผ ์๋ฒ ์ ์ฒด๊ฐ ์ฅ์
๋๋ฏ๋ก ๋ฐฑ์๋ ์ฝ๋๋ ์คํฌ๋ฆฝํธ์ ์ ๋ ํฌํจ๋์ด์๋ ์ ๋ฉ๋๋ค.
4. ๊ฒฐ๋ก : ์ต์ข ํ์๋ผ์ธ์ ์ฌ๊ตฌ์ฑ
์ฌ์ค ์ค์ ์ฅ์ ๊ฐ ๋ฐ์ํ๊ณ ์ฐ๋์ ๋ง์ณค๋ ๊ฒ์ ๋ช ๋ฌ ์ ์ ์ผ์ด์๊ณ , ์ด ๊ธ์ ๋น์ ๋ช ํํ ์ดํดํ์ง ๋ชปํ๋ ํด๊ฒฐ์ ์ค๋ง๋ฆฌ๋ฅผ ์ต๊ทผ์ ๋ค์ ์๋ฒ์ ์ ์ํด ๊ฒํ (Review)ํ๋ฉฐ ์์ฑํ ์ฌํ ๋ถ์์ ๋๋ค.
์๊ฐ์์ด ์ง๋ ๋ค ๋ฆฌ๋ ์ค ์ฝ์์ ์ด์ด ๋ค์ ๋ก๊ทธ์ ์ค์ ํ์ผ์ ๊ต์ฐจ ๊ฒ์ฆํด ๋ณธ ๊ฒฐ๊ณผ, ํ์๋ผ์ธ์ ์ง์ค์ ๋ค์๊ณผ ๊ฐ์์ต๋๋ค.
-
์๋ฌ ๋ฐ์: ์ต๊ณ ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก DB ๋น๋ฐ๋ฒํธ๋ฅผ ์ธํ ํ์ผ๋, ์ ์ ๋ฐฑ์๋ ์ฑ์์๋
Peer authentication failed์๋ฌ๊ฐ ๋ฐ์ํจ. -
์ฐ์ฐํ ํด๊ฒฐ: ๋ฐฑ์๋ ํ๊ฒฝ ์ค์ (
application.yml)์ DB ์ ์ ์ฃผ์๋ก LXC ์ปจํ ์ด๋์ IP ์ฃผ์๋ฅผ ๊ธฐ์ฌํ์ฌ ์ ์. -
์๋ฆฌ ํ์ (ํ์ฌ): LXC IP๋ฅผ ํตํ ์ ์์ TCP/IP ํต์ ์ด๋ฏ๋ก, ๊น๊นํ ๋๋ณด ์ ๋ฌธ(
local์์ผ์peer๋ฃฐ) ๋์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ํธํ ์ธ์ฆ(md5๋ฑ)์ด ํ์ฉ๋ ์ฃผ์ฐจ์ฅ ๊ฒ์ดํธ(host๋คํธ์ํฌ ๋ฃฐ)๋ฅผ ํ๊ฒ ๋์ด ์ฐ๋์ ์ฑ๊ณตํ๋ค๋ ๊ฒ์ ๋ค๋ฆ๊ฒ ๊นจ๋ฌ์.
๊ฒฐ๊ณผ์ ์ผ๋ก ์ค๋ฌด ํ์ค์ด์ ๋ณด์์์ผ๋ก๋ ์์ ํ โ๋ฐฉ๋ฒ Bโ๋ฅผ ํตํด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค. ๋จ์ํ ์ ์ ์๋ฌ๋ผ๋ ๊ทธ ์ด๋ฉด์ ์๋ ์ ์ ํ๋กํ ์ฝ(Socket vs TCP/IP)์ ์ฐจ์ด์ ์ธ์ฆ ๋ฃฐ์ ์๋ ๋ฐฉ์์ ๋ช ํํ ๊ท๋ช ํ๊ณ ๋์ด๊ฐ ์ ์์๋ ํ๊ณ ์์ต๋๋ค.