当向外界主机发送数据时,在它从网卡流入后需要对它做路由决策,根据其目标决定是流入本机数据还是转发给其他主机,如果是流入本机的数据,则数据会从内核空间进入用户空间(被应用程序接收、处理)。当用户空间响应(应用程序生成新的数据包)时,响应数据包是本机产生的新数据,在响应包流出之前,需要做路由决策,根据目标决定从哪个网卡流出。
如果不是流入本机的,而是要转发给其他主机的,则必然涉及到另一个流出网卡,此时数据包必须从流入网卡完整地转发给流出网卡,这要求Linux主机能够完成这样的转发。但Linux主机默认未开启ip_forward功能,这使得数据包无法转发而被丢弃。Linux主机和路由器不同,路由器本身就是为了转发数据包,所以路由器内部默认就能在不同网卡间转发数据包,而Linux主机默认则不能转发。如下图:
另外,IP地址是属于内核的(不仅如此,整个tcp/ip协议栈都属于内核,包括端口号),只要能和其中一个地址通信,就能和另一个地址通信(这么说是不准确的,即使地址属于内核,但还存在一个检查数据包是否丢弃的问题,不过这不是本文内容),而不管是否开启了数据包转发功能。例如某Linux主机有两网卡eth0:172.16.10.5和eth1:192.168.100.20,某192.168.100.22主机网关指向192.168.100.20,若它ping 172.16.10.5,结果将是通的,因为地址属于内核,从eth1进来的数据包被内核分析时,发现目标地址为本机地址,直接就回应192.168.100.22,回应数据包继续从eth1出去。
如果Linux主机有多块网卡,如果不开启数据包转发功能,则这些网卡之间是无法互通的。例如eth0是172.16.10.0/24网段,而eth1是192.168.100.0/24网段,到达该Linux主机的数据包无法从eth0交给eth1或者从eth1交给eth0,除非Linux主机开启了数据包转发功能。
在Linux上开启转发功能有多种方法:
shell> echo 1
>
/proc/sys/net/ipv4/ip_forward
shell> sysctl -w net.ipv4.ip_forward=1
以上两种方法是临时生效的,若要永久生效,则应该写入配置文件。在CentOS 6中,将/etc/sysctl.conf文件中的”net.ipv4.ip_forward”值改为1即可,但在CentOS 7中,systemd管理了太多的功能,sysctl的配置文件也分化为多个,包括/etc/sysctl.conf、/etc/sysctl.d/.conf和/usr/lib/sysctl.d/.conf,并且这些文件中默认都没有net.ipv4.ip_forward项。当然,直接将此项写入到这些配置文件中也都是可以的,建议写在/etc/sysctl.d/*.conf中,这是systemd提供自定义内核修改项的目录。例如:
shell> echo "net.ipv4.ip_forward=1"
>
/etc/sysctl.d/ip_forward.conf
可以使用以下几种方式查看是否开启了转发功能。
[root@xuexi ~]# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward =
0
[root@xuexi ~]# cat /proc/sys/net/ipv4/ip_forward
0
[root@xuexi ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward =
0
net.ipv4.ip_forward_use_pmtu =
0
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。