Docker 컨테이너는 iptables를 사용하여 프록시를 사용합니다.

Docker 컨테이너는 iptables를 사용하여 프록시를 사용합니다.

두 개의 VPS가 있는데, 첫 번째 머신(대리인지금부터) 에이전트와 두 번째 머신(교각지금부터)는 도커 호스트입니다. Docker 컨테이너 자체 내부에서 생성된 모든 트래픽을 다음으로 리디렉션하고 싶습니다.대리인, 노출되지 않음교각머신 공용 IP.

VPS 간의 연결은 인터넷을 통해 이루어지기 때문에 로컬 연결이 없으므로 VPS 사이에 터널이 생성됩니다.IP 터널다음과 같이:

존재하다대리인:

ip tunnel add tun10 mode ipip remote x.x.x.x local y.y.y.y dev eth0
ip addr add 192.168.10.1/24 peer 192.168.10.2 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

존재하다교각:

ip tunnel add tun10 mode ipip remote y.y.y.y local x.x.x.x dev eth0
ip addr add 192.168.10.2/24 peer 192.168.10.1 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

추신 : 거기에 있는지 모르겠습니다IP 터널프로덕션에서 사용할 수 있습니다. 그것은 또 다른 질문입니다. 어쨌든 사용하려는 의도입니다.리브레스완또는오픈VPNVPS 간 터널 역할을 합니다.

그런 다음 아래와 같이 두 VPS의 iptables에 SNAT 규칙과 일부 라우팅 규칙을 추가합니다.

존재하다대리인:

iptables -t nat -A POSTROUTING -s 192.168.10.2/32 -j SNAT --to-source y.y.y.y

존재하다교각:

iptables -t nat -A POSTROUTING -s 172.27.10.0/24 -j SNAT --to-source 192.168.10.2
ip route add default via 192.168.10.1 dev tun10 table rt2
ip rule add from 192.168.10.2 table rt2

마지막으로 도커 네트워크를 생성하고 다음과 같이 테스트 컨테이너를 연결합니다.

docker network create --attachable --opt com.docker.network.bridge.name=br-test --opt com.docker.network.bridge.enable_ip_masquerade=false --subnet=172.27.10.0/24 testnet
docker run --network testnet alpine:latest /bin/sh

불행히도 이 중 어느 것도 성공하지 못했습니다. 그렇다면 문제는 디버깅 방법입니다. 이것이 올바른 접근 방식입니까? 프록시를 통해 어떻게 리디렉션하시겠습니까?

이론에 대한 몇 마디: 172.27.10.0/24 서브넷의 트래픽이 iptables SNAT 규칙에 도달하고 소스 IP가 192.168.10.2로 변경됩니다. 라우팅 규칙을 통해 터널인 tun10 장치를 통해 라우팅됩니다. 그리고 또 다른 iptables SNAT 규칙에 도달하고 IP를 yyyy로 변경한 후 마침내 대상에 도달합니다.

답변1

Docker 머신의 공용 IP가 노출되지 않도록 Docker 컨테이너 내부에서 생성된 모든 트래픽을 프록시를 통해 리디렉션하고 싶습니다.

이것이 원하는 경우 두 Docker 인스턴스 간에 NAT가 필요하지 않습니다.

proxy인스턴스에서 전달을 활성화 해야 합니다 (예: sysctl을 통해).

공용 IP가 다음과 같은 proxy경우보이는inside 인 경우 SNAT inside(내부 아님) proxy에 해당 공용 IP만 사용해야 합니다. 이것을 가면무도회라고도 합니다. 이것은 표준 설정인 Google 검색 "masquerade"입니다.proxydock

공용 IP가 다음과 같은 proxy경우보이지 않는호스트(또는 위의 다른 호스트)가 NAT를 수행하므로 이중 proxyNAT 를 피하고 호스트를 다른 컨테이너처럼 보이게 만들어야 합니다 . 세부 사항은 호스트에서 네트워크가 어떻게 설정되어 있는지에 따라 다르지만(말하지 않았음) 기본적으로 터널 끝은 호스트의 컨테이너와 동일한 서브넷에 IP 가 있어야 합니다 .ip addrproxydockdockproxy

터널은 ipip암호화되지 않습니다. 전송이 완전히 신뢰할 수 있는 네트워크 내에서 이루어지지 않는 한(다른 공용 IP 주소가 필요한 것처럼 보이기 때문에 그렇지 않을 수도 있음) 이 터널을 사용해서는 안 됩니다. 따라서 OpenVPN다음과 같은 대안을 사용하거나 설정하기 쉽습니다.딩크. Libreswan설정하기가 그리 쉽지는 않습니다.

편집하다

단계별:

1) 터널이 제대로 작동하는지 확인합니다. 올라가서 proxy해보세요 ping 192.168.10.2. 올라가서 dock해보세요 ping 192.168.10.1. tcpdump액세스할 수 있는 모든 중간 네트워크 인터페이스를 디버그합니다 . ipip-tunnel이 작동하지 않으면 다른 터널을 사용하여 작동하게 만드세요.

2) 모든 iptables규칙을 삭제합니다 dock. 터널을 통과하는 기본 경로를 설정합니다. ip route get 8.8.8.8경로가 작동하는지 테스트합니다 .

3) eth0proxy공용 IP가 있다고 가정하고 모든 iptables규칙을 삭제한 후 다음을 실행합니다.

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o tun10 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -o eth0 -i tun10 -j ACCEPT

eth0이는 "패킷을 전달하고, 공용 IP 주소를 소스 주소로 사용하여 전달된 모든 패킷을 위장하고 eth0연결이 이를 추적합니다. 의 패킷은 tun10항상 으로 전달될 수 있으며 , 들어오는 패킷은 연결이eth0 통과 하도록 설정된 경우에만 전달됩니다 ." 를 의미합니다.eth0tun10dock

ping 8.8.8.8에서 실행 하고 동시에 dock실행하여 테스트합니다 . 패킷이 전달되고 소스가 다시 작성되는 것을 볼 수 있습니다.tcpdumptun10eth0proxy

4) 모든 것이 작동하면 영구적으로 만듭니다. 파일을 편집 하거나 /etc/sysctl.conf편집하여 시작 스크립트를 사용하여 규칙을 추가 하거나 배포판에서 제공하는 패키지를 사용하여 규칙을 저장합니다./etc/sysctl.dnet.ipv4.ip_forward = 1iptables

관련 정보