如何列出对远程机器开放的所有套接字?

spr*_*aff 14 linux security socket

一个香草ss -l列表(在我当前的机器上)许多打开的套接字,具有各种 Netid 类型,其中许多只在 localhost 上侦听。

如何获得所有且仅包含远程机器可以与机器交换数据的所有套接字的列表?

  • 这将包括 TCP、UDP、任何其他传输层协议、RAW 套接字以及我可能不知道的任何其他协议。(ss在这个意义上是完整的吗?)

  • 我相信这将排除 UNIX 套接字(它们仅在本地文件系统上,对吗?或者 UNIX 套接字可以远程操作,它们应该包括在内)。

  • 可以忽略受本地主机限制的侦听器,但我不知道在如何表示/映射本地主机方面是否有任何警告。

基本标准是“如果侦听过程允许,我可以远程入侵任何套接字”。

(我记得ss几年前的命令显示的结果比我现在得到的少得多。这让我想知道某些发行版是否配置ss为默认隐藏内容。我正在寻找一个ss或类似的实用程序命令,它尽可能可移植, 只要它不会仅仅因为它在不同的环境中运行而隐藏任何东西。此外,从安全理论的角度来看,对于威胁模型,我们可以假设机器完全在我们的控制之下并且运行正常,非恶意软件。)

那么如何列出所有且仅相关的套接字?

sou*_*edi 19

在大多数环境中,您只会期望找到 tcp、udp、原始和数据包套接字。幸运的是,ss知道所有这些。

假设ss知道您需要的所有协议,我可能会使用以下命令。这将排除“unix”套接字。它还排除了“netlink”套接字,它们仅用于与本地内核通信。

sudo ss -l -p | grep -vE '^(u_|nl )'
Run Code Online (Sandbox Code Playgroud)

通常,您没有很多侦听套接字。因此,您可以查看所有这些,并手动忽略任何侦听环回 IP 地址的内容。或者,您可以要求ss进行所有过滤:

sudo ss -l -p -A 'all,!unix,!netlink' 'not src 127.0.0.1 not src [::1]'
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,输出还可以包括“客户端”udp 套接字。所以它也可能显示 DNS 客户端、HTTP/3 客户端、...

如果您不需要查看有关打开每个套接字的程序的信息,那么您可以删除该-p选项,并且您不需要以root 权限 ( )运行ss(或)。netstatsudo

上面的命令有多全面?

尽管被宣传为 netstat 的替代品,但ss缺乏对显示“udplite”套接字的支持。

此外,答案取决于您的版本ss(我猜也是内核)。这个答案最初写的时候,2017年之前,ss不支持“sctp”。 netstat20142 月起支持)。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不支持蓝牙插座。蓝牙插座不是传统问题。如果您正在进行全面审计,这可能是相关的。不过,蓝牙安全性是一个非常具体的问题;我不在这里回答。

省略本地主机netstat

netstat没有特定的方法来省略绑定到本地主机的套接字。你可以| grep -v在最后使用。如果您使用-pnetstat / ss 选项,请小心。如果进程名称匹配,您可能会意外排除某些进程。我会在你的模式中包含冒号,比如grep -v localhost:. 除了默认的 inss是显示数字地址,所以在这种情况下你会使用| grep -vE (127.0.0.1|\[::1\]):. 我想您可以尝试检查会被意外排除的进程,例如ps ax | grep -E (127.0.0.1|\[::1\]):.

有没有更简单的命令?

不幸的是数据包套接字。否则,我可能会建议一个简单的netstat -l命令。 netstat有助于预测您的请求并将输出拆分为“Internet 连接”、“UNIX 域套接字”和“蓝牙连接”。你只看第一部分。没有关于 netlink 套接字的部分。

假设您只关心 tcp、udp、原始和数据包套接字。对于前三种类型的套接字,您可以使用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 协议的特定协议,则它是仅传输的。我没有检查这些是否仅被视为侦听套接字)