개요
- 목적: n8n 워크플로의 Webhook 트리거(Telegram 등)를 외부에서 접근 가능하도록 노출
- 배경: n8n은 내부 svc VNet에서 운영 중이라 외부 서비스(Telegram Bot 등)가 Webhook을 전달할 수 없음
외부 노출 방법 후보
| 방안 | 개요 |
|---|
| Cloudflare Tunnel | Cloudflare 엣지를 경유하여 내부 서비스를 외부에 노출 |
| Proxmox SDN + Nginx | VNet 분리 후 pub VNet의 Nginx에서 리버스 프록시 |
Cloudflare Tunnel 미채택 이유
| 항목 | 상세 |
|---|
| 보안 우회 | OPNsense 방화벽을 우회하여 내부 서비스에 직접 접근 가능. 방화벽 기반 보안 정책 무력화 |
| 지연(Latency) | 트래픽이 미국 Cloudflare 엣지를 경유하여 약 300ms 추가 지연 발생 |
| 기존 인프라 | 이미 Proxmox SDN과 Nginx 인프라가 구축되어 있어 별도 외부 서비스 불필요 |
1. 네트워크 구성 (Proxmox SDN)
- Proxmox SDN의
vlan Zone 내에 VNet을 분리하여 역할별 네트워크 격리.
VNet 구성
| VNet ID | VLAN Tag | 용도 | 대역 | 비고 |
|---|
| vnetsvc | 40 | 내부 서비스 (n8n, DB 등) | 192.168.4.x | 외부 직접 접근 불가 |
| vnetpub | 30 | 외부 노출 서비스 (Nginx) | 192.168.3.x | 공인 IP 포트포워딩 대상 |
트래픽 흐름
graph LR
A["외부<br/>(Telegram 등)"] -->|":443"| B["공인 IP"]
B -->|"포트포워딩"| C["Nginx<br/>(pub 192.168.3.x)"]
C -->|"리버스 프록시"| D["n8n<br/>(svc 192.168.4.x:5678)"]
2. n8n LXC 설정
- n8n은 Proxmox LXC 컨테이너에서 구동. svc VNet에 배치.
n8n 환경 변수 (Webhook 외부 노출 관련)
# Webhook 외부 접근 URL (Nginx에서 프록시되는 도메인)
WEBHOOK_URL=https://n8n.fresh96jwjw.org/
N8N_HOST=0.0.0.0
N8N_PORT=5678
N8N_PROTOCOL=https
주의: WEBHOOK_URL을 설정하지 않으면 n8n이 내부 IP로 Webhook URL을 생성하여 외부에서 접근 불가.
3. Nginx 리버스 프록시 (pub VNet)
- pub VNet의 LXC에 Nginx를 배치. n8n으로 리버스 프록시.
Nginx 설정 예시
server {
listen 443 ssl;
server_name n8n.fresh96jwjw.org;
location / {
proxy_pass http://<n8n_svc_ip>:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 지원 (n8n 에디터 실시간 통신)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
4. Proxmox 방화벽 구성
- Proxmox Datacenter 레벨에서 Alias와 Security Group을 정의하고, 각 CT 방화벽에서 Security Group을 참조하는 구조.
Alias 정의 (Datacenter > Firewall > Alias)
- 방화벽 규칙에서 IP를 직접 쓰지 않고 Alias로 관리하여 가독성과 유지보수성 확보.
| Alias | IP/CIDR |
|---|
admin_pc | 관리 PC IP |
ext_npm | Nginx(pub VNet) IP |
lan_net | LAN 대역 (x.x.x.0/24) |
svc_net | svc 대역 (x.x.x.0/24) |
Security Group: isolated_svc
- 용도: svc VNet 컨테이너(n8n 등)에 적용. Nginx와 관리 PC만 접근 허용, 나머지 내부망 차단.
| # | 유형 | 액션 | 소스 | 대상(Destination) | 설명 |
|---|
| 0 | in | ACCEPT | dc/admin_pc | | 관리 PC → svc 접근 |
| 1 | in | ACCEPT | dc/ext_npm | | Nginx → svc 접근 (Webhook 프록시) |
| 2 | out | ACCEPT | | dc/ext_npm | svc → Nginx 응답 |
| 3 | out | ACCEPT | | dc/admin_pc | svc → 관리 PC 응답 |
| 4 | out | ACCEPT | | +dc/opnsense_gw | 게이트웨이 통신 (DNS, NTP 등) |
| 5 | out | REJECT | | 192.168.0.0/16 | 그 외 내부망 접근 차단 |
Security Group: isolated_pub
- 용도: pub VNet 컨테이너(Nginx)에 적용. LAN 접근만 차단, 나머지(svc, 인터넷) 허용.
| # | 유형 | 액션 | 소스 | 대상(Destination) | 설명 |
|---|
| 0 | in | ACCEPT | | | 외부 인바운드 허용 |
| 1 | out | REJECT | | dc/lan_net | LAN 직접 접근 차단 |
| 2 | out | ACCEPT | | | 나머지 아웃바운드 허용 (svc, 인터넷 포함) |
CT 방화벽 적용
- 각 CT의 Firewall 탭에서 Security Group을 삽입하여 규칙 적용.
| CT | Security Group |
|---|
| CT 111 (n8n) | isolated_svc |
| CT 117 (nginxproxymanager-ext) | isolated_pub |
핵심: Security Group을 재사용하므로 동일 VNet의 다른 CT에도 즉시 적용 가능. svc는 Nginx와 관리 PC만 접근, pub는 svc에만 아웃바운드 허용하여 LAN 우회 차단.
결과
- Telegram Bot의 Webhook URL을
https://n8n.fresh96jwjw.org/webhook/... 으로 설정하여 정상 수신 확인.
- SDN 방화벽 로그에서 허용된 트래픽만 svc VNet에 도달함을 검증.
최종 구성 요약
| 구성 요소 | 위치 | 역할 |
|---|
| n8n | svc VNet (LXC) | 워크플로 엔진, Webhook 수신 |
| Nginx | pub VNet (LXC) | 리버스 프록시 |
| OPNsense | 게이트웨이 | VNet 간 방화벽, 접근 제어 |
| Proxmox SDN | 하이퍼바이저 | VNet 네트워크 분리 |