Tinyproxy의 Listen, Bind, BindSame: 어떤 주소가 이기는가
Listen은 클라이언트를 받는 주소를 고르고, Bind는 나가는 연결의 출발지를 고릅니다. 둘 다 경로를 설치하지 않으므로 경로는 따로 확인해야 합니다.
프록시가 응답하고 요청이 완료되는데도 목적지에는 여전히 LAN 주소가 기록된다. 프록시 로그에는 잘못된 것이 없어 보이고, 변경한 줄은 문서가 변경하라고 한 바로 그 줄이다. LAN 주소와 터널 주소를 모두 가진 호스트에서 세 지시문이 어느 주소가 어디에 나타나는지를 결정하며, 그중 나가는 쪽에 관한 것은 하나뿐이다. 순서를 잘못 읽으면 이유 없이 라우팅 테이블로 들어가게 된다.
증상: 목적지가 LAN 주소를 본다
클라이언트가 LAN 주소로 프록시에 접속하고, 프록시는 목적지로 자신의 연결을 연다. 그 두 번째 연결은 커널 규칙에 따라 출발지 주소를 고르며, 기본값은 경로 조회가 선택한 주소다. 그래서 모든 바이트가 프록시를 거쳤는데도 목적지에는 호스트의 기본 주소가 기록된다. 전달 측면에서는 아무것도 깨지지 않았고, 그래서 프록시 로그는 이 일에 대해 할 말이 없다.
그 결함의 거울상은 더 찾기 쉽다. 나가는 출발지를 터널 주소에 고정하면 LAN 클라이언트는 아예 리스너에 도달하지 못한다. 그 판본은 스스로를 알리지만, 첫 번째는 정상 동작하는 요청 뒤에 숨는다. 둘 다 하나의 지시문이 두 질문 모두에 답한다고 다루는 데서 나온다.
세 지시문, 세 가지 주소
Listen은 프록시 클라이언트를 받는 로컬 주소를 지정한다. Bind는 프록시가 바깥으로 여는 연결에 출발지 주소를 제공하고, BindSame은 방금 받은 연결의 로컬 주소를 다시 쓰라고 지시한다. 이들은 세 가지 별개의 질문이며, 한 줄은 그중 하나에만 답한다. 이들을 혼동하는 것이 변경이 아무 효과 없는 것처럼 보이는 흔한 이유다.
| What you observe | Check first |
|---|---|
| A client cannot connect at all | Listen: the local address the listener binds |
| The request works but the far side logs the LAN address | Bind: the outgoing source is not being applied |
| A configured Bind appears to have no effect | BindSame yes: the accepted local address overrides the Bind list |
| The lookup names the LAN interface | The route, not the proxy: the source cannot reach that destination |
설치된 버전과 함께 오는 주석이 달린 구성을 읽어 보라. 기본값과 허용되는 문법은 릴리스마다 달라진다. 프로젝트의 예시 구성은 각 지시문을 다른 것들과 나란히 문서화한다. 그 파일을 디스크에 있는 파일과 비교하고, 다른 배포판을 위해 쓰인 안내서와 비교하지는 말라.
리스너와 나가는 출발지를 따로 설정하라
LAN 주소가 192.168.50.10이고 터널 주소가 10.90.0.3인 호스트를 생각하자. LAN 클라이언트가 프록시에 도달하되 그 요청이 터널로 나가야 한다면, 이는 두 개의 독립적인 결정이며 둘 다 적어야 한다. 아래 조각은 정확히 그것만 표현한다.
Listen 192.168.50.10
Bind 10.90.0.3
BindSame no이것은 완전한 구성이 아니므로 승인된 포트, 인증, 클라이언트 접근 제어, 목적지 제한을 유지하라. 두 주소 모두 Tinyproxy의 네트워크 네임스페이스 안에서 이 호스트에 속해야 한다. 프로세스가 소유할 수 없는 Bind 값은 시작할 때가 아니라 연결할 때 실패하기 때문이다. BindSame yes는 다른 정책을 설명하며, 받아들인 연결의 로컬 주소가 나가는 출발지가 된다. 현재 릴리스에서는 그 분기가 Bind 목록보다 우선하며, 그렇게 설정한 출발지가 오류 없이 사라진다.
출발지가 함축하는 경로를 확인하라
출발지 주소를 고른다고 경로가 생기지는 않으므로, 그 출발지와 그 목적지로 커널이 무엇을 할지 물어보라. 터널 인터페이스를 지목하는 조회가 최소한의 증거이고, LAN 인터페이스를 지목한다면 그 출발지는 적힌 대로 동작할 수 없다. 조회는 맥락에 따라 그 네임스페이스에 유효한 정책 규칙과 테이블을 평가한다. 그것은 연결이 아니며, 하류의 NAT가 서비스에 무엇을 보여줄지에 대해서도 말하지 않는다.
ip -4 route get 203.0.113.25 from 10.90.0.3예시에서는 문서용 주소를 쓰고, 시험할 권한이 있는 서비스로 바꿔라. 프록시가 컨테이너에서 돌면 조회를 프록시의 네임스페이스 안에서 실행하라. 호스트의 규칙은 프로세스가 보는 규칙이 아니기 때문이다. 의도한 터널 경로가 없으면, 프록시 호스트에 목적지별 규칙을 더하는 대신 네트워크 소유자가 고치게 하라. 조회를 성공시키려고 호스트 경로를 지우거나 서버가 밀어주는 경로를 끄지 말라. 오래된 안내서가 그렇게 했더라도, 그런 변경은 프록시 경로 하나를 고치려고 호스트 전체의 승인된 VPN 동작을 옮긴다.
목적지에서 출발지를 확인하라
출발지는 요청이 나가는 곳이 아니라 도착하는 곳에서 읽어라. 목적지의 애플리케이션 로그나 그 앞의 엣지 장비가 실제로 본 주소를 기록하는 반면, 프록시는 의도만 말해 줄 수 있다. 변경 후 의도한 리스너를 통해 새 요청을 한 번 보내라. 캐시된 연결은 새 바인딩에 대해 아무것도 증명하지 않는다. 그다음 기록된 주소를 설정한 주소와 비교하라.
ss -ltnp | grep tinyproxy
curl -x http://192.168.50.10:8888 https://example.com -o /dev/null -sScurl은 트래픽 생성기일 뿐이다. 검증할 가치가 있는 주소는 먼 쪽이 기록한 주소이며, curl이 우연히 연결한 상대가 아니다. 둘이 다르면 그 차이가 출발지 선택에서 오는지 더 앞단의 변환에서 오는지 판단하라. 둘은 서로 다른 곳에서 고친다. 주소 변경과 프록시 재시작도 함께 계획하라. 터널이 더 이상 갖지 않는 주소를 바인딩하면 재접속 후 조용히 실패한다. DNS와 IPv6 동작도 따로 정의하라. 위의 IPv4 조각은 둘 중 어느 것도 증명하지 않는다.