Nginx Proxy Manager로 NAS 외부 접속 구성하기

NAS 외부 접속을 DNS, 포트 전달, TLS, Proxy Host로 나눠 확인하고 증상별 점검 순서를 설명합니다.

NAS 서비스를 외부에 연결할 때는 설정 화면보다 요청이 멈춘 경계를 먼저 확인합니다. DNS를 관리하고 공유기와 NAS의 포트 설정을 확인할 수 있어야 합니다.

공개 전 조건을 표로 확인합니다

경계 통과 기준 실패할 때 확인할 항목
공인 DNS 도메인이 현재 공인 주소를 반환합니다 A·AAAA 레코드와 TTL을 확인합니다
라우터 외부 TCP 80·443이 NAS로 전달됩니다 포트포워딩, 방화벽, CGNAT를 확인합니다
Nginx Proxy Manager Proxy Host가 내부 서비스에 도달합니다 scheme, 대상 호스트, 포트를 확인합니다
TLS 도메인과 인증서 이름이 일치합니다 DNS 전파, 80·443 접근, 만료일을 확인합니다
Nginx Proxy Manager 외부 접속의 증상별 점검 순서
오류 화면에 따라 DNS, 포트, Proxy Host, TLS 중 조사할 경계를 선택합니다.

Compose 파일은 실행 전에 펼쳐 봅니다

경로는 NAS에서 사용하는 예시이므로 다른 환경에서는 자신의 Docker 데이터 경로로 바꿉니다.

mkdir -p /volume2/docker/nginx-proxy-manager
cd /volume2/docker/nginx-proxy-manager || exit
nano compose.yml
services:
  npm:
    image: jc21/nginx-proxy-manager:2.15.0
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - "80:80"
      - "127.0.0.1:81:81"
      - "443:443"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
docker compose up -d
docker compose ps
격리 환경에서 정상 기동한 Nginx Proxy Manager 초기 관리 화면
Nginx Proxy Manager 초기 관리 화면

공식 설치 문서는 80을 공개 HTTP, 443을 공개 HTTPS, 81을 관리 화면 포트로 설명합니다. 위 예시는 관리 포트 81을 NAS의 loopback 주소(127.0.0.1)에만 바인딩합니다. 다른 PC에서 관리 화면에 접속해야 한다면 81번 포트를 인터넷에 직접 노출하지 말고, 내부망·VPN·방화벽 등 별도 접근 제어를 사용합니다.

loopback 바인딩에서는 다른 PC가 http://NAS_IP:81로 바로 접속할 수 없습니다. NAS에 SSH 접속이 허용된 환경이라면 관리 PC에서 ssh -L 8181:127.0.0.1:81 your_user@192.168.0.10처럼 로컬 포워딩을 연 뒤 http://127.0.0.1:8181로 접속합니다. 사용자명과 NAS 내부 IP는 실제 값으로 바꿉니다.

격리된 예시 Compose 파일에서 127.0.0.1:8181:81과 8182:81을 docker compose config --format json으로 비교했습니다. 전자는 host_ip가 127.0.0.1로 출력됐고 후자는 host_ip가 생략됐습니다. Compose 포트 문서에 따르면 호스트 IP를 생략하면 모든 인터페이스에 바인딩됩니다. 이 확인은 설정 해석 결과이며 운영 NAS의 포트나 방화벽을 시험한 것은 아닙니다.

SSH 터널을 사용하지 않는다면 NAS의 내부망 IP에만 관리 포트를 바인딩하고 방화벽이나 VPN으로 접근 대상을 제한하는 별도 구성을 사용하세요. 81:81처럼 모든 인터페이스에 관리 포트를 여는 예시는 권장하지 않습니다.

Proxy Host와 TLS를 실제로 연결합니다

Nginx Proxy Manager가 기동된 뒤 관리 화면에서 Proxy Hosts → Add Proxy Host로 이동합니다. Domain Names에는 외부에서 사용할 도메인을 넣고, Scheme은 내부 서비스가 실제 사용하는 http 또는 https, Forward Hostname/IP에는 내부 서비스의 호스트명·IP, Forward Port에는 서비스 포트를 입력합니다. 같은 Docker 호스트에서 공용 사용자 정의 네트워크를 사용한다면 NPM 공식 고급 설정처럼 서비스 이름을 호스트명으로 지정할 수 있습니다.

먼저 Proxy Host를 저장한 뒤 HTTP로 내부 서비스가 정상 전달되는지 확인합니다. 그 다음 SSL 탭에서 Let’s Encrypt 인증서를 요청하거나 이미 준비한 인증서를 선택하고, 인증서 발급이 성공한 뒤 HTTPS와 Force SSL 적용 여부를 확인합니다. Nginx Proxy Manager 공식 안내는 외부 80·443을 NPM 호스트로 전달하고 도메인을 공인 주소에 연결한 뒤 NPM을 게이트웨이로 사용하는 구성을 설명합니다.

외부 HTTPS 인증은 클라이언트와 Nginx Proxy Manager 사이의 연결을 보호합니다. Proxy Host에서 내부 서비스의 scheme을 http로 정하면 프록시와 내부 서비스 사이 구간은 별도의 TLS로 암호화되지 않습니다. 내부망의 신뢰 경계와 접근 권한을 확인하고, 내부 구간에도 암호화가 필요하면 해당 서비스의 HTTPS와 인증서 검증을 구성하세요.

실제 적용에서는 외부 네트워크에서 https://<도메인>/을 열어 인증서 이름과 대상 서비스가 모두 맞는지 마지막으로 확인하세요.

외부와 내부를 따로 시험합니다

내부 서비스부터 curl -sS -D - -o /dev/null http://<내부서비스>:<포트>/로 확인합니다. 여기서 실패하면 Nginx Proxy Manager보다 대상 프로세스와 포트를 먼저 고칩니다. 내부 응답이 정상일 때 공인 DNS와 외부 HTTPS를 확인합니다.

dig A <도메인> @1.1.1.1의 응답이 기대한 공인 주소와 일치하고 외부 네트워크의 curl -sS -D - -o /dev/null https://<도메인>/이 응답하면, 해당 주소에서 HTTP 응답을 받은 것까지 확인한 것입니다. 상태 코드만으로 의도한 내부 서비스에 도달했다고 단정하지 말고 실제 페이지나 서비스의 응답 내용도 확인하세요. 리다이렉트라면 출력된 Location이 예상한 주소인지 살펴본 뒤 그 목적지도 확인합니다. HTTP 표준은 리다이렉트 응답의 Location을 이동 대상 참조로 정의합니다. 내부 Wi-Fi의 접속 성공만으로 외부 경로가 정상이라고 판정하지 않습니다.

증상에서 역순으로 범위를 줄입니다

DNS 조회 실패는 레코드와 위임을, 연결 거부나 시간 초과는 포트 전달·방화벽·CGNAT를 확인합니다. 502 응답은 Proxy Host의 scheme·호스트·포트와 내부 서비스 로그를 확인합니다. 인증서 경고는 요청 도메인, 인증서 이름, 만료일을 대조합니다.

설정 변경 전에는 현재 포트 점유와 라우터 규칙을 기록합니다. 인증서 발급을 반복하기 전에 DNS와 80·443 도달 여부를 먼저 고쳐 불필요한 재시도를 줄입니다.

공식 기준은 Nginx Proxy Manager 설치와 Docker Compose config 문서에서 확인할 수 있습니다.

공유기까지 요청이 도달하는지 먼저 확인하려면 공유기 포트포워딩 점검 순서에서 내부 리스닝, 이중 NAT, CGNAT, 외부 네트워크 시험을 순서대로 확인합니다.

관련 글