iptables --set-mark - 通过不同的接口路由不同的端口

Tor*_*xed 17 ubuntu routing iptables route

小故事,
3个接口,eth0(局域网),eth1(ADSL),eth2(4G)。
eth0 -> eth1:有效
(端口 80、443、4070) eth0 -> eth2:不会发生


这是这个想法的图形表示:

端口 80 和 443 通过 eth2
ant 其余通过 eth1
在此处输入图片说明

网络方案:

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 
Run Code Online (Sandbox Code Playgroud)






我认为,这个新脚本将 22 和 4070 重新路由到正确的表。
但是,到达该表后,它不会重新路由到 eth2。




此脚本有效,除了 22 和 4070!

(端口 80 没有注释并且可以工作,但是通过 eth1 是错误的。)

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)









旧脚本:


  Ignore everything below unless you're interested in retracing my steps!!
Run Code Online (Sandbox Code Playgroud)




我已经创建了一个 router.sh 脚本来设置我的环境,以防我做坏事。我有 3 个端口,我想将它们发送到 4G 连接,其余端口则通过陆线 ADSL 连接发送。为此,我已指示 iptables 在默认路由上处理包,并在 --dport == 443 | 时通过我的 4G 接口发送它们。80 | 4070

但是,这不起作用;无论如何,我仍然通过固定电话路由。

这是我的脚本的样子:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)

我还尝试将这 3 个添加到脚本的底部:

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"
Run Code Online (Sandbox Code Playgroud)

也试过没有成功:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的,尝试:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1
Run Code Online (Sandbox Code Playgroud)

路由工作,我可以浏览网页,听音乐等等,但我通过错误的界面来做。我已经在谷歌上搜索了很长时间,并找到了一些零碎的东西来了解我在做什么以及我为什么这样做。我可以通过 tc 进行流量整形,但如果可以通过在 iptables 中标记包来做的话,它会对我有很大帮助。

我的猜测是我在不同的规则上做错了顺序,主要是MASQUERADE部分?或者如果那甚至应该在那里?

有人可以解释如何将DNAT端口说,tcp:80 从外部接口(一个或两个协议)到内部 10.0.0.0 地址空间?



输出:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1
Run Code Online (Sandbox Code Playgroud)


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0
Run Code Online (Sandbox Code Playgroud)

遵循以下说明:
output-traffic-on-different-interfaces-based-on-destination-por
iptables-forward-specific-port-to-specific-nic
在其他一些相关线程中。

Bat*_*hyX 6

注意:我只考虑了第一个脚本,忽略了旧脚本。

  • 您不需要使用当前的 iptables 手动修改 netfilter 模块。这仅对自定义连接跟踪器是必需的。
  • 不要混淆routeip route。这是纯粹的邪恶。ip随处使用,忘记ifconfigroute
  • /etc/iproute2/rt_tables不会在重新启动后重置。一遍又一遍地附加相同的条目并不是一个好主意,您只需要做一次。请记住,rt_tables只需为数值定义名称别名,它不会更改任何配置。

  • 现在iptables:在您的FORWARD链中,您将来自 LAN 的数据包丢弃到 4G。这不好。该FORWARD挂钩路由完成后使用。至此,所有的策略路由都完成了,已经知道数据包应该上4G还是ADSL了。在中FORWARD或之后没有重新路由FORWARD(好吧,从技术上讲,POSTROUTING在严重的情况下可以在之后重新路由,但回到正题)。

现在进行路由:请记住,Ubuntu 默认启用反向路径过滤。反向路径过滤的工作原理如下:当内核从接口 A 接收到一个数据包(可以转发也可以不转发)时,它会反转源地址和目的地址,并检查生成的数据包是否应该通过接口 A 路由。如果不是,则数据包将作为地址欺骗尝试被丢弃。

对于从 接收的数据包eth0,这不是问题。对于从 接收到的数据包eth1,这也不是问题,因为在颠倒源 IP 地址和目标 IP 地址时,内核会将其作为表中的默认路由main。对于从 接收到的数据包eth2,您没有标记,这是一个问题,因为内核会命中表中的默认路由main,并认为这些数据包应该是从 接收到的eth1。最简单的解决方案是在 eth1 上禁用反向路径过滤:

sysctl -w net.ipv4.conf.eth1.rp_filter=0
Run Code Online (Sandbox Code Playgroud)


Joh*_*Siu 6

BatchyX已经对iptables和路由做了很好的解释,所以我就锻炼我的懒惰,直接上脚本。

它应该将所有流量通过 192.168.0.91 NAT 到端口 80,443,22,4070。其余的将通过 192.168.1.254 进行 NAT。

我重新进行测试并最终遵循本指南。该指南中缺少的是我脚本中的最后 3 行。这是我从另一个端口发现的,但我丢失了那个链接。

这是一个经过测试的工作脚本。

需要默认路由

我没有放在脚本中的一件事是设置默认路由。它应该是

route add default gw 192.168.1.254
Run Code Online (Sandbox Code Playgroud)

当你这样做时route -n,它应该是唯一的默认路由 (Dest:0.0.0.0)

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1
Run Code Online (Sandbox Code Playgroud)

转发路由器.sh

# 重置/刷新 iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P 输入接受
iptables -P 向前接受
iptables -P 输出接受

#Reset/Flush/Setup IP 路由(表 4)
ip 路由刷新表 4
ip route show table main | grep -Ev ^default | 读取 ROUTE 时;do ip route add table 4 $ROUTE ; 完毕
ip route add table 4 默认通过 192.168.0.1

#Mark 数据包与匹配的 D.Port
iptables -t mangle -A PREROUTING -p tcp --dport 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNAT 规则
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.0.91

#IP 路由
ip 规则添加 fwmark 4 表 4
ip 路由刷新缓存

#IP 堆栈
#这是指南中缺失的部分
回声 1 > /proc/sys/net/ipv4/ip_forward
对于 f 在 /proc/sys/net/ipv4/conf/*/rp_filter ; 做回声 0 > $f ; 完毕
回声 0 > /proc/sys/net/ipv4/route/flush

PS1:简而言之,MASQUERADE对于需要某种负载平衡或需要 DNAT 来处理传入流量的多个外部 IP 的 NAT 不起作用(在大多数情况下,并且绝对在您的情况下)。你需要SNAT方向控制。

PS2:纯 iptables 是不够的。