지정한 URL과 관계없이 curl이 localhost로 연결을 시도한다면, VPN은 시작할 곳이 아닙니다. 로컬 HTTP 또는 SOCKS 프록시가 의도된 첫 연결일 수 있으며, 원하는 서비스가 완전히 다른 곳에 있어도 마찬가지입니다. 그 프록시가 더 이상 실행되지 않으면 curl이 목적지에 도달하기 전에 localhost 시도가 실패합니다. 프록시의 응답도 목적지가 응답했다는 증거가 아닙니다.

다음 단계를 순서대로 진행하고 첫 연결 시도를 바꾸는 첫 단계에서 멈추세요.

먼저 curl 자체의 프록시 규칙을 읽으세요

curl은 프로토콜별 프록시 변수를 읽습니다. 예를 들어 https_proxy 와 HTTPS_PROXY, 그리고 프로토콜별 값이 적용되지 않을 때는 ALL_PROXY 입니다. curl을 실제로 실행하는 셸, 서비스, 작업의 환경을 확인하고 현재 터미널의 환경을 보지 마세요. CI 작업, systemd 유닛, 대화형 셸은 각각 다른 집합을 상속할 수 있습니다. 눈에 보이는 셸에서 추측하는 것이 이 조사에서 반나절을 낭비하는 이유입니다.

기억해 둘 만한 예외가 하나 있습니다. curl은 http_proxy 를 소문자로만 받아들이고, 대문자 HTTP_PROXY 는 무시합니다. 그래서 같은 환경이라도 다른 도구에서는 다르게 동작합니다.

값은 노출되지 않게 읽으세요. 프록시 URL은 종종 자격 증명을 담고 있습니다.

그다음 curl의 기본 설정 파일에 프록시나 연결 재정의가 있는지 확인하고, 실제로 어떤 실행 파일을 돌리고 있는지 확인하세요. 셸 별칭, 함수, 래퍼 스크립트는 명령줄에는 절대 나타나지 않는 옵션을 추가할 수 있습니다.

TLS를 켠 채로 세 호출을 비교하세요

세 번의 실행 모두에 승인된 진단 대상 하나와 같은 바이너리를 사용하세요.

curl -v https://service.corp.example/status
curl -q -v https://service.corp.example/status
curl -q --proxy '' -v https://service.corp.example/status

-q 기본 curlrc를 억제하며 동작하려면 줄의 첫 번째 매개변수여야 합니다. 프록시 환경 변수는 제거하지 않는데, 바로 그걸 기대하는 사람을 놀라게 합니다. 세 번째 형태는 빈 --proxy 값을 더해 그 호출에 한해 환경이 요청한 프록시를 재정의합니다. 최종 상태 코드가 아니라 각 출력의 첫 연결 시도를 비교하세요.

자세한 출력은 헤더, 토큰, 프록시 자격 증명을 노출할 수 있으므로 로컬에 보관하고 공유 전에 발췌를 읽으세요.

각 결과가 배제하는 것

기본 설정을 생략했을 때 연결이 바뀌면 설정 파일이 원인입니다. 상속된 프록시를 명시적으로 끄면 바뀐다면 환경 변수가 원인입니다. 둘 다 바꾸지 않는데 localhost가 여전히 나타난다면 명령줄의 연결 재정의, 호스트 이름 확인, 선택된 실행 파일을 보세요. 각각 고치는 방법이 다르고, 어느 것도 라우팅 변경이 아닙니다.

사용자 라이브러리 로딩이나 주입된 네트워크 동작은 이후 계층이며, 환경 변수 하나만으로는 그 증거가 되지 않습니다.

프록시 결정은 VPN과 분리해 두세요

curl이 직접 대상을 고른 뒤에도 운영 체제는 그 연결을 계속 라우팅합니다. 애플리케이션 프록시를 끈다고 VPN의 경로나 필터링 정책이 꺼지지는 않습니다. 직접 접근 비교는 그 진단이 허용된 곳에서만 하세요. 정책을 조용히 우회하는 시험은 유효한 결과가 아니라 사고입니다.

로컬 프록시가 필요하다면 설정을 지우는 대신 서비스와 주소를 복구하세요.

선택된 사설 대상만 직접 접근이 필요하다면 좁게 승인된 예외를 추가하고 나머지 모두에는 프록시를 유지하세요. 고른 경로의 첫 오류를 보존하세요. localhost 거부, 프록시 CONNECT 거부, 인증서 실패, 권한 오류는 서로 다른 네 단계를 가리킵니다.

관련 글