怎么ping命令还需要root权限?
事情起因
事情的起因是这样的,由于原本的WSL Ubuntu被我给玩坏了,所以打算准备卸载了从新安装一下,正好也想尝试尝试Debian这个上游的发行版。不过在我装好之后心血来潮执行了一次ping命令之后:
奇怪了,这个命令应该是不需要提升权限的呀,为什么这次必须要加上sudo才可以执行呢?话不多说,我们先来检查一下这个命令的权限配置情况:
蛤,这个命令所有者原来是root呀,回想下passwd
这个命令的权限情况我们不难看出,原来是我们没有赋予ping
这个程序suid
权限,所以普通用户无法执行。那解决方法也很简单,就是赋予其suid
权限即可。
可以看到,我们给了suid
权限后(注意权限位置s
),这个命令就可以通过普通用户执行啦。其中suid
权限的意思是在普通用户执行的时候可以短暂获得root权限级别而不需要申请。详细的讲解可以查看这篇:suid权限详解
进一步探索
由于我记得以前ping的时候是不需要提升权限的,于是便抱着尝试的心态看了看CentOS 7关于ping的权限情况,然鹅出大问题兄弟们。在CentOS 7或者Ubuntu20.04LTS上,这个命令是不需要root权限的,但是在检查ping程序的权限时我发现,这个命令的权限竟然没有设置suid
位。这就很奇怪了,同样都没有设置suid
,为社么WSL Debian的不行,但是CentOS 7和Ubuntu20.04LTS就可以执行呢?
下面是Ubuntu20.04LTS的ping权限,可以看出没有suid
权限,但是普通用户也可以执行。甚是奇怪。
那既然这里和我们具体的执行权限关联似乎并不大,那说明必定在其他地方也有控制程序执行的权限。遇事不决我先man
一下。在ping的man手册中,最后的安全部分有这么一段话:
首先我们已经知道了ping走的是ICMP协议,而且,各项都指出我们必须能创建ICMP套接字才可以执行此程序。那我怎么知道普通用户能否创建ICMP套接字呢?我们继续man(笑)
man icmp
(注意这是Linux Programmer’s Manual,部分发行版出场可能没有带相关的包,必须安装后才可以man到icmp),或者可以通过Debian的Wiki进行查询:man icmp的wiki 注意不要看中文版,中文版不全面。
sudo apt install manpages
来进行安装。
我们看看我们能发现什么。
首先我们又知道了ICMP 支持通过sysctl接口来设置一些全局IP参数,并且配置文件的位置是*/proc/sys/net/ipv4/*
.
接下来我们终于注意到什么样的用户才可以创建ICMP scokets了:
这段的意思是说。允许创建 ICMP 套接字的组 ID 的范围是(包括最小和最大组 ID)。默认值为“1 0”,表示不允许任何组创建 ICMP Echo 套接字。那让我们看看我们WSL的Debian这个值是多少吧:
那Ubuntu的值呢?
这下就能说的通了,Ubuntu的值设定的是0
到一个超大的组的值,也就是说,基本上所有的组都可以创建ICMP套接字,所以普通用户也就可以创建ICMP套接字,从而普通用户也可以执行ping命令。所以此时该命令的能否执行已经与suid权限没有太大关系了。
所以说ip_forward又是什么?
如同ping_group_range
是Linux内核提供的,这个转发数据包的能力也是Linux内核所提供的。我们知道在局域网络里面的主机可以透过广播的方式来进行网络封包的传送,但在不同网段内的主机想要互相联机时,就得要透过路由器了。既然主机想要将数据传送到不同的网域时得透过路由器的帮忙,所以,路由器的主要功能就是:“转递网络封包“嘛!也就是说,路由器会分析来源端封包的 IP 表头,在表头内找出要送达的目标 IP 后,透过路由器本身的路由表 (routing table) 来将这个封包向下一个目标 (next hop) 传送。这也就是路由器的功能。
而为什么WSL Debian只有这一个配置文件我觉的这可能与WSL1有关吧。可能这些命令并没有直接调用Linux的底层而是直接走的Windows的底层,毕竟WSL Debian的这个文件夹只有这一个文件,而虚拟机中的这个文件夹可是有一堆文件的哦。当然这都是我的个人猜测。
我们学到了什么?
我们来理一理我们的思路,我们一路从一个普通用户无法执行ping命令而已,一路追查到这里。我记得当初看鸟哥的书的时候,他说过一句话:学习Linux更多的时候培养的是解决问题的能力,每一个东西都是新的,同样经过这次摸索是不是觉得原来底层原来这么庞大,我们看到的只不过是冰山一隅罢了。