
로컬 개발 환경 외부 공개 및 보안 강화 설정 가이드
1. 개요 (Overview)
이 문서는 macOS (Apple Silicon) 환경에서 실행 중인 다수의 로컬 웹
애플리케이션을 Nginx 리버스 프록시와 Cloudflare Tunnel을 사용하여 외부
인터넷에 안전하게 공개하는 방법을 기술합니다. 서버의 실제 IP를 노출하지 않고,
각 프로젝트를 고유한 서브도메인으로 접근할 수 있도록 설정하며, 기본적인 웹
공격에 대한 보안을 강화하는 것을 목표로 합니다.
2. 시스템 아키텍처 (System Architecture)
사용자의 요청은 다음의 흐름에 따라 처리됩니다.
1 외부 사용자 -> Cloudflare DNS -> Cloudflare 네트워크 (DDoS 방어, WAF) ->
Cloudflare Tunnel -> 로컬 Nginx (8080 포트) -> 로컬 프로젝트 (300x 포트)
- Cloudflare Tunnel: 로컬 서버의 인바운드 포트를 열 필요 없이 Cloudflare
네트워크와 안전한 터널을 생성하여 트래픽을 수신합니다.
- Nginx: 로컬에서 리버스 프록시 역할을 수행하며, 요청된 서브도메인에 따라
적절한 포트에서 실행 중인 프로젝트로 트래픽을 라우팅합니다.
3. 사전 준비 (Prerequisites)
- macOS (Apple Silicon) 운영체제
- Homebrew (https://brew.sh/)) 설치
- Cloudflare에 등록된 개인 도메인
4. 설정 절차 (Setup Procedure)
1단계: 프로젝트 식별 및 포트 할당
먼저, 외부로 공개할 로컬 프로젝트와 각 프로젝트에 할당할 포트를 결정합니다.
- proj1: http://localhost:3001
- proj2: http://localhost:3002
- proj3: http://localhost:3003
- proj4: http://localhost:3004
2단계: 필수 패키지 설치
Homebrew를 사용하여 Nginx와 Cloudflare Tunnel 클라이언트(cloudflared)를
설치합니다.
1 brew install nginx cloudflared
3단계: Nginx 리버스 프록시 설정
3.1. 설정 디렉토리 생성
Nginx가 추가 설정을 로드할 디렉토리를 생성합니다. (이미 존재할 수 있음)
1 sudo mkdir -p /opt/homebrew/etc/nginx/servers/
3.2. Nginx 설정 파일 생성
각 서브도메인을 로컬 프로젝트 포트로 전달하고 보안 헤더를 추가하는 설정
파일을 작성합니다. 아래 내용을 projects.conf 파일로 저장합니다.
1 \# /opt/homebrew/etc/nginx/servers/projects.conf
2
3 server {
4 listen 8080;
5 server\_name proj1.01079991731.work;
6
7 location / {
8 proxy\_pass http://localhost:3001;
9 proxy\_set\_header Host $host;
10 proxy\_set\_header X-Real-IP $remote\_addr;
11 proxy\_set\_header X-Forwarded-For $proxy\_add\_x\_forwarded\_for;
12 proxy\_set\_header X-Forwarded-Proto $scheme;
13 proxy\_http\_version 1.1;
14 proxy\_set\_header Upgrade $http\_upgrade;
15 proxy\_set\_header Connection "upgrade";
16
17 \# Security Headers
18 add\_header X\-Frame-Options "SAMEORIGIN" always;
19 add\_header X\-Content\-Type-Options "nosniff" always;
20 add\_header Strict-Transport-Security "max-age\=31536000;
includeSubDomains" always;
21 }
22 }
23
24 server {
25 listen 8080;
26 server\_name proj2.01079991731.work;
27
28 location / {
29 proxy\_pass http://localhost:3002;
30 \# ... (proxy\_set\_header 및 add\_header 내용은 위와 동일)
31 }
32 }
33
34 server {
35 listen 8080;
36 server\_name proj3.01079991731.work;
37
38 location / {
39 proxy\_pass http://localhost:3003;
40 \# ... (proxy\_set\_header 및 add\_header 내용은 위와 동일)
41 }
42 }
43
44 server {
45 listen 8080;
46 server\_name proj4.01079991731.work;
47
48 location / {
49 proxy\_pass http://localhost:3004;
50 \# ... (proxy\_set\_header 및 add\_header 내용은 위와 동일)
51 }
52 }
3.3. Nginx 서비스 재시작
새 설정을 적용하기 위해 Nginx를 재시작합니다.
1 brew services restart nginx
4단계: Cloudflare Tunnel 설정
4.1. Cloudflare 인증
아래 명령을 실행하고, 열리는 브라우저 창에서 Cloudflare 계정에 로그인하여
인증을 완료합니다.
1 cloudflared tunnel login
4.2. 터널 생성
터널을 식별할 이름(예: my-dev-tunnel)으로 새로운 터널을 생성합니다.
1 cloudflared tunnel create my-dev-tunnel
이 명령은 터널의 UUID와 크리덴셜 파일 경로(~/.cloudflared/.json)를
출력합니다.
4.3. 터널 구성 파일 작성
~/.cloudflared/config.yml 파일을 생성하고 아래 내용을 작성합니다. tunnel:과
credentials-file:의 UUID는 이전 단계에서 출력된 값으로 대체해야 합니다.
1 # ~/.cloudflared/config.yml
2 tunnel: 123123123123123123123
3 credentials-file:
/Users/user/.cloudflared/12312312312312123.json
4
5 ingress:
6 \- hostname: proj1.01079991731.work
7 service: http://localhost:8080
8 \- hostname: proj2.01079991731.work
9 service: http://localhost:8080
10 \- hostname: proj3.01079991731.work
11 service: http://localhost:8080
12 \- hostname: proj4.01079991731.work
13 service: http://localhost:8080
14 \- service: http\_status:404 \# 일치하는 호스트가 없는 경우 404 반환
4.4. Cloudflare DNS 설정
Cloudflare 대시보드에서 도메인의 DNS 레코드로 이동하여, 터널을 가리키는 CNAME
레코드를 추가합니다. 와일드카드(*)를 사용하면 모든 서브도메인을 한 번에
처리할 수 있습니다.
- Type: CNAME
- Name: *
- Content: 123123123123123.cfargotunnel.com (터널 생성 시 얻은 UUID)
- Proxy status: Proxied (주황색 구름 활성화)
4.5. Cloudflare Tunnel 실행
터미널 세션이 종료되어도 프로세스가 유지되도록 nohup을 사용하여 터널을
백그라운드에서 실행합니다.
1 nohup cloudflared tunnel run my-dev-tunnel > /dev/null 2>&1 &
5단계: 로컬 애플리케이션 실행
각 프로젝트를 백그라운드에서 지속적으로 실행합니다.
1 # proj1
2 cd /Users/jsy/dev/proj1
3 npm install
4 nohup npm run dev -- -p 3001 > /dev/null 2>&1 &
5
6 # proj2
7 cd /Users/jsy/dev/proj2
8 npm install
9 nohup npm run dev -- -p 3002 > /dev/null 2>&1 &
10
11 # proj3
12 cd /Users/jsy/dev/proj3
13 npm install
14 nohup npm run dev -- -p 3003 > /dev/null 2>&1 &
15
16 # proj4
17 cd /Users/jsy/dev/proj4
18 npm install
19 nohup npm run dev -- -p 3004 > /dev/null 2>&1 &
5. 보안 강화 (Security Hardening)
Nginx 보안 헤더 (적용 완료)
- X-Frame-Options "SAMEORIGIN": 클릭재킹 공격 방지.
- X-Content-Type-Options "nosniff": MIME 타입 스니핑 방지.
- Strict-Transport-Security: 모든 연결을 HTTPS로 강제.
Cloudflare 보안 기능
- DDoS 방어: Cloudflare의 글로벌 네트워크를 통해 기본적으로 활성화됩니다.
- IP 마스킹: Cloudflare Tunnel을 사용하여 실제 서버 IP가 외부에 노출되지 않습니다.
- WAF (Web Application Firewall): 애플리케이션 취약점 공격 방어.
1. Cloudflare 대시보드 -> Security -> WAF -> Managed rules 탭으로이동합니다.
2. Cloudflare Managed Ruleset과 OWASP Core Ruleset을 활성화("On")합니다.
(플랜에 따라 일부 제한될 수 있습니다.)
6. 관리 및 유지보수
- Nginx 재시작: brew services restart nginx
- Nginx 에러 로그: tail -f /opt/homebrew/var/log/nginx/error.log
- 실행 중인 터널 및 프로젝트 확인: ps aux | grep 'cloudflared\|node'
- 특정 포트 사용 프로세스 확인: lsof -i :<포트번호>
- 프로세스 종료: kill 또는 pkill <프로세스이름>
'개발 > Linux & DevOps' 카테고리의 다른 글
| vercel git 연동 오류 (0) | 2025.12.17 |
|---|---|
| github acitons 타임스탬프 찍기, 배포 관리 방법, 우선순위 (0) | 2025.04.16 |
| Actuator 의 DB 헬스체크 (1) | 2024.12.18 |
| 젠킨스 build.xml 에 대한 고찰 (0) | 2024.11.26 |
| nginx, logrotate 운영 환경 세팅 (kill USR1, 파일디스크립터) (4) | 2024.07.22 |