一个普通的ss -l
列表(在我当前的机器上)有很多打开的套接字,具有各种 Netid 类型,其中许多只在本地主机上侦听。
如何获取远程计算机可以与该计算机交换数据的所有且仅那些套接字的列表?
这将包括 TCP、UDP、任何其他传输层协议、RAW 套接字以及我可能不知道的任何其他协议。 (
ss
这个意义上完整吗?)我相信这将排除 UNIX 套接字(它们仅在本地文件系统上,对吧?或者 UNIX 套接字可以远程操作,它们应该被包括在内)。
可以忽略本地主机限制的侦听器,但我不知道在如何表示/映射本地主机方面是否有任何警告。
基本标准是“如果侦听进程允许,我可以远程攻击任何套接字”。
(我记得ss
几年前的命令显示很多结果比我现在得到的要少。这让我想知道某些发行版是否配置ss
为默认隐藏内容。我正在寻找一个ss
或类似的实用程序命令,它尽可能可移植,只要它不会仅仅因为它在不同的环境中运行而隐藏任何内容。此外,从安全理论的角度来看,对于威胁模型,我们可以假设该机器完全在我们的控制之下,并且正在运行普通的非恶意软件。)
那么如何列出所有且仅相关的套接字呢?
答案1
在大多数环境中,您只希望找到 tcp、udp、原始套接字和数据包套接字。幸运的是,ss
知道所有这些。
假设ss
知道您需要的所有协议,我可能会使用以下命令。这将排除“unix”套接字。它还排除了“netlink”套接字,这些套接字仅用于与本地内核通信。
sudo ss -l -p | grep -vE '^(u_|nl )'
通常您没有很多监听套接字。因此,您可以查看所有这些内容,并手动忽略任何侦听环回 IP 地址的内容。或者,您可以要求ss
进行所有过滤:
sudo ss -l -p -A 'all,!unix,!netlink' 'not src 127.0.0.1 not src [::1]'
在这两种情况下,输出还可以包括“客户端”udp 套接字。因此它还可能显示 DNS 客户端、HTTP/3 客户端……
如果您不需要查看打开每个套接字的程序的信息,那么您可以删除该-p
选项,并且不需要以root权限运行ss
(或)( )。netstat
sudo
上面的命令有多全面?
尽管被宣传为 netstat 的替代品,但ss
缺乏对显示“udplite”套接字的支持。
另外,答案取决于您的版本ss
(我猜也取决于内核)。最初写这个答案时,之前2017年,ss
不支持“sctp”。 netstat
从那时起就支持它2014年2月)。 sctp 预计具体里面电话公司。在电话公司之外,VOIP 通常使用 udp。
不幸的是,如果您在 中查找完整的列表man netstat
,它会变得非常混乱。 sctp 和 udplite 的选项以及 tcp、udp 和 raw 都显示在第一行。再往下看,是一个完整的协议列表家庭: [-4|--inet] [-6|--inet6] [--unix|-x] [--inet|--ip|--tcpip] [--ax25] [--x25] [--rose] [--ash] [--bluetooth] [--ipx] [--netrom] [--ddp|--appletalk] [--econet|--ec]
。
虽然netstat
支持udplite和sctp,但不支持“dccp”。此外,netstat 不支持数据包套接字(如原始套接字,但包括链路级标头),如ss -l -0
.总之,我讨厌一切,而且我可能可以忍受不那么迂腐。
也不ss
支持蓝牙插座。蓝牙插座并不是传统意义上的问题。如果您正在进行全面审核,这可能是相关的。不过,蓝牙安全性是一个非常具体的问题;我这里不回答。
省略 localhost 中netstat
?
netstat
没有特定的方法来省略绑定到本地主机的套接字。你可以用| grep -v
在最后。如果您使用-p
netstat /ss 选项,请小心。如果进程名称匹配,您可能会意外排除某些进程。我会在你的模式中包含冒号,例如grep -v localhost:
.除了默认情况下ss
显示数字地址外,因此在这种情况下您将使用| grep -vE (127.0.0.1|\[::1\]):
.我想您可以尝试检查哪些进程会被意外排除,例如ps ax | grep -E (127.0.0.1|\[::1\]):
。
有没有更简单的命令?
不幸的是数据包套接字。否则,我可能会建议一个简单的netstat -l
命令。 netstat
有助于预测您的请求并将输出分为“Internet 连接”、“UNIX 域套接字”和“蓝牙连接”。您只需查看第一部分即可。没有 netlink 套接字部分。
假设您只关心 tcp、udp、raw 和 packet 套接字。对于前三种类型的套接字,您可以使用netstat -l -46
.
数据包套接字很常用。因此您还需要训练自己运行ss -l -0
(或ss -l --packet
)。
不幸的是,这给你留下了一个很大的陷阱。问题是现在很想尝试结合这两个命令......
要避免的陷阱ss
ss -l -046
作为单个命令的答案看起来很有吸引力。然而这是不是真的。 ss -46
仅显示 IPv6 套接字。 ss -64
仅显示 IPv4 套接字。
我建议始终对您的结果进行健全性检查。了解会发生什么;检查每个协议,看看是否缺少任何应该存在的内容。如果您没有 IPv4 地址,或没有 IPv6 地址,那就非常可疑了。您可以预期大多数服务器都会有 SSH 服务侦听这两种服务器。由于使用 DHCP,大多数非服务器也应该显示数据包或原始套接字。
如果您不想解释两个不同命令的输出,一种替代方法可能是将netstat
命令替换为ss -l -A inet
.这有点不幸,因为当您运行 netstat 时,完全相同的选项将排除 ipv6 套接字。
因此,对于单个命令,您可以使用ss -l -A inet,packet ...
.
IMO,您也可以ss -l | grep ...
按照我在第一部分中建议的方式使用。这个命令很容易记住,并且它避免了 的选择选项中的任何和所有令人困惑的行为ss
。
尽管如果您编写使用此输出来自动化某些操作的脚本,那么您可能应该更喜欢过滤积极的相反,套接字类型列表。否则,当ss
开始支持新型仅限本地套接字时,脚本可能会中断。
我是否提到过显示来自和 的ss -a -A raw -f link
套接字的组合?而显示ss -a -A raw
ss -a -f link
ss -a -A inet -f inet6
较少的插座比ss -a -A inet
?我认为-f inet6
和-f inet
是特殊情况,没有正确记录。
( -0
、-4
和-6
是-f link
、-f inet
、 和的别名-f inet6
)。
我是否提到过它将ss -A packet
显示标题,但永远不会显示任何套接字? strace
表明它实际上没有读取任何内容。这似乎是因为它将数据包套接字视为始终处于“监听”状态。 ss
懒得对此提供警告。这与原始套接字不同,原始套接字ss
被视为同时地“听”与“不听”。
(man 7 raw
表示如果原始套接字是不是绑定到特定协议但未绑定到特定 IP 协议,则它是仅传输的。我没有检查这些是否仅被视为监听套接字)