我有一个很奇怪的问题。我有一台带有两个网络接口的服务器eth0
和eth1
.每个都连接到不同的网络。每个网络都有一个互联网网关。服务器有各种出境连接:http(服务器上的一些脚本抓取网站)、nfs 客户端、samba 客户端、dns 客户端和电子邮件获取器等等。
由于我不会详细说明的原因,我需要将这些出站客户端拆分,以便仅请求出站 http、nfs、samba 和 dns 流量,eth0
而其他所有流量都通过eth1
.
我已经阅读了一些谷歌搜索,看起来iptables
就是我需要的,但我真的没有任何线索。我只习惯通过 管理入站防火墙规则ufw
。
有人可以从一些示例规则开始,并告诉我如何让系统在启动时采用这些规则吗?理想情况下,不会将我锁定在 SSH 连接之外(我能获得物理访问权限,但我不想)。
编辑如果可以限制从一个帐户到一个接口的所有出站流量,我可以将客户端拆分为两个用户。在纸面上看起来可能更容易。
答案1
我将设置一个单独的路由表和一个策略来使用该表路由标记的数据包,并让 iptables/netfilter 标记某些数据包。
创建一个表:
echo 1 known >> /etc/iproute2/rt_tables
创建路由规则(命令ip
来自ip路由2):
ip rule add from all fwmark 1 table known
我们创建了一个名为“known”的表,并创建了一条路由规则,该规则表示任何标记等于 1 的数据包都会根据“known”表进行路由。我只是称其为已知,因为它用于已知协议列表 - 您可以将其命名为任何您想要的名称。现在我们设置已知的表以正确的方式路由。
ip route add default dev eth0 table known
创建 iptables 规则:
iptables -t mangle -I PREROUTING -p tcp --dport 111 -j MARK --set-mark 1
iptables -t mangle -I PREROUTING -p tcp --dport 2049 -j MARK --set-mark 1
该示例将 NFS 端口 (111、2049) 上的数据包标记为 1。我们将此规则添加到“mangle”iptable 中。这与路由表不同,并且不可更改; mangle 表专门用于以 NAT 以外的任何方式更改数据包。
现在,为了通过其他接口路由其他所有内容,我们向标准路由表添加一条路由。
ip route add default dev eth1
要真正理解这一点,请阅读第 4 节和第 11 节LARTC 操作指南。
答案2
嗯,“最简单的”的方式应该是指示单个程序使用特定的接口(或者该接口的ip。例如:
ping -I eth1 8.8.8.8
指示 ping 使用 eth1 作为源接口,同时
wget --bind-address 10.0.0.1 http://www.google.it/
指示 wget 到经历10.0.0.1
具有IP 地址的接口。
老实说,我不知道是否可以全部您需要的程序,但这是减少您需要编写的规则iptables
和iproute
程序的开始。
作为开始,你应该阅读本教程在多个互联网连接。好好读书也是其中之一数千iptables 教程,特别是outbound filtering
, process
/pid filtering
和port filtering
.
答案3
正确的方法是将bind() 绑定到要用于传出数据包的接口。然后,您可以使用ip route
和命令设置路由ip rule
,以控制数据包如何根据其传出接口进行路由。对于我的示例,我将假设以下网络:
- eth0:
- 地址:192.168.0.2/24
- 默认网关:192.168.0.1
- 以太网1:
- 地址:192.168.1.2/24
- 默认网关:192.168.1.1
我将创建两个路由表,一个用于 eth0 的流量传出,称为“alternate”,另一个表用于 eth1,称为“main”。路由表 main 始终存在,并且是route
和命令使用的普通表ip route
。大多数人从不处理任何其他表。要创建名为alternate 的表,我们将以下行添加到/etc/iproute2/rt_tables
:
10 alternate
主表的默认优先级为 254。路由表生效的规则由ip rule
命令控制。默认情况下,该命令将打印出现有规则的列表,其应如下所示:
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
这基本上表示它将在表中查找路由local
,该表是内核为本地路由(例如我自己的 IP 地址)维护的特殊表。然后它将尝试表主表和表默认值。表默认值通常为空,因此如果 main 中没有匹配项,则没有到主机的路由。首先,让填充表与 eth0 的规则交替。
sudo ip route add table alternate 192.168.0.0/24 dev eth0
sudo ip route add table alternate 192.168.1.0/24 dev eth1
sudo ip route add table alternate default via 192.168.0.1
您通常希望alternate
表格看起来与main
表格相似。唯一的区别是路由应该不同。如果您确实希望所有 NFS、HTTP 等流量都通过 eth0 上的默认网关,即使它的目的地是 eth1 上的网络,您可能不想包含上面的第二行。下一步是添加何时使用此备用路由表的规则:
sudo ip rule add from 192.168.0.0/24 pref 10 table alternate
该规则表示来自 192.168.0 网络上的地址的任何流量都将使用alternate
路由表而不是普通main
表。最后一步是确保所有必须使用eth0
绑定的客户端。wget
例如,使用set--bind-address=192.168.0.2
为 NFS 设置clientaddr=192.168.0.2
挂载选项。如果将 LibWWW 与 Perl 一起使用,您可以在 LWP::UserAgent 中设置 localaddr 选项来控制它绑定到的本地接口。如果你碰巧有一个客户端,你无法控制绑定并且编译源不是一个选项,你也许可以使用 iptables 规则来修改它的地址,但这更多的是一种 hack,可能不起作用。您需要在 nat 表或 mangle 表的 PREROUTING 链中设置 SNAT 规则。您仍然需要上面给出的修改后的路由表才能使其工作。