프록시와 VPN
포워드·리버스 프록시의 중개 방향과 용도를 구분하고 Nginx 프록시 설정 및 VPN 터널의 보호 범위를 이해합니다.
프록시(Proxy)는 대리인이라는 뜻 그대로, 클라이언트와 서버 사이에서 요청을 중개하는 서버입니다.
누구를 대신해 중개하는지에 따라 포워드 프록시와 리버스 프록시를 구분합니다.
포워드 프록시 vs 리버스 프록시
| 구분 | 중개 관계 |
|---|---|
| 포워드 | 클라이언트가 프록시를 선택하고, 프록시가 여러 목적지로 요청을 보냅니다. 클라이언트의 외부 접근 정책을 적용하는 지점입니다. |
| 리버스 | 클라이언트는 서비스 주소로 요청하고, 프록시가 백엔드로 전달합니다. 서버 진입점의 라우팅·TLS·캐시 정책을 적용합니다. |
포워드 프록시
포워드 프록시(Forward Proxy)는 클라이언트 측에 위치하여 클라이언트의 요청을 대신 보냅니다.
일반적으로 목적지 서버는 직접 연결한 주체인 프록시의 IP를 보며, 실제 클라이언트 IP는 프록시가 별도 헤더로 전달하지 않는 한 알기 어렵습니다.
기업에서 직원들의 인터넷 접속을 관리하는 용도로 많이 사용합니다.
회사 프록시가 특정 사이트 접근을 차단하거나, 직원들의 웹 사용 기록을 모니터링합니다.
HTTPS 트래픽의 본문까지 검사하려면 단순 프록시만으로는 부족하고, 기업 단말에 신뢰된 루트 인증서를 배포하는 TLS inspection 구성이 필요합니다.
학교나 도서관의 인터넷 필터링도 포워드 프록시 방식으로 구현될 수 있습니다.
개발 환경에서도 포워드 프록시를 만납니다.
회사 네트워크에서 npm install이 실패하면 DNS·인증서·인증과 함께 프록시 설정을 확인합니다.
# 환경 변수 설정
export HTTP_PROXY=http://proxy.company.com:8080
export HTTPS_PROXY=http://proxy.company.com:8080
export NO_PROXY=localhost,127.0.0.1,.company.com
# npm 프록시 설정
npm config set proxy http://proxy.company.com:8080
npm config set https-proxy http://proxy.company.com:8080
# git 프록시 설정
git config --global http.proxy http://proxy.company.com:8080환경 변수 이름의 대소문자와 NO_PROXY 해석은 도구마다 다릅니다. 예를 들어 curl은 HTTP 프록시에 소문자 http_proxy를 사용하며 대문자 HTTP_PROXY를 받지 않습니다. 예시의 회사 주소는 실제 환경 값으로 바꿔야 하고 npm·git --global 명령은 저장된 설정을 변경합니다.
리버스 프록시
리버스 프록시(Reverse Proxy)는 서버 측에 위치하여 클라이언트의 요청을 받아 적절한 백엔드 서버로 전달합니다.
클라이언트는 리버스 프록시를 접점으로 사용하지만 응답 헤더·오류에 백엔드 정보가 드러날 수 있어 익명성을 보장하는 것은 아닙니다.
HTTP 로드 밸런서는 리버스 프록시로 구현할 수 있습니다. 직접 서버 반환(DSR) 같은 L4 분산 방식까지 모두 같은 프록시 구조로 볼 수는 없습니다.
그 외에도 다양한 역할을 합니다.
| 기능 | 적용 효과와 조건 |
|---|---|
| TLS 종단 | 인증서를 진입점에서 관리합니다. 백엔드 구간 TLS는 별도 설정입니다. |
| 캐싱 | 저장 가능한 정적 파일·API 응답으로 백엔드 부하를 줄입니다. |
| 압축 | 지원되는 gzip·Brotli 등으로 전송량을 줄이되 CPU 비용을 비교합니다. |
| 보안 | WAF·진입 경로 제한으로 공격 표면을 줄입니다. 프록시 배치만으로 보장되지 않습니다. |
| 속도 제한 | 설정된 키별 요청 수를 제한합니다. 대규모 공격에는 용량·상위 방어도 필요합니다. |
Nginx를 리버스 프록시로 사용하기
Nginx는 리버스 프록시와 웹 서버 기능을 제공합니다. 다음 예시는 http 문맥 안에 놓는 설정이며, http2 on은 Nginx 1.25.1 이상을 기준으로 합니다.
upstream backend {
least_conn; # 최소 연결 알고리즘
server 127.0.0.1:3001 weight=3; # 가중치 3
server 127.0.0.1:3002 weight=1; # 가중치 1
server 127.0.0.1:3003 backup; # 백업 서버
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri; # HTTP → HTTPS 리다이렉트
}
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
# 정적 파일 직접 서빙 (백엔드 거치지 않음)
location /static/ {
root /var/www;
expires 30d;
add_header Cache-Control "public, immutable";
}
# API는 백엔드로 프록시
location /api/ {
proxy_pass http://backend;
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;
# 타임아웃 설정
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
# WebSocket 지원
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}least_conn은 가중치를 고려한 연결 수로 대상을 고르므로 요청 수가 항상 3:1이 되는 것은 아닙니다. backup은 주 대상이 사용 불가일 때 쓰며, 예시에는 별도의 능동 헬스 체크가 없습니다.
proxy_pass http://backend에는 URI 부분이 없으므로 /api/·/ws/ 경로를 그대로 전달합니다. 정적 /static/a.js는 /var/www/static/a.js에 대응하며, immutable은 내용이 바뀌면 URL도 바꾸는 자원에 적용해야 합니다.
proxy_read_timeout 30s는 전체 응답 마감이 아니라 연속 읽기 사이의 시간 제한입니다. /ws/에는 이 30초 설정이 상속되지 않으며, 별도 설정이 없으면 기본 읽기 제한과 서버 Ping 등 연결 유지 방식을 확인해야 합니다.
X-Real-IP와 X-Forwarded-For는 신뢰할 프록시 범위를 정한 뒤 해석합니다. 특히 $proxy_add_x_forwarded_for는 받은 값을 앞에 남기므로, 신뢰한 프록시가 보냈다는 이유로 클라이언트가 넣은 맨 왼쪽 IP까지 신뢰해서는 안 됩니다.
VPN
VPN(Virtual Private Network)은 공용 인터넷을 통해 가상의 사설 네트워크를 구성합니다.
암호화를 사용하는 원격 접속 VPN의 경계입니다. 단말에서 VPN 게이트웨이까지 터널이 보호하며, 게이트웨이 이후 서버까지의 기밀성은 HTTPS 등 별도 보호가 필요합니다. 내부 접근은 라우트와 권한 정책이 허용할 때만 가능합니다.
VPN의 핵심은 터널링(Tunneling)입니다.
이 절에서 다루는 암호화 원격 접속 VPN은 원래 패킷을 보호하고 외부 전송용 패킷으로 감쌉니다. VPN이라는 이름만으로 모든 구현이 같은 암호화·보호 범위를 제공하는 것은 아닙니다.
외부 네트워크에서는 VPN 게이트웨이와 통신한다는 사실, 대략적인 트래픽 양, 타이밍 같은 메타데이터는 볼 수 있지만, 터널 안의 사설 IP와 애플리케이션 데이터는 알기 어렵습니다.
또한 모든 트래픽을 VPN으로 보내는 full tunnel과 내부망 트래픽만 보내는 split tunnel은 동작 범위가 다릅니다.
| 방식 | 캡슐화·보호의 구분 |
|---|---|
| IPsec | IP 계층을 보호하며 일반적인 VPN 구성은 ESP와 IKEv2를 사용합니다. 암호화 방식은 협상 설정에 달려 있습니다. |
| OpenVPN | UDP 또는 TCP 위 터널입니다. TLS 기반 제어 채널과 데이터 채널을 구분하며 TUN은 IP, TAP은 이더넷 프레임을 운반합니다. |
| WireGuard | UDP로 IP 패킷을 운반하며 Noise 기반 핸드셰이크·ChaCha20-Poly1305 등을 사용합니다. |
| L2TP/IPsec | L2TP 캡슐화와 IPsec 보호를 결합합니다. L2TP 자체를 암호화로 해석하지 않습니다. |
개발자 실무에서 VPN은 주로 회사의 개발 서버, 데이터베이스, 내부 API에 외부에서 접근할 때 사용합니다.
접속 후에도 필요한 라우트·DNS·접근 권한과 방화벽 정책이 허용해야 회사 자원에 접근할 수 있습니다. 프로토콜 이름만으로 성능 순위를 정하지 말고 MTU·암호화 구현·경로·장비 조건을 함께 비교합니다.
다음 절에서는 클라우드와 컨테이너 환경의 네트워크를 다루겠습니다.