웹만 허용하는 네트워크에서 VPN이 막혔나요? 계층별로 확인하세요
브라우저는 되는데 터널이 죽는다. curl의 시간 단계를 읽고, 프록시를 시험하고, 443이 정말 허용되는지 확인한 뒤 머신을 떠난 것을 캡처한다.
브라우저는 되고 모든 터널이 죽는 캠퍼스나 호텔 네트워크는 문제 하나가 아니라 네 개의 층이다. 경로가 TCP 443만 허용할 수도, 인증된 프록시를 요구할 수도, 핸드셰이크를 검사할 수도, 아니면 정책으로 원격 접속을 그냥 금지할 수도 있다. 순서대로 처리하면 네트워크 규칙을 고치려고 새 클라이언트를 사는 일은 없다. 아래 절차는 약 십 분이 걸리고 어느 층이 당신을 거부했는지에 대한 서면 답으로 끝난다.
어느 층이 연결을 거부하는지 증명하세요
VPN 클라이언트부터 시작하지 마세요. 같은 호스트로 평범한 HTTPS 요청을 보내고 시간 단계를 읽으세요, 실패하는 단계가 어느 장비의 책임인지 알려줍니다:
curl -sS -o /dev/null -w 'connect=%{time_connect} tls=%{time_appconnect} code=%{http_code}\n' \
--max-time 8 https://vpn.example.net/
응답도 connect 시간도 없으면 TCP가 끝나지 않은 것이므로 방화벽, 프록시 요구, 잘못된 목적지가 작동 중이다. connect 시간이 있고 tls 시간이 없으면 중간의 무언가가 연결을 받아들인 뒤 핸드셰이크를 멈춘 것이고, 검사 프록시는 클라이언트 쪽에서 그렇게 보인다.
이제 실제로 받는 인증서를 보세요. 서버와 이야기하는지, 세션에 다시 서명한 중간 상자와 이야기하는지 아는 가장 빠른 방법입니다:
openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -brief </dev/null
발급자 줄을 읽으세요. 자기 CA면 서비스에 도달한 것이고, 기업이나 장비 발급자면 필터가 연결을 끝내고 다음을 결정하고 있는 것이다. 두 출력을 시각과 함께 기록하세요, 한 시간 뒤 게스트 네트워크의 같은 시험은 다른 답을 줄 수 있다.
프록시를 인식하는 클라이언트는 첫 패킷을 바꾸지, 정책을 바꾸지 않는다
네트워크가 인증 프록시를 통한 CONNECT를 요구하면 VPN 클라이언트에 알려야 한다, 그렇지 않으면 라우팅할 수 없는 주소로 소켓을 열려고 한다. 프록시는 클라이언트와 따로 시험해 실패의 설명이 하나가 되게 하세요:
https_proxy=http://proxy.example.edu:3128 curl -v -o /dev/null https://vpn.example.net/
sudo openvpn --config /etc/openvpn/corp.conf --proto tcp-client \
--remote vpn.example.net 443 --verb 4
첫 명령은 프록시가 목적지를 나른다는 것을 증명한다. 둘째는 클라이언트에 443의 TCP를 쓰라고 한다, 웹 전용 경로 대부분이 실제로 넘겨 주는 유일한 전송이다. 첫째가 성공하고 둘째가 여전히 실패하면 프록시는 장애물이 아니다.
일부 클라이언트는 덮어쓰기 대신 운영체제 프록시를 읽고, 일부는 둘 다 읽지 않는다. 시스템 전체 설정이 적용된다고 가정하기 전에 애플리케이션 자체 문서를 확인하세요. 프록시가 서비스하지 않는 리졸버로 엔드포인트를 푸는 클라이언트도 여기서 실패한다, 그래서 DNS 변경이 단지 우회인데도 해결책처럼 보일 수 있다.
유도 패턴도 보세요. 필터링된 네트워크는 공급업체의 탐지 호스트명에 자기 무언가로 응답할 수 있고, 그러면 클라이언트가 고르는 프록시 프로필이 바뀐다. 그 기벽에 절차를 세우지 마세요. 사이트마다 다르고 예고 없이 바뀌며 남을 위해 지원할 수 있는 것이 아니다.
포트 443은 도달 가능한 것이지 허용된 것이 아니다
443에서 터널을 TLS로 감싸는 것은 도달성만 푼다. 포트를 검사하는 필터는 통과시키지만 핸드셰이크 지문을 보는 필터는 통과시키지 않는다. 암호화 클라이언트 헬로가 서버 이름을 숨기는 것은 양쪽이 지원할 때뿐이다, 기대하는 대신 시험을 돌려 자신이 어떤 필터 뒤에 있는지 알아내세요.
나중에 알게 되는 성능 비용도 있다. 신뢰할 수 있는 전송 안의 신뢰할 수 있는 전송은 손실을 증폭한다, 안쪽 스택이 바깥쪽 스택이 이미 재전송한 세그먼트를 다시 보내기 때문이다. 깨끗한 링크에서는 아무도 모른다. 혼잡한 캠퍼스 무선에서는 필요한 바로 그때 터널이 쓸 수 없게 되고, 일부러 버리는 것이 없는데도 그래프는 패킷 손실처럼 보인다.
UDP가 보통 첫 희생자이며, 추정보다 확인이 낫다. TCP 443이 작동하는데 WireGuard나 기본 OpenVPN이 핸드셰이크를 끝내지 못하면 네트워크가 UDP를 버리는 것이고, 키를 다시 만들어도 바뀌지 않는다:
sudo wg show
dig +short vpn.example.net
dig +short vpn.example.net @1.1.1.1
어제 작동하던 피어 옆에 비어 있는 핸드셰이크 시각이 UDP의 답이다. 두 DNS 질의는 다른 질문에 답한다, 로컬 리졸버와 공개 리졸버가 엔드포인트 주소에 대해 어긋나면 당신은 유도되고 있고, 전송 논거가 틀린 것이다.
머신에서 실제로 무엇이 나갔는지 확인하세요
클라이언트 로그는 클라이언트가 믿는 것을 적는다. 캡처는 네트워크가 본 것을 적는다, 이 둘의 차이가 이런 사례 대부분이 풀리는 지점이다:
sudo tcpdump -ni any -c 20 'tcp port 443 and host 203.0.113.10'
sudo ss -tunp | grep -E ':(443|1194|51820)\b'
SYN 패킷은 보이고 SYN-ACK가 없으면 차단은 상류에 있고 클라이언트는 결백하다. 서버의 것이 아닌 주소로 완료된 핸드셰이크가 보이면 프록시나 가로채는 자와 이야기하는 것이다. 아무것도 보이지 않으면 결론을 내리기 전에 올바른 인터페이스에서 캡처했는지 확인하세요.
소켓 목록은 더 미묘한 경우를 잡는다, 기본 경로를 이미 쥐고 있는 두 번째 터널이다. 라우팅 테이블을 다투는 두 클라이언트는 차단된 네트워크와 똑같아 보이는 간헐적 실패를 만들고, 캡처는 예상하지 못한 인터페이스로 나가는 트래픽을 보여 줄 것이다.
되돌리기, 그리고 남길 만한 메모
변경을 만든 역순으로 되돌리세요. 프록시 변수를 해제하고, 손으로 시작한 클라이언트를 멈추고, 추가한 경로나 리졸버 덮어쓰기를 제거하세요:
unset https_proxy http_proxy
sudo systemctl stop openvpn-client@corp
sudo ip route show default
손으로 시작한 클라이언트를 켜 둔 채 두는 것이 다음 사무실 방문에서 노트북이 망가진 네트워크를 안고 가는 이유다. 셸 프로필에 남긴 프록시 변수는 몇 주 뒤 무관한 도구를 망가뜨리고, 그것을 디버그하는 사람은 두 사건을 연결하지 못한다.
그다음 네 줄을 쓰세요, 네트워크, 시각, 실패한 단계, 본 발급자. 한 캠퍼스에서 되고 다음에서 실패하는 경로는 정상이며, 다음 사람은 차이가 프록시인지 리졸버인지 필터인지 알아야 한다. 답이 네트워크가 원격 접속을 금지한다는 것이면, 거기서 멈추고 읽지 않은 정책에 우회를 들고 가는 대신 관리자에게 지원되는 경로를 물으세요.