Sunday, August 23, 2009

netfilter中的route

数据包内核中的流转如图下:
从图中, 可以很清楚看到netfilter的table与chain的先后顺序. 这里需要了解table与chain的关系

netfilter中, 常常看到table与chain这两个概念. 我之前一直将两者解理为:包含(chains belong to tables)关系. 其实这种解理是错的.
如下是书中的说法:

chains represent hook points  in the packet flow, and tables represent the types of processing that can occur
* 来自<<linux iptables: pocket reference>>一书

但是还有一个引起本人兴趣:
* 图中的routing部分.

大概可以知道, 这就是netfilter的转发机制的决定的一步.

Q: 这里的route表与route命令的route表是否一致?
A: 正是内核的route表

内核route表对发出的数据包起来择路的作用, 为什么"NetWork A"进入的数据会与route表有关系呢?

内核对进入的数据包有如下处理过程:
a. 首先,当一个包进来的时候,也就是从以太网卡进入防火墙,内核首先根据路由表决定包的目标。
b. 如果目标主机就是本机,则如上图直接进入INPUT链,再由本地正在等待该包的进程接收,结束。
c. 否则,如果从以太网卡进来的包目标不是本机,再看是否内核允许转发包(可用echo 1> /proc/sys/net/ipv4/ip_forward 打开转发功能)如果不允许转发,则包被DROP掉,如果允许转发,则送出本机,结束。


这样, 转发出的数据包就与内核的route表相关.

举例说明: 使用linux实现共享上网(windows下叫share connection)

环境假设:
NetWork A 网段: 192.168.1.0/24
NetWork B 网段: 192.168.10.0/24

wlan0网卡与"NetWork B"连接, 通过本网卡可以与广域网通信
配置如下:
IP: 192.168.10.103
Mask:255.255.255.0

配置情况:
jessinio@niolaptop ~ $ ifconfig wlan0
wlan0     Link encap:Ethernet  HWaddr 00:16:cf:68:5b:a7  
          inet addr:192.168.10.103  Bcast:255.255.255.255  Mask:255.255.255.0
          inet6 addr: fe80::216:cfff:fe68:5ba7/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3807509 errors:0 dropped:0 overruns:0 frame:0
          TX packets:480534 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1579932243 (1.4 GiB)  TX bytes:80990478 (77.2 MiB)

jessinio@niolaptop ~ $ netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 wlan0
127.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 lo
0.0.0.0         192.168.10.1    0.0.0.0         UG        0 0          0 wlan0

jessinio@niolaptop ~ $ ping www.google.com
PING www.l.google.com (64.233.189.104) 56(84) bytes of data.
64 bytes from hkg01s01-in-f104.google.com (64.233.189.104): icmp_seq=1 ttl=243 time=105 ms
64 bytes from hkg01s01-in-f104.google.com (64.233.189.104): icmp_seq=2 ttl=243 time=103 ms

wlan0可以通信

可以要证eth0也可以上网:
0. eth0网卡与"NetWork A"连接, 配置如下:
jessinio@niolaptop ~ $ sudo ifconfig eth0 192.168.1.11 netmask 255.255.255.0
* eth0的IP可以随意, 只要在子网中是唯一的就OK

1. 让Linux接爱和转发目的不是本地的数据包:
jessinio@niolaptop ~ $ sudo sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

这样, 所有eth0收到非本地的数据包, 都被forward, forward的方式与路线都由内核的route表决定, 在本例中, 被forward的数据也是走如下这条路线:
0.0.0.0         192.168.10.1    0.0.0.0         UG        0 0          0 wlan0

2. 被forward的数据需要firewall转换源地址(从192.168.1.0/8修改为192.168.10.103)和端口:
jessinio@niolaptop ~ $ sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
* 当wlan0收到被forward的数据包的回复后, 会自动修改为192.168.1.0/24

3. 让forward的回复数据包流回eth0 ( 这一步很重要, 在逻辑上形成一个回路 )
jessinio@niolaptop ~ $ sudo route add -net 192.168.1.0 netmask 255.255.255.0 dev eth0

这时的route表如下:
jessinio@niolaptop ~ $ netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 wlan0
127.0.0.0       0.0.0.0         255.0.0.0       U         0 0          0 lo
0.0.0.0         192.168.10.1    0.0.0.0         UG        0 0          0 wlan0



上面4个步骤就完成了linux路由器的共享配置, 客户端只需要简单配置一下IP, netmask和gateway即可:

other@machine ~ $ sudo ifconfig eth0 192.168.1.10 netmask 255.255.255.0
other@machine ~ $ sudo route add default gw 192.168.1.11 dev eth0


No comments:

Post a Comment

Note: Only a member of this blog may post a comment.