본문 바로가기

홈 서버

홈서버 구축기 #5 - Nginx Stream 모듈로 VM의 PostgreSQL 포트 포워딩하기

반응형

KVM/libvirt로 생성한 VM에서 실행 중인 PostgreSQL에 외부에서 접근하려면 포트 포워딩이 필요합니다. iptables를 사용하는 전통적인 방법도 있지만, Nginx의 Stream 모듈을 활용하면 더 직관적이고 관리하기 편한 솔루션을 구축할 수 있습니다.

 

응용하여, VM 내부에 실행 중인 프로세스를 외부에서 접속(연결)하도록 하고 싶은 경우에도 응용할 수 있습니다.

 

시작하기 전에

이 가이드는 다음 환경을 가정합니다.

  • 호스트 OS: Ubuntu 24.04
  • VM: KVM/libvirt로 생성된 VM (NAT 네트워크 사용)
  • VM IP: 192.168.122.100 (예시)
  • 목표: 호스트의 5432 포트로 들어오는 연결을 VM의 PostgreSQL(5432)로 포워딩
    DBeaver 같은 툴로 외부에서 DB를 다루기 위함. (내부 네트워크에서만 허용)

 

내부 네트워크 대역 확인.

DB의 경우 외부에서 접근 시 위험도가 높으므로, 현재 공유기 내부에 DBeaver 클라이언트 (데스크탑), 홈 서버가 위치하니 이점을 살려 내부에서만 접근가능하도록 해볼려고 합니다. 공유기 페이지에 접속하여 내부 네트워크 대역(IP 주소, 서브넷마스크)를 확인합니다.

 

1단계: VM IP 주소 확인

먼저 포워딩할 VM의 IP 주소를 확인합니다.

# VM 이름으로 IP 확인
virsh domifaddr <VM_NAME>

# 또는 모든 VM의 IP 확인
virsh net-dhcp-leases default

 

2단계: Nginx Stream 모듈 설치 및 활성화

현재 Nginx 상태 확인

# Nginx 버전 확인
nginx -v

# Stream 모듈 컴파일 여부 확인
nginx -V 2>&1 | grep -o with-stream

with-stream이 출력되더라도 바로 사용할 수 있는 것은 아닙니다. 대부분의 최신 Ubuntu에서 Nginx는 stream을 동적 모듈(dynamic module)로 컴파일하므로 별도 설치가 필요합니다.

 

# stream이 dynamic으로 컴파일되었는지 확인
nginx -V 2>&1 | grep "with-stream=dynamic"

 

Stream 동적 모듈 설치 (중요!)

Ubuntu의 기본 Nginx 패키지는 stream 기능이 동적 모듈로 분리되어 있습니다. 따라서 반드시 별도 패키지를 설치해야 합니다.

# Stream 동적 모듈 설치
sudo apt update
sudo apt install libnginx-mod-stream

# 설치 확인
dpkg -l | grep libnginx-mod-stream

 

모듈 활성화 확인

모듈 설치 후 자동으로 활성화되지만, 확인해보겠습니다.

# 모듈 설정 파일 확인
ls -la /usr/share/nginx/modules-available/ | grep stream
# 50-mod-stream.conf 파일이 있어야 함

# modules-enabled에 심링크 확인
ls -la /etc/nginx/modules-enabled/ | grep stream
# 50-mod-stream.conf 심링크가 있어야 함

 

만약 심링크가 없다면 수동으로 생성

sudo ln -s /usr/share/nginx/modules-available/50-mod-stream.conf \
           /etc/nginx/modules-enabled/50-mod-stream.conf

 

Nginx 재시작 (중요!)

모듈 설치 후에는 반드시 restart를 해야 합니다 (reload가 아님)

# Nginx 완전 재시작
sudo systemctl restart nginx

# 상태 확인
sudo systemctl status nginx

 

3단계: Nginx Stream 포트 포워딩 설정

이제 stream 모듈이 로드되었으므로 설정을 추가할 수 있습니다.

기본 설정

Nginx 메인 설정 파일을 편집합니다.

sudo vim /etc/nginx/nginx.conf

 

파일의 맨 아래에 다음 내용을 추가합니다 (중요: http { } 블록 밖에 위치해야 함)

# PostgreSQL 포트 포워딩
stream {
    server {
        listen 5432;

		# 접근 제어
        allow 172.30.1.0/24; # 내부 네트워크 요청만 허용
        allow 127.0.0.1; # 로컬

        # 추가적으로 외부에서 고정 IP로 접근하는 경우 allow 사용

        deny all;

        proxy_pass 192.168.122.100:5432; # VM IP

    }
}

 

설정 테스트 및 적용

# 설정 문법 검사
sudo nginx -t

 

성공 메시지가 나오면 리로드를 진행해 줍니다.

# 설정 리로드
sudo systemctl reload nginx

# 포트 리스닝 확인
sudo ss -tlnp | grep 5432

 

postgresql 설정

postgresql의 경우 외부에서 연결하려면 설정을 더 해주어야 합니다. 이 설정은 postgresql이 설정된 가상머신 내부에서 진행하면 됩니다.

 

1. 접근 가능한 address 설정.

가상머신 내에서

sudo vi /etc/postgresql/16/main/postgresql.conf 

# Vi 편집기 내부
# 아래처럼 변경 후 저장
listen_addresses = '*'            # what IP address(es) to listen on;

 

2. 접근 가능한 IP 대역 설정

sudo vi /etc/postgresql/16/main/pg_hba.conf  

# 아래 추가 (KVM/libvirt의 기본 NAT 네트워크 대역)
host    all             all             192.168.122.0/24        scram-sha-256

 

postgresql 재시작

sudo systemctl restart postgresql

 

접속 테스트

내부 네트워크에서는 공유기 포트포워딩 없이 바로 접속 가능합니다. 즉, DBeaver 등 GUI 툴에서 아래 값을 입력하면 연결이 될 것입니다.

  • Host: 172.30.1.x (서버 내부 IP)
  • Port: 5432
  • Database: 데이터베이스명
  • Username/Password: DB 계정 정보

 

간단하게 구조를 보면 아래와 같습니다.

  • 홈 데스크탑(172.30.1.x) → 홈 서버(172.30.1.x):5432 → VM PostgreSQL 

 

프로덕션 환경을 위한 고급 설정

실제 운영 환경에서는 더 상세한 설정이 필요할 수 있습니다.

stream {
    # 로그 설정
    access_log /var/log/nginx/postgres_access.log;
    error_log /var/log/nginx/postgres_error.log;
    
    # 업스트림 서버 정의
    upstream postgres_backend {
        server 192.168.122.100:5432 max_fails=3 fail_timeout=30s;
        # 여러 PostgreSQL 서버가 있다면 추가 가능
        # server 192.168.122.101:5432;
        # server 192.168.122.102:5432;
    }
    
    server {
        listen 5432;
        
        # 접근 제어
        allow 172.30.1.0/24; # 내부 네트워크 요청만 허용
        allow 127.0.0.1; # 로컬
		deny all;
        
        proxy_pass postgres_backend;
        
        # 타임아웃 설정
        proxy_connect_timeout 60s;
        proxy_timeout 600s;  # 긴 쿼리를 위한 타임아웃
        
        # 버퍼 크기
        proxy_buffer_size 64k;
    }
}

 

 

핵심 포인트 정리

  1. Ubuntu의 기본 Nginx는 stream이 동적 모듈: nginx -V에서 with-stream이 보여도 바로 사용할 수 없음
  2. 반드시 libnginx-mod-stream 패키지 설치 필요: 이것이 가장 중요한 단계
  3. 모듈 설치 후 restart 필요: reload가 아닌 restart를 해야 모듈이 로드됨
  4. stream 블록은 http 블록 밖에: nginx.conf의 최상위 레벨에 위치해야 함

 

여러 서비스 포워딩하기

동일한 방법으로 다른 서비스들도 포워딩할 수 있습니다.

stream {
    # PostgreSQL
    server {
        listen 5432;
        allow 172.30.1.0/24;
    	allow 127.0.0.1;
    	deny all;
        proxy_pass 192.168.122.100:5432;
    }
    
    # MySQL/MariaDB
    server {
        listen 3306;
        allow 172.30.1.0/24;
    	allow 127.0.0.1;
    	deny all;
        proxy_pass 192.168.122.100:3306;
    }
    
    # MongoDB
    server {
        listen 27017;
        allow 172.30.1.0/24;
        allow 127.0.0.1;
    	deny all;
        proxy_pass 192.168.122.100:27017;
    }
    
    # Redis
    server {
        listen 6379;
        allow 172.30.1.0/24;
    	allow 127.0.0.1;
    	deny all;
        proxy_pass 192.168.122.100:6379;
    }
    
    # SSH (다른 포트로 포워딩)
    server {
        listen 2222;
        proxy_pass 192.168.122.100:22;
    }
}

 

마무리

Nginx Stream 모듈을 사용한 포트 포워딩은 설정이 직관적이고 관리가 편리합니다. 특히 Ubuntu에서는 libnginx-mod-stream 패키지만 설치하면 바로 사용할 수 있어 매우 간단합니다.

 

핵심은 stream이 동적 모듈이라는 점을 이해하고, 별도 패키지 설치가 필요하다는 것을 아는 것입니다. 이 점만 기억한다면 손쉽게 VM의 데이터베이스나 다른 서비스들을 접근 가능하게 할 수 있습니다.

반응형