Linux运维之如何使用ss命令代替netstat
前言
在运维和管理Linux服务器的时候,我们最常用的一个命令就是netstat,我常用这个命令来查看当前服务器上有哪些进程正在侦听端口,主要用来诊断网络服务的工作状态。
不过,最近有一次安装好一个Ubuntu发型版,发现默认没有安装netstat,觉得非常奇怪,自己手动安装后,发现manpages提示,netstat命令已经是deprecated了,建议使用ss命令代替。
Thisprogramismostlyobsolete.Replacementfornetstatisss.Replacementfornetstat-risiproute.Replacementfornetstat-iisip-slink.Replacementfornetstat-gisipmaddr.
netstatmanpages
netstat的用法
netstat有许多许多参数,我一般就用一种组合,以至于后来已经想不起来为什么是这几个参数了:
netstat-npl
得到的结果是这样的:
ActiveInternetconnections(onlyservers) ProtoRecv-QSend-QLocalAddressForeignAddressStatePID/Programname tcp00127.0.0.53:530.0.0.0:*LISTEN655/systemd-resolve tcp000.0.0.0:220.0.0.0:*LISTEN890/sshd tcp00127.0.0.1:6310.0.0.0:*LISTEN30790/cupsd tcp000.0.0.0:180250.0.0.0:*LISTEN890/sshd tcp600:::22:::*LISTEN890/sshd tcp600::1:631:::*LISTEN30790/cupsd tcp600:::9090:::*LISTEN15415/./prometheus tcp600:::18025:::*LISTEN890/sshd udp00127.0.0.53:530.0.0.0:*655/systemd-resolve udp000.0.0.0:6310.0.0.0:*30792/cups-browsed udp000.0.0.0:53530.0.0.0:*757/avahi-daemon:r udp000.0.0.0:423600.0.0.0:*757/avahi-daemon:r udp600:::58232:::*757/avahi-daemon:r udp600:::5353:::*757/avahi-daemon:r ActiveUNIXdomainsockets(onlyservers) ProtoRefCntFlagsTypeStateI-NodePID/ProgramnamePath unix2[ACC]STREAMLISTENING351161304/gnome-session-@/tmp/.ICE-unix/1304 unix2[ACC]SEQPACKETLISTENING14481/init/run/udev/control unix2[ACC]STREAMLISTENING342771270/systemd/run/user/1000/systemd/private unix2[ACC]STREAMLISTENING342821270/systemd/run/user/1000/gnupg/S.gpg-agent.ssh unix2[ACC]STREAMLISTENING335101270/systemd/run/user/1000/gnupg/S.gpg-agent unix2[ACC]STREAMLISTENING335111270/systemd/run/user/1000/pulse/native unix2[ACC]STREAMLISTENING335121270/systemd/run/user/1000/gnupg/S.gpg-agent.extra
最常用的就是这个命令组合,展示的结果有两个段落,第一个段落展示的是TCP/UDP协议的侦听情况,第二个段落展示的是socks文件的侦听情况。参数n的意思是展示数字格式的IP地址,不然会展示主机名称或者是域名,参数p的意思显示进程的名字(有时候显示不出来),l的意思,是关注处于LISTENING状态的socket。
通过如上命令,我们看到了系统所有打开的socket,如果你启动一种网络服务也好,自己开发一个网络服务打开端口也好,通过这个命令都应该能看到自己打开的端口,如果看不到,应该就是没有能够正确打开端口,要好好查询是什么原因。所以这是一个很好用的调试命令。
ss的用法
上面介绍了netstat的最最基本的一种用法,其他用法当然还有很多,但是先略过不表,如果想使用ss命令来代替netstat的话,我们怎样达到类似的效果呢?
ss-atlp
这是我自己摸索的一个参数组合,目前我背诵得还不是很流利,每次还需要看一下文档:
StateRecv-QSend-QLocalAddress:PortPeerAddress:Port LISTEN0128127.0.0.53%lo:domain0.0.0.0:*users:(("systemd-resolve",pid=655,fd=13)) LISTEN01280.0.0.0:ssh0.0.0.0:*users:(("sshd",pid=890,fd=5)) LISTEN05127.0.0.1:ipp0.0.0.0:*users:(("cupsd",pid=30790,fd=7)) LISTEN01280.0.0.0:180250.0.0.0:*users:(("sshd",pid=890,fd=3)) LISTEN0128[::]:ssh[::]:*users:(("sshd",pid=890,fd=6)) LISTEN05[::1]:ipp[::]:*users:(("cupsd",pid=30790,fd=6)) LISTEN0128*:9090*:*users:(("prometheus",pid=15415,fd=3)) LISTEN0128[::]:18025[::]:*users:(("sshd",pid=890,fd=4))
这是ss命令呈现出来的结果,可以看到,格式和netstat很不一样,不像netstat命令那么紧凑和直观。这是很多人诟病这个命令的原因之一。当然,批判这种批判的声音认为,人们只是死守了一种习惯,不愿前行。当然了,这么说也未尝不对,就拿Charles个人来说,就算我2010年参加工作,才学会netstat命令,那我到现在也使用了将近十年,从来没有变过,当然看得无比顺眼啦。
当然,也有一种理由是老外提出来的,说ss这个命令的名字不好,其实ss可能是socketstatistics的意思,缩写以后,竟然只有两个字母,不太好联想,不像netstat那么直观。当然这是我的解释,不是老外抱怨的理由,他们抱怨的是,每每提及ss,他们会联想起希特勒!是不是匪夷所思,我是80后,我这个年代的人,对这个都没有什么印象,关键我们用中文为主,估计大家看到ss最多联想到梯子,怎么都不会想到希特勒。这个大纳粹有一个武装部队,以前叫党卫队特别机动部队,后来改名叫武装党卫队。它的德语简称正是SS。
不说闲话了,说说几个参数,a参数是显示所有的意思,t参数意思是显示TCP协议的,l代表正在LISTENING状态的,p代表进程信息。从上面的表里,我们看到p参数打印的信息,组织得不如netstat精炼。但是更为完善一点,显示了进程名字和PID以及FD。但是因为用了两重小括号,key/value的格式,再加引号,看起来脏乱差。当然,我们可以用一些命令去格式化它,不过还是太麻烦了。
更换的原因是什么?
这可能是我最为好奇的事情。不过网上我搜索了不少的资料,基本都语焉不详。这也有点让我有点无奈。
大体上,我们能看出来,主要是net-tools这个包,将要被iproute这个包给替换。理由大概是,1,这个包太老了,2,这个包不支持很多内核新的特性(但是没有说是哪些特性),界面不够优化使用困难(对命令行不友好),3,net-tools里面的ifconfig确实缺点多多,4,未来不再想维护net-tools了。
LukClaesandme,asthecurrentmaintainersofnet-tools,we'vebeenthinkingaboutit'sfuture.Net-toolshasbeenacorepartofDebianandanyotherlinuxbaseddistroformanyyears,butit'sshowingitsage.
Itdoesntsupportmanyofthemodernfeaturesofthelinuxkernel,theinterfaceisfarfromoptimalanddifficulttouseinautomatisation,andalso,ithasn'tgotmuchloveinthelastyears.
Ontheotherside,theiproutesuite,introducedaroundthe2.2kernelline,hasbothamuchbetterandconsistentinterface,ismorepowerful,andisalmosttenyearsold,sonobodywouldsayit'suntested.
Hence,ourplansaretoreplacenet-toolscompletelywithiproute,maybeleadingtherouteforotherdistributionstofollow.Ofcourse,mostpeopleandtoolsuseandrememberthevenerableoldinterface,sothefirststepwouldbetowritewrappers,tryingtobecompatiblewithnet-tools.
Atthesametime,webelievethatmostpackagesusingnet-toolsshouldbepatchedtouseiprouteinstead,whileotherscancontinueusingthewrappersforsometime.Theifupdownpackageisobviouslythefirstcandidate,butitseemsthataversionusingiproutehasbeenavailableinexperimentalsince2007.
https://serverfault.com/questions/633087/where-is-the-statement-of-deprecation-of-ifconfig-on-linux
也有从 原理层面分析的:现在的netstat和ifconfig命令,都是通过读写/proc目录下的虚拟文件来完成任务的,这个东西在小型业务系统上,是没问题的,但是在大规模系统里,可能会伤害系统的性能之类的。相比之下,ss和ip两个命令,使用的是Linux内核的netlinksockets特性。有着根本上的不同。虽然,老命令也可以用新原理重写,但是其实并没有人那么做,主要因为不同程序员团体的一些politicalissues,大家意见不合……
当然,深层次的还有,我们使用这样的调试命令,本质上还是希望获知内核的状态的,其实,内核已经改变了networking模块的整个原理,另一方面我还要求命令像从前那样去展示信息,展示层面的格式和真实原理已经背离,所以,从长远看,替代这两个命令才是必然。
结论
咱们这些做技术的,也还是要与时俱进比较好,虽然,以前的那些命令熟悉,好用,手到擒来,甚至无法忘记,但是新的还是要保持学习。很多发型版已经默认不带有net-tools包了,虽然仍然可以手动安装回来,但是,这背后的态度已经很明确了。另一方面,我们做技术,也要谨防自己的大脑僵化,还是要保持对新事物的好奇心和热情。