VPN 출구 뒤에서 포트 스캔 결과가 왜 달라질까?
출구를 바꾸면 서비스가 움직이지 않아도 포트가 다르게 응답할 수 있습니다. 경로 관찰과 실제로 필요한 목록을 분리하세요.
같은 포트 점검을 사무실 회선과 VPN 출구에서 실행하면, 아무도 바꾸지 않은 주소에 대해 두 답이 어긋날 수 있습니다. 그 차이는 경로와 어느 호스트가 응답했는지에서 오며, 서비스가 켜져 있는지와는 무관합니다. 세 가지 질문이 그 설명을 나눕니다. 점검이 실제로 무엇을 물었는지, 어느 호스트가 답했는지, 그리고 여러분의 서버가 무엇을 기록했는지입니다. 이 순서로 확인하고 다음으로 넘어가기 전에 각 답을 적어 두세요.
두 실행을 비교하기 전에 점검을 바로잡으세요
상태 단어는 둘 다 같은 실험에서 나왔을 때만 다른 상태 단어와 비교할 수 있습니다. 다섯 가지 항목이 그것을 고정합니다. 먼 쪽이 본 출발지 주소, 해석된 목적지, 포트, 스캔 종류, 그리고 시각입니다. 이 중 하나라도 바꾸면 첫 실험을 두 번 측정한 것이 아니라 두 번째 실험을 한 것입니다.
VPN 클라이언트가 켜져 있어도 트래픽은 여전히 물리 인터페이스로 나갈 수 있으므로 무엇보다 먼저 출발지를 확인하세요. 그런 다음 먼 쪽에 무엇이 보이는지 묻고, 커널에 어느 인터페이스를 골랐는지 물으세요:
curl -s https://ifconfig.me
ip route get 203.0.113.20서로 다른 네트워크의 두 주소는 설명이 이미 손에 있다는 뜻이며, 나머지 점검은 그것을 확인해 줄 뿐입니다. 둘이 일치하면 이유 플래그를 켠 채로 점검을 기록해, 상태가 벌거벗은 단어로 홀로 서지 않고 설명에 묶여 돌아오게 하세요. 스캔 종류도 그 기록에 속하는데, 무엇이 돌아왔는지가 아니라 무엇을 물었는지를 설명하기 때문입니다. 출발지도 방법도 시각 표시도 없는 상태는 무엇과도 비교할 수 없습니다:
nmap -sT -p 443,8443 --reason 203.0.113.20그 출력은 다음 사람이 볼 수 없는 스크롤백 버퍼가 아니라 기록 옆에 두세요. 서로 어긋나는 두 정직한 스캔은 아무도 조건을 적어 두지 않았을 때만 논쟁이 됩니다. 조건이 고정되면 결과가 일치해 질문이 닫히거나, 결과가 다르고 그 차이가 경로에 관한 사실이 됩니다.
어느 호스트가 핸드셰이크를 끝냈는지 알아내세요
완료된 핸드셰이크는 어느 호스트가 그것을 완료했음을 증명하며, 그 호스트가 여러분이 생각하는 프로세스일 필요는 없습니다. 로드 밸런서, 리버스 프록시, SYN 프록시는 실제 서버가 관여하기 전에 응답할 수 있으며, 이는 증상이 아니라 평범한 설계입니다. 기대한 이름에 대한 유효한 인증서도 이것을 좁히지 않습니다. 인증서는 서비스 관계를 설명할 뿐 어느 기계가 연결을 끝냈는지는 말하지 않기 때문입니다.
Nmap 포트 상태 참조는 이것을 기본으로 봅니다. 상태는 점검이 보낸 위치에서 무엇을 관찰할 수 있었는지를 기록하는 것이지 포트의 속성이 아닙니다. 상태 단어를 그렇게 읽으면 서로 어긋났던 두 실행이 모순이 아니라 일관되게 보이기 시작하고, 질문은 포트가 열려 있는지에서 그 앞에 누가 서 있었는지로 옮겨 갑니다.
두 번째 질문에는 바깥이 아니라 백엔드에서 답하세요. 연결을 받아들인 뒤 업스트림에 닿지 못하는 프런트엔드는 느린 애플리케이션을 가진 건강한 서비스의 외부 모습을 그대로 만들어 냅니다. 업스트림 자체의 기록만이 두 경우를 구분합니다:
tail -n 5 /var/log/nginx/access.log
ss -ltnp 'sport = :443'로그 줄은 애플리케이션이 실제로 본 클라이언트 주소를 보여 주고, 두 번째 명령은 포트 443을 쥐고 있는 프로세스가 여러분의 애플리케이션인지 그 앞의 무언가인지를 보여 줍니다. 둘이 어느 주소가 연결되었는지에 대해 어긋난다면, 여러분은 한 요청의 두 다리를 보고 있는 것이며 티켓은 그렇게 적어야 합니다.
터널을 탓하기 전에 자신의 규칙을 확인하세요
의도된 정책은 포트가 한 네트워크에서는 응답하고 다른 네트워크에서는 응답하지 않는 가장 흔한 이유이며, 이용 가능한 설명 중 가장 흥미롭지 않은 것입니다. 접근 규칙은 한 출발지를 허용하고 나머지를 버리기 위해 존재하므로, 출구의 변화는 바로 그 규칙이 쓰인 사건입니다. 따라서 VPN을 통한 다른 상태는 제공자가 트래픽을 검사한다는 것을 보여 주지 않습니다. 그것은 출발지 주소가 이제 다르다는 것을 보여 줄 뿐이며, 훨씬 작은 주장입니다.
그 규칙은 서버에서 읽을 수 있으니 네트워크 중간을 추측하는 대신 읽어 보세요. 두 주소 범위 중 하나라도 언급하는 필터 규칙을 나열하고, 그다음 연결이 데몬에 도달하기는 했는지 확인하세요:
nft list ruleset | grep -n -e 203.0.113 -e 198.51.100
journalctl -u sshd -n 50 | grep 203.0.113두 번째 결과가 비어 있다는 것은 정보가 됩니다. 데몬에 아무것도 도달하지 않았고 질문은 필터, 보안 그룹 또는 경로 자체에 속하기 때문입니다. 적중은 서비스가 여러분의 출발지를 보고 자기 답을 골랐다는 뜻이며, 그 결정은 보통 읽을 수 있는 규칙에 적혀 있습니다. 어느 결과도 제공자에 관한 이야기를 뒷받침하지 않으며, 둘 다 패킷 캡처보다 싸게 확인할 수 있습니다.
전송, 인증서, 응답을 따로 읽으세요
세 계층이 세 관찰을 만들어 내고, 그중 하나를 시험하는 점검은 나머지 둘에 대해 보고할 수 없습니다. 하나의 판결로 접지 말고 기록에서 별도의 줄로 유지하세요. 각 줄은 저마다의 방식으로 실패하며, 실패 방식이 다음에 어디를 봐야 하는지 알려 주기 때문입니다.
| Observation | What it settles | What it leaves open |
|---|---|---|
| Connection completed | A host on the path accepted the handshake | Which host, and whether its upstream is reachable |
| Certificate valid for the name | The endpoint holds a credential for that name | Whether the process behind it is the one you meant |
| Expected response body | The application handled the request | Anything about other ports or other paths |
| Connection refused | A host replied and nothing was listening | Whether a filter sits ahead of the refused port |
| Timeout | No reply arrived before the deadline | Drop, blackhole route or an overloaded host |
명령 하나가 여러분이 통제하는 서비스에 대해 처음 세 줄을 만들어 냅니다. 그 출력은 채팅 메시지가 아니라 스캔 옆의 기록에 두세요:
curl -v --resolve office.example:443:203.0.113.20 https://office.example/출력을 순서대로 읽으세요. 핸드셰이크는 전송 질문에, 인증서 주체는 이름 질문에, 응답 본문은 애플리케이션 질문에 답합니다. 핸드셰이크 줄은 성공하고 응답 줄은 실패한다면, 막힌 포트가 아니라 업스트림이 깨진 프런트엔드를 가진 것입니다. 그것은 여러분이 연 티켓과 다른 티켓이며, 분명히 말할 가치가 있습니다.
티켓에 네 가지 사실을 적어 끝내세요. 출발지 주소, 스캔 종류, 응답한 호스트, 그리고 시각입니다. 나중 비교에 필요한 모든 것은 그 네 가지 안에 살고, 다음에 사건을 맡는 사람은 여러분의 터미널 기록을 갖지 못합니다. 네 가지를 모두 채울 수 없다면 그 실행은 끝난 것이 아닙니다.