我正在尝试创建一个透明代理来缓存和黑名单我自制的 Linux 路由器上的流量。问题是所有客户端在尝试访问任何 HTTP 站点时都会超时(HTTPS 可以工作)。
这是我的设置:
系统:Ubuntu 16.04
代理人:Squid 3.5.12
iptables:
- 相关规则:
-A PREROUTING -i wlx30b5c21224f3 -p tcp --dport 80 -j REDIRECT --to-port 9999
- 整个规则集:
https://pastebin.com/HtzTmYMp
乌贼:
- 相关规则:
http_port 192.168.99.1:8888
http_port 192.168.99.1:9999 intercept
- 整个配置:
https://pastebin.com/Ft2f3uaD
接口:
- 互联网 - enp1s0(以太网)
- 本地网络 - wlx30b5c21224f3(无线)
网络:
- 网络地址 - 192.168.99.0/24
- 网关、DNS、Squid - 192.168.99.1
鱿鱼日志:
- Access.log - 空
- Cache.log -https://pastebin.com/AQ6VFdNP
通过查看活动进程,我可以知道 squid 正在工作并且正在监听分配的端口。
结果netstat -tulpn | grep squid
:
tcp 0 0 192.168.99.1:9999 0.0.0.0:* LISTEN 2604/(squid-1)
tcp 0 0 192.168.99.1:8888 0.0.0.0:* LISTEN 2604/(squid-1)
udp 0 0 0.0.0.0:35057 0.0.0.0:* 2604/(squid-1)
udp6 0 0 :::50319 :::* 2604/(squid-1)
在尝试连接到某个客户端上的 HTTP 站点时,通过观察流量,我还可以知道 iptables 规则将流量从端口 80 重定向到 9999。
结果watch 'iptables -t nat -L -n -v'
:https://pastebin.com/wdRjnBDa
当我尝试访问该站点时,通过 iptables 规则的字节数不断增加 - 但客户端仍然超时。
因此,我的理论是,iptables 正确地重定向了流量,并且 squid 正在监听正确的端口,但我忽略了某些东西,导致流量无法到达 Squid。(因为 Squid 日志或多或少是空的)
我尝试了在线各种 Squid 指南中找到的大量不同的 iptables 规则 - 其中大多数都产生与上述相同的结果。我还尝试了 Squid 中的许多不同端口,并尝试从中删除 ip 地址http_port 192.168.99.1:9999
- 但这导致 squid 仅在 ipv6 上监听(我不确定这会如何影响 iptables 重新路由)。
PS. 这是我的第一个网络项目,所以我可能会遗漏一些不为人知的东西。
答案1
确保您打开或拥有用于反向代理的另一个 http_port:
SSL 之所以有效是因为它不经过 squid。在这个例子中,您也可以拦截它(第一行是您所需要的):
http_port 3130
http_port 3128 intercept
https_port 3129 intercept ssl-bump \
cert=/etc/squid/certs/squidCA.pem \
generate-host-certificates=on dynamic_cert_mem_cache_size=4MB
iptables:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 3128
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0
答案2
假设你的脚本中有基本的 iptables 规则(例如 LOOPBACK、Global、MASQUERADE 等)
变量:
# local network interface (for computers on the local network)
lan=wlx30b5c21224f3
# external network interface (output to the internet)
internet=enp2s0
PD:将变量的值更改为网络接口的名称。要找出网络接口的名称,请运行以下命令:
ip -o link | awk '$2 != "lo:" {print $2, $(NF-2)}' | sed 's_: _ _'
iptables 规则:
iptables -t nat -A PREROUTING -i $lan -p tcp --dport 80 -j REDIRECT --to-port 9999
iptables -A INPUT -i $lan -p tcp --dport 9999 -j ACCEPT
iptables -A FORWARD -i $lan -p tcp -m multiport --dports 443,9999 -o internet -j ACCEPT
但是如果 squid 中有两个指令(透明 9999 和非透明 8888),我建议您创建不同的列表,以便每个列表都指向您想要的指令。例如:
# send list of mac addresses to directive > http_port 192.168.99.1:8888
for mac in $(cat mac-proxy.txt); do
iptables -t mangle -A PREROUTING -i $lan -p tcp --dport 8888 -m mac --mac-source $mac -j ACCEPT
iptables -A INPUT -i $lan -p tcp --dport 8888 -m mac --mac-source $mac -j ACCEPT
iptables -A FORWARD -i $lan -p tcp --dport 8888 -m mac --mac-source $mac -j ACCEPT
done
# send list of mac addresses to directive > http_port 192.168.99.1:9999 intercept
for mac in $(cat mac-transparent.txt); do
iptables -t nat -A PREROUTING -i $lan -p tcp --dport 80 -m mac --mac-source $mac -j REDIRECT --to-port 9999
iptables -A INPUT -i $lan -p tcp --dport 9999 -m mac --mac-source $mac -j ACCEPT
iptables -A FORWARD -i $lan -p tcp -m multiport --dports 443,9999 -o $internet -m mac --mac-source $mac -j ACCEPT
done
mac-transparent 和 mac-proxy 列表必须包含本地网络上将通过 squid 的计算机的 mac 地址