ROUTER + PORT FORWARDING + HTTPS

공유기에서 443 포트만 MyBoard로 연결하기

외부에서 443번 HTTPS만 열려 있는 환경에서는 공유기가 인터넷의 443 요청을 스마트폰의 Nginx로 전달해야 합니다. 이 페이지는 내부 IP 고정, 포트포워딩 입력, Nginx 수신 포트, 테스트와 장애 확인 순서를 설명합니다.

먼저 전체 흐름 이해하기

포트포워딩은 인터넷에서 공유기로 들어온 특정 포트의 연결을 내부 네트워크의 특정 기기와 포트로 전달하는 기능입니다. 공개 포트는 하나만 사용하고, PHP-FPM과 SQLite는 외부에 직접 노출하지 않습니다.

인터넷 사용자
    │ https://example.com:443
    ▼
공유기 공인 IP
    │ 외부 TCP 443
    ▼
스마트폰 내부 IP 192.168.0.25
    │ 내부 TCP 443 또는 8443
    ▼
Nginx ── HTTPS 인증서
    │ 127.0.0.1:9000 또는 PHP-FPM 소켓
    ▼
PHP-FPM ── MyBoard ── data/board.sqlite

공유기에서 443만 허용하는 환경이라면 외부 사용자는 반드시 HTTPS로 접속해야 합니다. 80번 HTTP 포트를 열 수 없으면 HTTP에서 HTTPS로 자동 이동하는 기능은 동작하지 않을 수 있으므로 처음부터 https:// 주소를 사용하세요.

1. 포트포워딩 전에 확인할 것

  1. 도메인의 A 레코드가 공유기의 현재 공인 IPv4 주소를 가리키는지 확인합니다.
  2. 공유기 관리 화면에서 인터넷(WAN) IP 주소를 확인합니다.
  3. 스마트폰과 공유기가 같은 Wi-Fi에 연결되어 있는지 확인합니다.
  4. 스마트폰의 내부 IPv4 주소를 확인합니다.
  5. Nginx가 실제로 443 또는 8443에서 듣고 있는지 확인합니다.
# 스마트폰 Termux에서 내부 주소 확인
ip addr
ip route

# Nginx와 PHP-FPM 수신 포트 확인
ss -ltnp | grep -E ':(443|8443|9000)\b'

# 공유기 외부 주소 확인
curl -4 https://ifconfig.me

공유기의 WAN 주소와 외부 주소 확인 결과가 다르면 통신사 장비, 상위 공유기 또는 CGNAT 뒤에 있을 수 있습니다. 이 경우 현재 공유기에서 포트포워딩을 만들어도 인터넷에서 도달하지 않을 수 있습니다.

2. 스마트폰 내부 IP를 고정하기

포트포워딩은 특정 내부 IP로 전달하므로 스마트폰 주소가 바뀌면 설정이 깨집니다. 공유기의 DHCP 예약 또는 고정 할당 메뉴에서 스마트폰의 MAC 주소에 항상 같은 주소를 배정하세요.

예시
스마트폰 MAC 주소: 공유기 연결 기기 목록에서 확인
예약 내부 IP:       192.168.0.25
서브넷 마스크:      255.255.255.0
게이트웨이:         192.168.0.1

스마트폰에서 수동으로 주소를 지정하는 방식보다 공유기의 DHCP 예약을 우선 권장합니다. 공유기 주소 대역이 192.168.1.x 또는 다른 대역이면 예시를 그대로 입력하지 말고 현재 네트워크 대역에 맞추세요.

설정 후 Wi-Fi를 다시 연결하고 다음 결과가 예약한 주소인지 확인합니다.

ip route get 1.1.1.1
ip -4 addr show

3. 공유기 포트포워딩 규칙 만들기

공유기 관리 화면의 메뉴 이름은 제조사에 따라 포트포워딩, NAT, 가상 서버, 포트 매핑 등으로 표시됩니다. 새 규칙을 만들고 다음처럼 입력합니다.

규칙 이름:       myboard-https
프로토콜:        TCP
외부 시작 포트:  443
외부 종료 포트:  443
내부 IP 주소:    192.168.0.25
내부 시작 포트:  443
내부 종료 포트:  443
사용:            켜짐

이 설정은 공인 IP의 TCP 443번 요청만 스마트폰의 443번으로 전달합니다. UDP 443을 별도로 열 필요는 없습니다. Nginx가 8443에서 실행되는 일반 Termux 환경이라면 내부 포트만 8443으로 바꿉니다.

규칙 이름:       myboard-https-termux
프로토콜:        TCP
외부 포트:       443
내부 IP 주소:    192.168.0.25
내부 포트:       8443

외부 포트는 사용자가 접속하는 주소의 포트이고, 내부 포트는 스마트폰에서 Nginx가 실제로 듣는 포트입니다. 두 포트가 반드시 같을 필요는 없지만, 외부 443은 그대로 유지해야 사용자가 별도 포트 없이 https://example.com으로 접속할 수 있습니다.

4. Nginx 수신 포트 맞추기

포트포워딩의 내부 포트와 Nginx의 listen 포트가 같아야 합니다. 443을 직접 사용할 수 있는 환경은 아래처럼 설정하고, 일반 Termux 사용자 환경은 8443을 사용합니다.

# root 또는 443 사용 권한이 있는 환경
server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate /home/user/.ssl/example.com/fullchain.cer;
    ssl_certificate_key /home/user/.ssl/example.com/key;

    root /home/user/www/myboard;
    index index.php;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        fastcgi_pass 127.0.0.1:9000;
    }
}
# 일반 Termux 사용자 환경
server {
    listen 8443 ssl;
    server_name example.com www.example.com;
    ssl_certificate /data/data/com.termux/files/home/.ssl/example.com/fullchain.cer;
    ssl_certificate_key /data/data/com.termux/files/home/.ssl/example.com/key;
    root /data/data/com.termux/files/home/www/myboard;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS on;
        fastcgi_pass 127.0.0.1:9000;
    }
}

설정을 바꾼 뒤 다음 순서로 검사합니다.

nginx -t
nginx -s reload
ss -ltnp | grep -E ':(443|8443)\b'

5. 같은 Wi-Fi와 외부 인터넷에서 각각 테스트

같은 Wi-Fi에 연결된 다른 기기에서는 먼저 내부 주소로 테스트합니다. 내부 테스트가 실패하면 공유기 포트포워딩보다 스마트폰의 Nginx, 방화벽, 포트 설정을 먼저 고쳐야 합니다.

# 내부 443 포트 구성
curl -k -I https://192.168.0.25

# 내부 8443 포트 구성
curl -k -I https://192.168.0.25:8443

외부 테스트는 스마트폰을 Wi-Fi에서 분리하고 모바일 데이터나 다른 네트워크를 사용하세요. 일부 공유기는 자신의 공인 도메인을 내부에서 다시 접속하는 NAT loopback을 지원하지 않습니다.

# 외부 네트워크에서 도메인 테스트
curl -I https://example.com

# DNS가 어느 주소를 가리키는지 확인
nslookup example.com

인증서가 정상이라면 -k 없이도 HTTPS 요청이 성공해야 합니다. -k는 내부 IP로 접속할 때 도메인 불일치 경고를 건너뛰기 위한 테스트 옵션일 뿐, 실제 운영 옵션으로 사용하지 마세요.

6. 443만 열 때의 보안 원칙

  • 공유기에서 외부로 공개하는 규칙은 TCP 443 하나만 유지합니다.
  • 8080, 8443, 9000, SQLite 관련 포트는 외부 포트포워딩을 만들지 않습니다.
  • PHP-FPM은 127.0.0.1:9000 또는 Unix 소켓에서만 수신하도록 합니다.
  • SSH가 필요하면 웹 서비스와 별도로 관리하고, 인터넷에 SSH 포트를 공개할 때는 키 인증과 허용 IP 제한을 함께 검토합니다.
  • 공유기의 UPnP 자동 포트 개방 기능은 필요하지 않다면 끕니다.
  • 관리자 화면, 공유기, Termux, Nginx와 PHP를 최신 보안 상태로 유지합니다.
  • 인증서 개인키와 SQLite 백업 파일은 웹 루트 밖에 두고 외부 공유를 금지합니다.

443 하나만 공개해도 웹 애플리케이션의 로그인과 업로드 기능은 인터넷에 노출됩니다. 포트 수가 적다는 것만으로 안전해지는 것은 아니므로 관리자 비밀번호, 파일 업로드, 업데이트와 백업도 함께 관리해야 합니다.

접속이 안 될 때 확인 순서

  1. 도메인 문제: DNS A 레코드가 현재 공유기 공인 IP를 가리키는지 확인합니다.
  2. 공인 IP 문제: 공유기 WAN IP와 외부 IP가 다른지 확인합니다. 다르면 CGNAT 또는 이중 공유기일 수 있습니다.
  3. 내부 서비스 문제: 스마트폰에서 ss -ltnp로 Nginx가 443 또는 8443을 듣는지 확인합니다.
  4. 포트 규칙 문제: 프로토콜이 TCP인지, 내부 IP가 현재 스마트폰 주소인지, 외부 443과 내부 포트가 올바른지 확인합니다.
  5. 인증서 문제: Nginx 설정의 도메인, fullchain.cer, key 경로를 확인하고 nginx -t를 실행합니다.
  6. 통신사 차단: CGNAT, 기업·공용망 방화벽, ISP의 인바운드 443 제한 여부를 확인합니다.

CGNAT 뒤에 있어 공인 인바운드 연결을 받을 수 없다면 공유기 설정만으로 해결되지 않습니다. 이 경우 공인 IP를 제공하는 회선, 외부 VPS의 리버스 프록시, 또는 신뢰할 수 있는 터널링 서비스를 검토해야 합니다.