VPN 컨테이너의 DNAT: INPUT이 아니라 포워딩
DNAT 이후 터널 주소로 가는 요청은 포워딩된 트래픽이 됩니다. 포워딩 규칙을 좁히고 Docker 체인을 읽고 반환 경로를 의도적으로 고르십시오.
요청은 터널 IP 주소로 도착하고 같은 컨테이너에서 이웃 서비스 주소로 떠납니다. 그 두 순간 사이에 DNAT가 목적지를 다시 썼고, 패킷은 VPN 컨테이너의 입력이 아니게 되었습니다. 이제 그것은 다른 규칙으로 판정되는 포워딩 트래픽입니다. 이 변화가 터널 주소에 맞아 보이는 방화벽 규칙이 변환된 연결에 효과가 없는 이유를 설명합니다.
변환 후 패킷을 따라가기
클라이언트 풀 10.90.0.0/24와 터널 주소 10.90.0.1을 생각합니다. 두 컨테이너가 하나의 브리지에 있고, 192.0.2.2가 VPN을, 192.0.2.3이 애플리케이션을 실행합니다. 클라이언트가 10.90.0.1:8080에 연결하면 VPN 컨테이너의 네임스페이스에 있는 DNAT 규칙이 이를 애플리케이션의 실제 주소와 포트로 다시 씁니다. 그다음 라우트가 패킷을 브리지 너머로 보냅니다. 이 주소들은 예시이며 배포 절차가 아닙니다.
애플리케이션이 실제로 수신하는 포트는 호스트에 게시된 어떤 포트와도 다를 수 있습니다. 두 숫자가 같다고 가정하지 말고 컨테이너 안의 수신자를 읽으십시오.
허가는 포워딩 경로에 속한다
VPN 컨테이너에는 IP 포워딩과 클라이언트 풀, 애플리케이션 주소, 의도한 포트로 좁힌 포워딩 결정이 필요합니다. 설정된 응답에는 자체 허가가 필요합니다. 원래 터널 주소와 일치하는 규칙은 DNAT 이후 일치하지 않습니다. 목적지가 이미 바뀌었기 때문입니다. INPUT 허가는 더 이상 이 호스트로 향하지 않는 트래픽에 잘못된 고리입니다.
범위를 좁게 유지하십시오. 소스 범위 하나, 목적지 하나, 서비스 하나. 관대한 포워딩 규칙은 쓰기 쉽고 나중에 방어하기는 훨씬 어렵습니다.
docker exec vpn-container ip route get 192.0.2.3
docker exec vpn-container iptables -t nat -S
docker exec vpn-container iptables -S FORWARD
Docker의 체인은 당신 컨테이너의 체인이 아니다
컨테이너 네임스페이스 안의 규칙은 Docker 호스트의 규칙이 아닙니다. 트래픽이 터널 인터페이스에서 브리지로 넘어갈 때 호스트의 브리지 방화벽이 다른 결정을 내릴 수 있습니다. Docker의 iptables 백엔드에서 문서화된 포워딩 체인과 DNAT 이후 일치 지점이 그 결정이 나타나는 곳입니다.
Docker 방화벽 참조는 그 체인과 DNAT 이후 일치를 설명합니다. Docker의 방화벽 관리를 끄거나 모든 체인을 관대하게 만들어 빠진 허용을 고치지 마십시오. 사용하려는 경계가 사라집니다.
반환 경로를 의도적인 선택으로 만들기
소스 주소가 보존되면 애플리케이션은 10.90.0.x를 보고 응답을 VPN 컨테이너를 통해 되돌려 보내야 합니다. 그렇지 않으면 일반 Docker 게이트웨이가 응답을 터널을 소유하지 않은 호스트로 보냅니다. 대안은 VPN 컨테이너에서 소스를 좁게 변환하는 것이며, 응답은 단순해지지만 애플리케이션에서 클라이언트가 보이지 않습니다. 의도적으로 고르고 어느 쪽을 골랐는지 적어 두십시오.
일반 클라이언트에서 새로 허용된 연결을 시험한 뒤 관련 없는 포트가 닫혀 있는지 확인합니다. 패킷이 사라지면 VPN 네임스페이스, 애플리케이션 네임스페이스, 애플리케이션 자체 로그를 살펴보십시오. 브리지 게이트웨이로의 ping은 서비스의 인수 시험이 아닙니다.
규칙은 컨테이너의 지원되는 시작 구성에 두십시오. 대화형 편집은 다시 만들 때 사라집니다. 호스트 포트 게시는 다른 노출 경로이며 서비스가 터널로 도달 가능하다는 이유만으로 필요한 것은 아닙니다.