ip tables 和 ip route 是两个不同的工具,它们在不同的阶段执行不同的功能。ip route 是用来管理和控制路由表的,它决定了数据包应该从哪个网卡或网关发送出去。ip tables 是用来配置、管理和控制网络数据包的过滤、转发和转换的,它根据用户定义的规则对数据包进行检查、修改或丢弃。
一般来说,ip route 先于 ip tables 执行,因为路由表是在内核中最先处理数据包的部分。当内核收到一个数据包时,它会先查看路由表,找到合适的出口网卡或网关,然后将数据包发送出去。在发送之前,内核会根据 ip tables 中的规则对数据包进行过滤、转发或转换。例如,内核可能会根据 NAT 规则更改数据包中的源地址或目标地址,或者根据 filter 规则接受或丢弃数据包。
ip rule,ip tables,ip route 的顺序是这样的:
adb root
adb shell
改变网卡网址
ifconfig eth0 192.168.0.167 up

添加虚拟网卡
ifconfig eth0:0 192.168.10.10 up
以上的命令就可以在eth0网卡上创建一个叫eth0:0的虚拟网卡,他的地址是:192.168.10.10

删除虚拟网卡
ifconfig eth0:0 down
ip route 查看路由表的内容
- G8142:/ $ ip route
- 192.168.31.0/24 dev wlan0 proto kernel scope link src 192.168.31.165
- Android设备中可以使用命令ip rule显示现有的路由策略,如下所示:
-
- rk3399_all:/ # ip rule
- 0: from all lookup local
- 10000: from all to 172.29.7.148 lookup eth0
- 10000: from all fwmark 0xc0000/0xd0000 lookup legacy_system
- 10500: from all iif lo oif dummy0 uidrange 0-0 lookup dummy0
- 10500: from all iif lo oif eth0 uidrange 0-0 lookup eth0
- 13000: from all fwmark 0x10063/0x1ffff iif lo lookup local_network
- 13000: from all fwmark 0x10064/0x1ffff iif lo lookup eth0
- 14000: from all iif lo oif dummy0 lookup dummy0
- 14000: from all iif lo oif eth0 lookup eth0
- 15000: from all fwmark 0x0/0x10000 lookup legacy_system
- 16000: from all fwmark 0x0/0x10000 lookup legacy_network
- 17000: from all fwmark 0x0/0x10000 lookup local_network
- 19000: from all fwmark 0x64/0x1ffff iif lo lookup eth0
- 22000: from all fwmark 0x0/0xffff iif lo lookup eth0
- 23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main
- 32000: from all unreachable
- rk3399_all:/ #
-
-
- 其中第一列表示策略号码(同时也是策略对应的索引值),可支持上万条策略,
- 策略号码数值越小表示该条策略的优先级越高。策略0为优先级最高的策略,
- 在数据包进行路由时,首先匹配该数据包是否满足策略0的规则,
- 即所有的数据包去 local路由表中去查找自己的路由方向,
- 没有找到则使用下一优先级的路由策略,这里为10000号策略,
- 即所有的数据包发往172.29.7.148的都从eth0网卡出去。
-
- rk3399_all:/ # ip route list table local
- broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
- local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
- local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
- broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
- broadcast 172.29.0.0 dev eth0 proto kernel scope link src 172.29.7.28
- local 172.29.7.28 dev eth0 proto kernel scope host src 172.29.7.28
- broadcast 172.29.255.255 dev eth0 proto kernel scope link src 172.29.7.28
- rk3399_all:/ #
- 130|G8142:/ $ ip rule ls
- 0: from all lookup local
- 10000: from all fwmark 0xc0000/0xd0000 lookup 99
- 10500: from all oif dummy0 uidrange 0-0 lookup 1003
- 10500: from all oif wlan0 uidrange 0-0 lookup 1023
- 13000: from all fwmark 0x10063/0x1ffff lookup 97
- 13000: from all fwmark 0x10064/0x1ffff lookup 1023
- 14000: from all oif dummy0 lookup 1003
- 14000: from all oif wlan0 lookup 1023
- 15000: from all fwmark 0x0/0x10000 lookup 99
- 16000: from all fwmark 0x0/0x10000 lookup 98
- 17000: from all fwmark 0x0/0x10000 lookup 97
- 19000: from all fwmark 0x64/0x1ffff lookup 1023
- 22000: from all fwmark 0x0/0xffff lookup 1023
- 23000: from all fwmark 0x0/0xffff uidrange 0-0 lookup main
- 32000: from all unreachable
路由策略数据库管理命令
G8142:/ $ ip route 查看默认路由表(main)路由
192.168.31.0/24 dev wlan0 proto kernel scope link src 192.168.31.165
(前提条件应该是发往的目标地址网卡不在一个网段内,此时才寻找路由规则转发)
"default via 192.168.1.1 dev wlan0"
默认路由。任何无路由报文都交给wlan0 经由默认网关192.168.1.1来转发。
192.168.31.0/24 dev wlan0 proto kernel scope link src 192.168.31.165
发往192.168.31.0/24 网络的报文 则交给wlan0 发送,并且使用192.168.31.165作为其source ip.
proto kernel的意思是这个路由项是在自动配置阶段由kernel创建的
scope link的意思是192.168.31.0/24 这个子网内的目标ip仅仅在wlan0这个接口上valid.
- G8142:/ $ ip route
- 192.168.31.0/24 dev wlan0 proto kernel scope link src 192.168.31.165
-
- G8142:/ $ ifconfig
- wlan0 Link encap:UNSPEC Driver icnss
- inet addr:192.168.31.165 Bcast:192.168.31.255 Mask:255.255.255.0
- inet6 addr: fe80::86c7:eaff:fe2d:b98/64 Scope: Link
- UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
- RX packets:6644 errors:0 dropped:0 overruns:0 frame:0
- TX packets:6980 errors:0 dropped:0 overruns:0 carrier:0
- collisions:0 txqueuelen:3000
- RX bytes:6001248 TX bytes:1155447
- kuznet@amber:~ $ ip ru ls
-
- 0: from all lookup local
-
- 200: from 192.203.80.0/24 to 193.233.7.0/24 lookup main
-
- 210: from 192.203.80.0/24 to 192.203.80.0/24 lookup main
-
- 220: from 192.203.80.0/24 lookup inr.ruhep realms inr.ruhep/radio-msu
-
- 300: from 193.233.7.83 to 193.233.7.0/24 lookup main
-
- 310: from 193.233.7.83 to 192.203.80.0/24 lookup main
-
- 320: from 193.233.7.83 lookup inr.ruhep map-to 192.203.80.144
-
- 32766: from all lookup main
-
- kuznet@amber:~ $
-
- 每行第一部分的数字是规则的优先级,接着是选择符。
-
- 关键词lookup后面接着路由表识别符。
-
- 如果规则要进行网络地址转换,还需要一个关键词map-to设置转换以后的地址。
-
- 上面的示例非常简单,192.203.80.0/24和193.233.7.0/24组成内部网络,但是它们向外发送数据包要通过不同的路由。主机193.233.7.83和外界会话时,地址需要转换为192.203.80.144。
查看路由表
最早的策略配置方式是写了个shell脚本,配置了如下策略,对于目的IP为77/78的都走eth0网卡。在init.rc中开启对应的服务ipruleservice,网卡启动或者链路有变化调用该服务配置策略,ipruleservice中命令如下
- ip rule add to 192.168.1.78 table eth0
- ip rule add to 192.168.1.77 table eth0
#清空用户自定义链的所有规则
iptables
查看防火墙规则
-L 通过列表显示当前防火墙的规则信息
-n 默认按照ip与端口号显示,不解析协议名称
-V 详细显示规则信息
--line-numbers 按照序号显示规则顺序
-t 指定显示规则的表



练习一:阻止所有用户不能访问ssh远程服务
iptables -A INPUT -p tcp --dport 22 -j DROP
-A 指定链添加规则
-p 指定协议
--dport 指定目标端口
--sport 指定来源端口
-s 指定来源ip地址
-i 指定接收数据的网卡
-j 指定规则策略DROP 丢弃 ACCEPT 接受 REJECT拒绝
练习二:阻止windows远程连接到虚拟机,允许其他网段连接
iptables -A INPUT -p tcp -s 10.0.0.1 --dport 22 -j DROP
练习三:只允许windows连接,其他网段全 不允许
方法一:
liptables -A INPUT -p tcp -s 10.0.0.1 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP
方法二:
iptables -A INPUT -p tcp !}s 10.0.0.1 --dport 22 -j DROP
练习四:只允许通过内网访问80端口,不允许通过外网访问80端口
方法一
iptables -A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 80 -j DROP
方法二
iptables -A INPUT !Fi ethO -p tcp --dport 80 -j ACCEPT
public static final int TRANSPORT_BLUETOOTH = 2; public static final int TRANSPORT_CELLULAR = 0; public static final int TRANSPORT_ETHERNET = 3; public static final int TRANSPORT_LOWPAN = 6; public static final int TRANSPORT_USB = 8; public static final int TRANSPORT_VPN = 4; public static final int TRANSPORT_WIFI = 1; public static final int TRANSPORT_WIFI_AWARE = 5;
考虑一个特殊的需求,某app只能通过WIFI接口去传输数据,是否可以实现?较新版本的android已经支持了该功能,通过调用setProcessDefaultNetwork()可以指定某一进程的网络接口,
该进程在创建socket时(app首先调用setProcessDefaultNetwork()),android底层会利用setsockopt函数设置该socket的SO_MARK为netId(android有自己的管理逻辑,每个Network有对应的ID),以后利用该socket发送的数据都会被打上netId的标记(fwmark 值)