두 가지 설계, 하나의 HTTPS 애플리케이션, 그리고 패킷은 각각 다른 경로를 갑니다. 포트 포워딩은 패킷이 전달되는 곳을 바꾸고 나머지는 그대로 둡니다. VPN은 먼저 그 패킷을 다른 패킷 안에 넣어 나르므로, 애플리케이션의 리스너는 다른 출처와 더 작은 최대 페이로드를 봅니다. 사람들이 논쟁하는 암호화는 두 경우 모두 존재합니다. 애플리케이션이 여전히 HTTPS이기 때문입니다. 다른 것은 누가 연결을 열 수 있는지, 그리고 중간 네트워크가 무엇을 관찰할 수 있는지입니다. 이 구분이 대부분의 실무 질문을 정리합니다.

DNAT 규칙은 목적지를 다시 쓰고 거기서 멈춘다

Linux 게이트웨이에서 서비스를 게시한다는 것은 nat 테이블의 PREROUTING 체인에 규칙을 두거나 nftables에서 그에 상응하는 것을 두는 것입니다. 규칙은 공인 주소와 포트에 일치하고, 그다음 목적지를 애플리케이션의 사설 주소로 다시 씁니다. 출발지 주소, 출발지 포트, 페이로드는 그대로이고, conntrack이 매핑을 기록하므로 응답은 나갈 때 다시 쓰입니다. 이 동작은 RFC 3022에 설명된 전통적인 주소 변환 모델입니다.

sudo iptables -t nat -A PREROUTING -d 203.0.113.10 -p tcp --dport 443 \
  -j DNAT --to-destination 10.20.30.40:443
sudo iptables -t nat -L PREROUTING -n -v
sudo conntrack -L -p tcp --dport 443

애플리케이션의 리스너는 연결이 변환을 거쳐 왔다는 것을 결코 알지 못하며, 클라이언트의 실제 출발지 주소를 보아 접근 로그와 속도 제한에 유용합니다. conntrack이 매핑을 뒤집기 때문에 사설 주소로 응답합니다. 그 경로에서 복호화나 재암호화는 일어나지 않습니다. TLS는 클라이언트와 애플리케이션 자체 인증서 사이에서 계속 동작합니다.

규칙은 나중에 만날 실패 방식도 정합니다. 게이트웨이가 전달하지만 애플리케이션 호스트에 클라이언트로 돌아가는 경로가 없으면, 응답은 잘못된 출처로 나가고 핸드셰이크가 멈춥니다. 두 번째 규칙이 먼저 일치하면 순서가 결과를 정하고, iptables -t nat -L -n -v은 어느 규칙이 패킷을 가져갔는지 보여 주는 카운터를 표시합니다.

터널은 리스너가 보기 전에 패킷을 감싼다

VPN은 애플리케이션을 전혀 게시하지 않습니다. 클라이언트는 게이트웨이의 공인 주소로 향하는 바깥 패킷을 만들고 그 안에 안쪽 패킷을 암호화하며, 게이트웨이는 복호화하여 안쪽 패킷을 사설 목적지로 라우팅합니다. WireGuard에서는 바깥 전송이 UDP이고 보통 높은 포트를 씁니다. OpenVPN을 TCP 443에서 쓰면 경로를 지켜보는 무엇에게든 바깥 패킷이 TLS처럼 보입니다.

터널 안에서 안쪽 패킷은 사설 주소를 유지합니다. 클라이언트의 터널 주소, 예를 들어 10.8.0.6, 그리고 10.20.30.40의 애플리케이션입니다. 그래서 리스너는 터널 풀에서 온 출처를 보고, 모든 클라이언트가 그 게이트웨이를 다음 홉으로 공유합니다. VPN 뒤의 접근 로그가 사용자 대신 게이트웨이를 자주 보여 주는 것은 바로 이 이유이며, 게이트웨이가 원래 출처를 보존하지 않는 한 그렇습니다.

감싸는 데 헤더 공간이 들고, 이것이 측정 가능한 결과를 가진 유일한 메커니즘 수준의 차이입니다. 바깥 IP 헤더에 UDP, 여기에 WireGuard 자체 헤더가 경로의 MTU를 먹으므로 큰 패킷은 분할해야 하거나 안쪽 TCP 스택이 MSS를 제한해야 합니다. 전달 경로에서 동작하는 전송이, 중간 장비가 더 작은 MTU를 알리는 ICMP를 버리면 터널에서 멈출 수 있습니다.

ip route get 10.20.30.40
ping -M do -s 1400 10.20.30.40
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
  -j TCPMSS --clamp-mss-to-pmtu

노출은 입구에서 정해지고 암호로 정해지지 않는다

두 설계 모두 같은 TLS 리스너에서 끝나므로 같은 인증서, 같은 프로토콜 버전, 같은 애플리케이션 로그인을 물려받습니다. 달라지는 것은 누가 핸드셰이크를 시작할 수 있느냐입니다. 공인 포워딩에서는 203.0.113.10:443에 도달할 수 있는 어떤 호스트든 애플리케이션 권한이 검토되기도 전에 TCP 핸드셰이크와 TLS ClientHello를 받습니다. 터널 전용 접속에서는 게이트웨이가 터널로 라우팅하는 주소에서만 리스너에 닿을 수 있고, 낯선 자의 SYN은 게이트웨이 정책에서 죽습니다.

이 차이는 도달 가능성에 관한 것이지 기밀성에 관한 것이 아닙니다. 포워딩된 HTTPS 서비스는 평문이 아니며, VPN은 애플리케이션 인증의 필요를 없애지 않습니다. 터널 입장은 장치가 이 네트워크로 패킷을 보낼 수 있는지를 답하고, 파일 애플리케이션은 사용자가 문서를 읽을 수 있는지를 답합니다. 둘을 혼동하면 팀은 LAN 전체를 내주는 VPN과 하나의 공유 비밀번호를 쓰는 애플리케이션에 이르게 됩니다.

리스너와 정책을 따로 점검하십시오. 둘 중 어느 쪽이든 생각보다 넓을 수 있습니다.

sudo ss -ltnp 'sport = :443'
sudo nft list ruleset
openssl s_client -connect 203.0.113.10:443 -servername files.example.com </dev/null

ss이 리스너가 0.0.0.0에 바인딩되어 있음을 보여 주면, 애플리케이션은 라우팅과 방화벽 정책이 허용하는 어디서든 도달할 수 있고, 포워딩은 입구 중 하나일 뿐입니다. 사설 주소에 바인딩하거나 방화벽에서 출발지 범위를 좁히는 것은 VPN 선택과 별개의 결정이며, 노출을 실제로 줄이는 결정입니다.

라벨이 아니라 경로를 측정한다

누군가 포워딩이 더 빠르다고 주장할 때, 정직한 비교는 같은 클라이언트, 같은 접속망, 같은 파일, 같은 TLS 구성, 같은 애플리케이션 호스트로 나머지를 모두 고정합니다. 경로마다 전송을 두 번 실행하고 총 시간, 실패 횟수, 응답성을 기록하십시오. 무관한 속도 테스트의 출력이 아닙니다.

curl -sS -o /dev/null -w '%{time_connect} %{time_appconnect} %{time_total}\n' \
  https://files.example.com/report.pdf
mtr -rwc 20 203.0.113.10
mtr -rwc 20 10.20.30.40

이 숫자들은 연결 설정과 전송 시간을 분리합니다. 두 경로는 보통 암호 비용이 아니라 왕복 지연과 MTU에서 다르기 때문입니다. TLS 작업은 두 설계 모두 끝점에서 일어나고, 터널은 캡슐화, 다른 경로, 어쩌면 더 붐비는 게이트웨이를 더합니다. 터널 경로가 더 길거나 게이트웨이가 부하를 받고 있다면 그 차이는 경로의 것이지 암호화라는 단어의 것이 아닙니다.

서비스가 실제로 필요로 하는 입구 정책을 고르고, 측정된 차이가 그것을 바꿀 만한지 결정하십시오. 공인 포워딩은 출발지 제한, 최신 TLS, 앞단 모니터링을 갖춘 개방 인터넷용 서비스에 어울립니다. 터널 전용 접속은 사용자가 이미 등록된 내부 도구에 어울리며, 게이트웨이 라우팅과 애플리케이션 권한이 모두 LAN 전체보다 좁아야 합니다.

설계를 완료라고 부르기 전에 네 가지를 확인하십시오. 리스너가 어느 주소에 바인딩되어 있는지, 어떤 규칙이나 경로가 패킷을 받아들이는지, 클라이언트의 실제 주소에서 돌아오는 경로가 동작하는지, 큰 페이로드가 MTU를 넘어서는지입니다. 각각에 위의 명령이 있고, 어느 것도 «안전»이라는 단어나 대역폭 차트로 답할 수 없습니다.

관련 글