반갑습니다. 저는|기업가이자, 엔지니어입니다.
NAS 와 Linux 서버에서 Reverse Proxy 사용하기 (feat. Nginx Proxy Manager)

NAS 와 Linux 서버에서 Reverse Proxy 사용하기 (feat. Nginx Proxy Manager)

Tags
NAS
Docker
Nginx
Proxy
Published
발행일 - 2022년 6월 30일
Author
Eugene Jeon (전유진)
AuthorLink

개요

NAS 의 기본포트를 수정하지 않고, Nginx Proxy Manager 를 이용하여 프록시 서버를 구현할 수 있다. 이를 간단하게 따라할 수 있도록 소개한다.
 
Synology NAS 에는 이미 Nginx 서버가 설치되어 있다.
그래서 사실상 Synology NAS 에서는 Nginx Proxy Manager 를 설치할 필요가 없다.
 
그럼에도 불구하고 굳이 소개하는 이유는 다음과 같다.
 
  1. 검색을 해보면 Nginx Proxy Manager 를 이용하는 분들이 많은 것을 알게 되었다. 그리고 NAS 의 기본 포트인 80/443 을 변경하여 설정하는 것도 확인했다.
  1. Linux 서버에서 프록시 서버를 구축할 경우, 80/81/443 이외의 포트로 운영할 방법이 필요할 수 있다. 또한 Nginx Proxy Manager 에서는 Container 안에서 밖으로 통신 할 수 있는 host.docker.internal 방법이 적용되지 않는다. 이슈카드가 열려있다. 그래서 docker container 의 network modehost 로 열고 사용할 경우에도 기본포트를 변경해야 한다.
 
설명은 길지만, 요약하면 다음과 같다.
Nginx Proxy Manager 를 이용하면서 서비스 포트를 변경하고 싶은 경우, 아래 내용살펴보자.
 

Nginx Proxy Manager

 
많은 사람들이 이용하는 서비스이다. 포크버전도 많고, 중국 사용자를 위한 버전도 있다.
 

Nginx Proxy Manager 서비스 포트 수정

이제 우리는 서비스 포트를 수정하여, Nginx Proxy Manager 를 사용할 것이다.

프로젝트(소스) 복사

먼저 원본 소스를 다운받아 준다. 소스는 Github 에 존재한다.
notion image
(bash)
git clone https://github.com/NginxProxyManager/nginx-proxy-manager.git

서비스 포트 정하기

따라 할 내용은 없다. 다만, 아래 내용을 따라가다 보면 서비스 포트(코드)를 수정해야 하는데, 사용할 포트를 미리 정해두는 것이 좋다.
 
  1. Public HTTP Port - 80번으로 웹 프로토콜이다. 흔히 브라우저에 도메인으로 접속할때 사용된다.
  1. Public HTTPS Port - 443번으로 보안인증서를 사용하는 웹 프로토콜이다. (상동)
  1. Nginx Proxy Manager Admin Web Port - 원본은 81번 포트이다. 관리자 페이지 접속 포트이다.
 
우리는 각 포트를 원하는 대로 변경할 것이다. 아래 내용은 임의로 정한 포트이니 원하는 포트로 변경해서 사용할 수 있다.
기본(원본) - 변경전
변경후
1
80
8080
2
443
4443
3
81
8181
 

Dockerfile 내용 변경

우리는 변경한 서비스 포트를 이용하여 새로운 이미지를 만들 것이다.
그래서 Dockerfile 부터 변경한다.
주의! EXPOSE 부분을 원하는 포트로 변경해주어야 한다. → 31-32 번 라인
(bash)
cd nginx-proxy-manager && cat > Dockerfile
(docker)
# This is a Dockerfile intended to be built using `docker buildx` # for multi-arch support. Building with `docker build` may have unexpected results. # This file assumes that the frontend has been built using ./scripts/frontend-build FROM nginxproxymanager/nginx-full:certbot-node ARG TARGETPLATFORM ARG BUILD_VERSION ARG BUILD_COMMIT ARG BUILD_DATE ENV SUPPRESS_NO_CONFIG_WARNING=1 \ S6_FIX_ATTRS_HIDDEN=1 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ NODE_ENV=production \ NPM_BUILD_VERSION="${BUILD_VERSION}" \ NPM_BUILD_COMMIT="${BUILD_COMMIT}" \ NPM_BUILD_DATE="${BUILD_DATE}" RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ && apt-get update \ && apt-get install -y --no-install-recommends jq logrotate \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # s6 overlay COPY scripts/install-s6 /tmp/install-s6 RUN /tmp/install-s6 "${TARGETPLATFORM}" && rm -f /tmp/install-s6 # [주의!] 원하는 포트로 변경해야 한다. EXPOSE 8080 4443 8181 COPY backend /app COPY frontend/dist /app/frontend COPY global /app/global WORKDIR /app RUN yarn install # add late to limit cache-busting by modifications COPY docker/rootfs / # Remove frontend service not required for prod, dev nginx config as well RUN rm -rf /etc/services.d/frontend /etc/nginx/conf.d/dev.conf # Change permission of logrotate config file RUN chmod 644 /etc/logrotate.d/nginx-proxy-manager # fix for pip installs # https://github.com/NginxProxyManager/nginx-proxy-manager/issues/1769 RUN pip uninstall --yes setuptools \ && pip install "setuptools==58.0.0" VOLUME [ "/data", "/etc/letsencrypt" ] ENTRYPOINT [ "/init" ] LABEL org.label-schema.schema-version="1.0" \ org.label-schema.license="MIT" \ org.label-schema.name="nginx-proxy-manager" \ org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \ org.label-schema.url="https://github.com/jc21/nginx-proxy-manager" \ org.label-schema.vcs-url="https://github.com/jc21/nginx-proxy-manager.git" \ org.label-schema.cmd="docker run --rm -ti jc21/nginx-proxy-manager:latest"

file-patch 파일 작성

file-patch : 파일 내용을 간단하게 수정하도록 도와주는 쉘 스크립트이다.
nginx-proxy-manager 폴더에는 nginx 설정파일들이 있다.
파일을 하나씩 열어서 수정하는 것은 매우 번거롭다. 그래서 쉘 스크립트를 작성하여 간단하게 변경할 것이다.
(bash)
cat > file-patch.sh
(shell)
#!/bin/sh usage() { echo "usage: $(basename "$0") [SED_OPT...] SED_EXPRESSION FILE sed with a patch-like behavior. This helper returns: - A success when running the sed expression SED_EXPRESSION results in changes applied to file FILE. - An error when running the sed expression SED_EXPRESSION results in no change to file FILE. NOTE: sed option '-i' is already supplied by this script. " } eval FILE=\${$#} if [ "$#" -lt 2 ]; then echo "ERROR: Not enough arguments." exit 1 fi sed -i.bak "$@" RC="$?" if [ "$RC" -eq 0 ]; then diff "$FILE" "$FILE".bak > /dev/null 2>&1 case $? in 0) # Files are the same. echo "ERROR: No modification applied to $FILE." RC=1 ;; 1) # Files differ. RC=0 ;; *) ;; esac fi rm -f "$FILE".bak exit $RC

서비스 포트 변경을 위한 Nginx 파일 수정

위에서 작성한 file-patch.sh 을 이용하여 Nginx 각 파일을 수정할 것이다.
변경 & 사용할 서비스 포트를 주의해서 사용하기 바란다.
(bash)
# Change the management interface port to the unprivileged port 8181. sh ./file-patch.sh 's|81 default|8181 default|' ./rootfs/etc/nginx/conf.d/production.conf # Change the HTTP port 80 to the unprivileged port 8080. sh ./file-patch.sh 's|80;|8080;|' ./rootfs/etc/nginx/conf.d/default.conf && \ sh ./file-patch.sh 's|"80";|"8080";|' ./rootfs/etc/nginx/conf.d/default.conf && \ sh ./file-patch.sh 's|listen 80;|listen 8080;|' ../backend/templates/letsencrypt-request.conf && \ sh ./file-patch.sh 's|:80;|:8080;|' ../backend/templates/letsencrypt-request.conf && \ sh ./file-patch.sh 's|listen 80;|listen 8080;|' ../backend/templates/_listen.conf && \ sh ./file-patch.sh 's|:80;|:8080;|' ../backend/templates/_listen.conf && \ sh ./file-patch.sh 's|80 default;|8080 default;|' ../backend/templates/default.conf # Change the HTTPs port 443 to the unprivileged port 4443. sh ./file-patch.sh 's|443 |4443 |' ./rootfs/etc/nginx/conf.d/default.conf && \ sh ./file-patch.sh 's|"443";|"4443";|' ./rootfs/etc/nginx/conf.d/default.conf && \ sh ./file-patch.sh 's|listen 443 |listen 4443 |' ../backend/templates/_listen.conf && \ sh ./file-patch.sh 's|:443 |:4443 |' ../backend/templates/_listen.conf && \ sh ./file-patch.sh 's|:443;|:4443;|' ../backend/templates/_listen.conf
 
전부 Nginx 에서 사용하는 설정파일들이다.
참고로 templates 폴더에 있는 파일은 nginx-proxy-manager 에서 새로운 설정을 추가할 때 사용하는 템플릿이다.
 

Nginx Proxy Manager Admin Frontend Web 빌드

Nginx Proxy Manager 의 관리자 페이지를 사용을 위해 빌드한다.
 
그 전에 webpack.config.js 파일을 수정해야 한다.
이미지 폴더를 복사하는 구문이 존재하는데, 수정하지 않으면 나중에 관리자 페이지의 이미지(사진) 보이지 않아서 심적으로 불편할 수 있다.
 
코드를 열어서 수정해도 좋다. 개발자가 아니라면 위에서 생성했던, file-patch.sh 를 이용해서 수정하는 방법을 추천한다.
(bash)
sh ./file-patch.sh 's|/app/frontend|./|' ../frontend/webpack.config.js
 
변경이 완료된 부분의 webpack.config.js 코드 사진이다.
notion image
 
이제 Frontend 웹 코드를 빌드해야 한다.
빌드는 yarn 을 이용하므로, 주의한다.
(bash)
cd ../frontend && yarn && yarn build
 

Nginx Proxy Manager 의 Container 이미지 빌드

Nginx Proxy Manager 는 기본적으로 Docker 를 이용한다.
만약, docker 가 아직 설치되어 있지 않다면 아래 링크를 참고하여 docker 를 설치해야 한다.
 
수정한 내용으로 우리가 사용할 새로운 이미지를 만든다.
(bash)
cd ../ && docker build -t custom-nginx-proxy-manager:v0.0.1 -f ./docker/Dockerfile .
 

Nginx Proxy Manager Container 관리를 위한 docker-compose 작성

Docker 의 컨테이너를 편하게 관리하기 위해서 docker-compose 를 사용하는 것이다.
만약, docker-compose 가 아직 설치되어 있지 않다면 아래 링크를 참고하여 docker-compose 를 설치하자.
 
docker-compose 파일을 작성한다.
참고로 아래 코드를 이용하면, 자동으로 volumes 폴더를 생성하고 연결한다.
이는 1. 데이터를 남겨서 백업하거나 2. nginx-proxy-manager 를 업데이트 할 때, 3. nginx-proxy-manager 컨테이너가 종료되어 다시 시작할 때 와 같이 다양한 상황에서 유용하다.
(bash)
cd ../ && mkdir -p docker-containers/nginx-proxy && cd docker-containers/nginx-proxy && mkdir data && mkdir letsencrypt && cat > docker-compose.yaml
(yaml)
version: '3' services: nginx-proxy: image: 'custom-nginx-proxy-manager:v0.0.1' container_name: 'nginx-proxy' restart: unless-stopped network_mode: 'host' volumes: - ./data:/data - ./letsencrypt:/etc/letsencrypt environment: - TZ=Asia/Seoul
 

Nginx Proxy Manager 실행

작성한 docker-compose 파일을 이용해서 프록시 서버를 실행한다.
(bash)
docker-compose up -d
 
docker-compose 를 이용하면 컨데이터 종료&삭제 및 종료된 컨테이너 재 실행도 유용하다.
(bash)
# 컨테이너 종료 & 삭제 docker-compose down # 컨테이너 실행 & 재 실행 docker-compose up -d
 

관리자 페이지 접속 및 초기 사용자 정보

[서버IP]:8181 로 접속하면, 관리자 페이지를 볼 수 있다.
 
  • 초기 사용자 정보
    • admin@example.com
      changeme
 

만약, 접속이 되지 않는다면?

 
  1. Listen 포트 확인
    1. (bash)
      sudo lsof -i TCP -p | grep LISTEN
  1. ufw 확인
    1. (bash)
      sudo ufw status verbose
      → ufw 포트 추가
      (bash)
      sudo ufw allow 8080/tcp && \ sudo ufw allow 4443/tcp && \ sudo ufw allow 8181/tcp
 

호스트 추가할 때, 팁!

우리는 일반 80/443 포트를 이용하고 있지 않다.
그래서 커스텀 포트로 도메인 접속이 안될 수 도 있다. 이를 해결 하려면 Nginx 의 설정파일을 건드려야 한다.
 
하지만, 더 간단한 방법이 존재한다.
바로 각 도메인을 2개씩 추가하는 방법이다.
 
예를 들어, sub.domain.com:8080 을 추가 하여 다른 곳으로 프록시를 시키고 싶다.
그럴때는 아래 사진과 같이 각 2개씩 추가하는 것이다. (sub.domain.com / sub.domain.com:8080)
notion image
 

결론

본인은 여전히 Synology NAS 에서 해당 서비스를 사용하고 있지 않다.
기본으로 설치되어 있는 Nginx 를 이용하고 있다.
 
하지만, 여러가지 이유로 Nginx Proxy Manager 를 사용 할 분들을 위해, 작성하고 기록으로 남긴다.

Loading Comments...