我正在尝试在两个 Docker 容器之间实现 http 透明代理。
我安装了 squid 代理。我们称之为乌贼,还有另一个容器,我们称之为应用程序
我希望从 APP 请求的每个 http 连接都将通过 SQUID 容器
预期数据流为 APP ---> SQUID --->http://example.com--> SQUID --> 应用程序 --> 成功
通过使用 tcpdump,我可以证明我做了所有必要的配置正确,如果我使用 -x,我能够使用 curl 命令查看页面
通过 -x 证明 squid 正常工作
curl -x SQUID_IP:3128 -L http://www.example.com
此 curl 命令给出正确的输出。
tcpdump -i any host www.example.com
SQUID_IP
和之间的所有通信EXAMPLECOM_IP
。
14:02:04.213608 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [S], seq 2965828629, win 64240, options [mss 1460,sackOK,TS val 2305017503 ecr 0,nop,wscale 7], length 0
14:02:04.213608 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [S], seq 2965828629, win 64240, options [mss 1460,sackOK,TS val 2305017503 ecr 0,nop,wscale 7], length 0
14:02:04.213634 IP $LINUX_NAME.48808 > $EXAMPLECOM_IP..http: Flags [S], seq 2965828629, win 64240, options [mss 1460,sackOK,TS val 2305017503 ecr 0,nop,wscale 7], length 0
14:02:04.335400 IP $EXAMPLECOM_IP..http > $LINUX_NAME.48808: Flags [S.], seq 1004826113, ack 2965828630, win 65535, options [mss 1460], length 0
14:02:04.335454 IP $EXAMPLECOM_IP..http > $SQUID_IP.48808: Flags [S.], seq 1004826113, ack 2965828630, win 65535, options [mss 1460], length 0
14:02:04.335465 IP $EXAMPLECOM_IP..http > $SQUID_IP.48808: Flags [S.], seq 1004826113, ack 2965828630, win 65535, options [mss 1460], length 0
14:02:04.335595 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [.], ack 1, win 64240, length 0
14:02:04.335595 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [.], ack 1, win 64240, length 0
14:02:04.335627 IP $LINUX_NAME.48808 > $EXAMPLECOM_IP..http: Flags [.], ack 1, win 64240, length 0
14:02:04.336027 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [P.], seq 1:200, ack 1, win 64240, length 199: HTTP: GET / HTTP/1.1
14:02:04.464797 IP $EXAMPLECOM_IP..http > $LINUX_NAME.48808: Flags [P.], seq 1:1421, ack 200, win 65535, length 1420: HTTP: HTTP/1.1 200 OK
14:02:04.464871 IP $EXAMPLECOM_IP..http > $SQUID_IP.48808: Flags [P.], seq 1:1421, ack 200, win 65535, length 1420: HTTP: HTTP/1.1 200 OK
14:02:04.464888 IP $EXAMPLECOM_IP..http > $SQUID_IP.48808: Flags [P.], seq 1:1421, ack 200, win 65535, length 1420: HTTP: HTTP/1.1 200 OK
14:02:04.465051 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [.], ack 1421, win 63900, length 0
14:02:04.465051 IP $SQUID_IP.48808 > $EXAMPLECOM_IP..http: Flags [.], ack 1421, win 63900, length 0
14:02:04.465109 IP $LINUX_NAME.48808 > $EXAMPLECOM_IP..http: Flags [.], ack 1421, win 63900, length 0
14:02:04.465879 IP $EXAMPLECOM_IP..http > $LINUX_NAME.48808: Flags [P.], seq 1421:1614, ack 200, win 65535, length 193: HTTP
squid 访问日志
1581166924.466 253 $APP_IP TCP_MISS/200 1751 GET http://www.example.com/ - HIER_DIRECT/$EXAMPLECOM_IP text/html
透明代理部分
我想创建没有 -x 或环境变量的相同行为。
我在虚拟机中编写的Iptables规则
iptables -t nat -I PREROUTING 1 -s $APP_IP -p tcp --dport 80 -j DNAT --to-destination $PROXY_IP:3128
PS:Docker 一开始就写了一些规则,所以我总是将我的 iptables 规则写到顶部。
失败
不带 -X 的 Curl 命令
curl http://www.example.com/
tcpdump 输出显示我的 APP_IP 到达了 $EXAMPLECOM_IP
tcpdump -i any host www.example.com
APP_IP
tcpdump 显示和之间进行通信,这很奇怪EXAMPLECOM_IP
。
14:10:27.069971 IP $APP_IP.36286 > $EXAMPLECOM_IP.http: Flags [S], seq 2733675015, win 64240, options [mss 1460,sackOK,TS val 3465975630 ecr 0,nop,wscale 7], length 0
14:10:27.070010 IP $EXAMPLECOM_IP.http > $APP_IP.36286: Flags [S.], seq 121743720, ack 2733675016, win 65160, options [mss 1460,sackOK,TS val 3186379669 ecr 3465975630,nop,wscale 7], length 0
14:10:27.070019 IP $APP_IP.36286 > $EXAMPLECOM_IP.http: Flags [.], ack 1, win 502, options [nop,nop,TS val 3465975630 ecr 3186379669], length 0
14:10:27.070145 IP $APP_IP.36286 > $EXAMPLECOM_IP.http: Flags [P.], seq 1:80, ack 1, win 502, options [nop,nop,TS val 3465975630 ecr 3186379669], length 79: HTTP: GET / HTTP/1.1
14:10:27.070159 IP $EXAMPLECOM_IP.http > $APP_IP.36286: Flags [.], ack 80, win 509, options [nop,nop,TS val 3186379669 ecr 3465975630], length 0
14:10:27.070297 IP $EXAMPLECOM_IP.http > $APP_IP.36286: Flags [P.], seq 1:3887, ack 80, win 509, options [nop,nop,TS val 3186379669 ecr 3465975630], length 3886: HTTP: HTTP/1.1 400 Bad Request
14:10:27.070348 IP $EXAMPLECOM_IP.http > $APP_IP.36286: Flags [F.], seq 3887, ack 80, win 509, options [nop,nop,TS val 3186379669 ecr 3465975630], length 0
Squid 日志和错误
1581168827.687 0 $APP_IP NONE/400 3886 GET / - HIER_NONE/- text/html
<p>The following error was encountered while trying to retrieve the URL: <a href="/">/</a></p>
这证明我的 iptables 规则路由流量,但是?
问题
SQUID
和之间的正确 iptables 应该是什么APP
才能使其表现得像透明代理。
信息说明
我写的没有额外的 iptables 规则,所有规则都在这里
iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-N NO_PROXY
-A PREROUTING -s 172.17.0.2/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.3:3128
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
iptables -t filter -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
export SQUID_IP=172.17.0.3
export APP_IP=172.17.0.2