如果我们有一个具有 10 个 IP 地址的服务器,那么是否有一种干净的方法可以在每次传出请求时随机选择其中一个作为源 IP?
我尝试了 Apache Mod Proxy,但显然即使我通过脚本自动更改源 IP 地址,每次这样做时我都必须重新加载 Apache。
有没有什么工具或干净的方法可以解决这个问题?
编辑:更多信息
一台服务器上托管多个客户,
他们中的许多人都在调用相同的 API(使用 cURL),该 API 的速率限制为每秒 2 个,因此基本上当其中一个客户发送 2 个请求时,其他客户就无法获得任何请求!
我正在尝试在每次请求时随机轮换服务器的“传出 IP 地址(源 IP)”(此处的问题)或为每个主机分配一个专用的“传出”IP(这不是此处的问题)。
答案1
您可以使用statistic
iptables 模块和SNAT
如下规则:
$ sudo iptables -t nat -A POSTROUTING -m statistic --mode random --probability 0.1 -j SNAT --to-source IP2
$ sudo iptables -t nat -A POSTROUTING -m statistic --mode random --probability 0.1 -j SNAT --to-source IP3
Other rules for remaining IPs ...
您可以选择random
模式或nth
模式。10 个 IP 为每个 IP 提供 0.1 的概率。无需为主接口 IP(IP1)添加规则,因为它是默认使用的。
上述规则适用于所有流量类型。您可以根据需要将其限制为特定协议/端口等。
答案2
(作为单独的答案发布,因为作为对 Khaled 的答案的评论太长了)
虽然模块的使用statistic
是可行的,但这里的数学公式并不准确。p=0.1
对于任何给定的数据包,第一条规则的命中率为。第二条规则匹配剩余数据包的 10%,因此总命中率为p=0.1*0.9=0.09
。第三条规则p=0.1*0.9*0.9=0.081
的命中率为,依此类推。对于九条规则,总概率只有p=0.651
,因此隐式DROP
匹配所有数据包的三分之一。您可以自己尝试:
$ for n in `seq 9`; do sudo iptables -A OUTPUT --dest 10.10.10.10 -m statistic --mode random --probability 0.1 -j ACCEPT; done
$ sudo iptables -A OUTPUT --dest 10.10.10.10 -j ACCEPT
$ sudo ping -c 1000 -i 0.001 -W 0.002 10.10.10.10
$ sudo iptables-save -c | grep 10.10.10.10
[103:8652] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[90:7560] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[73:6132] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[74:6216] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[73:6132] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[70:5880] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[44:3696] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[43:3612] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[50:4200] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode random --probability 0.10000000009 -j DROP
[380:31920] -A OUTPUT -d 10.10.10.10/32 -j DROP
您可以看到,第一条规则匹配了大约 10% 的包裹,匹配的概率逐渐下降,而最后一条规则匹配的包裹DROP
比应有的要多得多。您可以调整概率,或者更简单的方法是使用 notprobability
模式,但使用nth
:
$ sudo iptables -F OUTPUT
$ for n in `seq 10 -1 2`; do sudo iptables -A OUTPUT --dest 10.10.10.10 -m statistic --mode nth --every $n --packet 0 -j DROP; done
$ sudo iptables -A OUTPUT --dest 10.10.10.10 -j DROP
$ sudo ping -c 1000 -i 0.001 -W 0.002 10.10.10.10
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 10 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 9 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 8 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 7 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 6 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 5 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 4 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 3 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -m statistic --mode nth --every 2 --packet 0 -j DROP
[100:8400] -A OUTPUT -d 10.10.10.10/32 -j DROP