homelab89 Docs Logs Legacy Files ☰ TOC 🌓
notenetworking 2026-06-29networkingtunnelinghttpproxy

HTTP Tunneling

HTTP Tunneling이란?

HTTP Tunneling은 HTTP 프로토콜을 통로(터널)로 사용하여, 원래 HTTP가 아닌 트래픽을 전달하는 기법이다.

많은 기업 네트워크/방화벽은 HTTP(80)와 HTTPS(443) 포트만 허용한다. HTTP tunneling을 사용하면 이 제한된 환경에서도 다른 프로토콜의 트래픽을 주고받을 수 있다.


주요 방식

1. HTTP CONNECT (가장 대표적)

  • 클라이언트가 프록시 서버에 CONNECT 메서드를 전송
  • 프록시가 목적지와 TCP 연결을 수립하면, 이후 양방향 바이트 스트림이 됨
  • HTTPS 통신의 기본 동작 방식
Client → Proxy:  CONNECT example.com:443 HTTP/1.1
Proxy → Client:  HTTP/1.1 200 Connection Established
(이후 TLS 핸드셰이크 및 암호화된 데이터가 그대로 통과)

2. HTTP Encapsulation

  • 비-HTTP 데이터를 HTTP 요청/응답 body에 감싸서 전달
  • 예: SSH-over-HTTP, DNS-over-HTTPS (DoH)
  • 각 메시지가 일반 HTTP 요청처럼 보이므로 방화벽 통과가 용이

3. WebSocket Upgrade

  • 초기 HTTP 핸드셰이크 후 풀-듀플렉스 TCP 연결로 전환
  • 실시간 양방향 통신에 사용 (채팅, 스트리밍 등)

일반 프록시 vs HTTP Tunnel

[일반 HTTP 프록시]
Client → Proxy → Server   (프록시가 HTTP 내용을 읽고 중계)

[HTTP Tunnel (CONNECT)]
Client → Proxy → Server   (프록시는 바이트를 그대로 전달, 내용 못 봄)
         ════════════════  ← 투명한 TCP 파이프

핵심 차이는 프록시가 payload를 해석하느냐 여부이다. 터널에서는 프록시가 단순 relay 역할만 하므로 TLS 등 암호화된 트래픽도 통과시킬 수 있다.


실제 사용 사례

사례 설명
HTTPS 브라우저가 프록시 환경에서 CONNECT로 TLS 터널 생성
Corporate proxy 우회 방화벽 뒤에서 SSH, VPN 등을 HTTP로 감싸서 사용
ngrok / Cloudflare Tunnel 로컬 서비스를 외부에 노출할 때 HTTP 터널 활용
DNS-over-HTTPS DNS 쿼리를 HTTPS 요청으로 캡슐화

실습: Squid 프록시 + CLI 도구

환경 준비

# Squid 설치
sudo apt install -y squid

# 기본 포트: 3128
# 설정 파일: /etc/squid/squid.conf

Step 1: HTTPS 트래픽 터널링 (curl + CONNECT)

# CONNECT 터널 경유 HTTPS 요청
curl -x http://localhost:3128 https://httpbin.org/ip

# -v 옵션으로 CONNECT 핸드셰이크 과정 확인
curl -v -x http://localhost:3128 https://httpbin.org/ip

curl -v 출력에서 다음과 같은 흐름이 보인다:

* Establish HTTP proxy tunnel to httpbin.org:443
> CONNECT httpbin.org:443 HTTP/1.1
> Host: httpbin.org:443
>
< HTTP/1.1 200 Connection established
<
* CONNECT tunnel established, response 200
* TLS handshake starts...

Squid 로그 확인:

sudo tail -f /var/log/squid/access.log
# TCP_TUNNEL/200 CONNECT httpbin.org:443 형태의 로그가 기록됨

Step 2: 패킷 캡처로 CONNECT 동작 관찰

# 터미널 1: loopback 트래픽 캡처
sudo tcpdump -i lo port 3128 -A

# 터미널 2: curl 요청
curl -x http://localhost:3128 https://httpbin.org/ip

관찰 포인트:

  • CONNECT 요청/응답 헤더는 평문으로 보임
  • 이후 TLS 핸드셰이크 데이터는 암호화되어 읽을 수 없음
  • 프록시는 목적지 호스트:포트만 알 수 있고, 실제 전송 내용은 알 수 없음

Step 3: Raw CONNECT 핸드셰이크 직접 해보기 (nc)

# netcat으로 Squid에 직접 접속
nc localhost 3128

수동으로 아래 내용을 입력:

CONNECT httpbin.org:443 HTTP/1.1
Host: httpbin.org:443

응답:

HTTP/1.1 200 Connection established

이 시점에서 터널이 열린 상태이다. 이후 입력하는 모든 바이트는 httpbin.org:443으로 그대로 전달된다.

Step 4: SSH over HTTP Tunnel

Squid 설정에서 포트 22에 대한 CONNECT를 허용해야 한다:

# /etc/squid/squid.conf에 추가
# acl Safe_ports port 22
# acl SSL_ports port 22
# 설정 변경 후: sudo systemctl reload squid

SSH 터널링 실행:

# nc를 ProxyCommand로 사용하여 SSH를 HTTP CONNECT 터널로 통과
ssh -o ProxyCommand='nc -X connect -x localhost:3128 %h %p' localhost

Squid 로그에서 SSH 연결이 CONNECT로 터널링된 것을 확인할 수 있다.

정리

# 실습 후 정리
sudo apt remove --purge squid
sudo apt autoremove

보안 관점

  • 정당한 용도: HTTPS 통신, 기업 VPN, 보안 DNS
  • 리스크: 방화벽/DLP를 우회할 수 있어 데이터 유출 경로가 될 수 있음
  • 대응: 프록시에서 CONNECT 대상 도메인/포트를 화이트리스트로 제한

핵심 정리

  1. CONNECT 메서드 — 프록시에게 “이 호스트:포트로 TCP 파이프를 열어달라"는 요청
  2. 터널 vs 프록시 — 터널은 프록시가 payload를 해석하지 않음 (바이트 릴레이)
  3. 보안 시사점 — CONNECT로 임의 포트를 열 수 있으면 방화벽 우회 가능 → 포트 제한 필수

Files