C# - 通过 IP 地址 / DNS 名称获取操作系统

3
我们正在编写一个管理服务器的应用程序,我需要能够查看网络中任何远程机器上运行的操作系统。
我们并不总是拥有查看此信息的凭据,因此WMI不是解决方案。
我只需要知道它是否运行Windows、Linux或其他操作系统。以及操作系统的版本。
目前,我们从这些服务器上的数据库获取此信息。但我想在不询问数据库的情况下完成此操作。
如果我只有IP地址或DNS名称而没有凭据,是否可能获取此信息?C#/.Net Core解决方案将是理想的选择。或者任何可以实现此功能的协议也可以,我会将其转换为C#。
结论
因此,根据可用和不可用的选项,这里提出了以下选项。
  1. 如果您在远程计算机上拥有管理员帐户,则WMI是最佳方法。此处有来自learn.microsoft.com的示例
  2. 如果您可以访问像SQL这样的数据库,则可以查询SQL以返回操作系统信息。这将因数据库和版本而异,因此研究至关重要。
  3. 使用类似nmap的工具可以通过端口指纹识别获取操作系统信息。这并不总是准确的,取决于服务器安全性和设置。感谢@MindSwipe和@BlackSpy
  4. 使用代理发送此信息也是一种可能性,并且是一个很好的方法,但这需要一些开销,可以通过适当的设置避免。感谢@BlackSpy和@Clint

这有帮助吗?-> 我不确定您能否获取正在运行的操作系统 -> https://social.msdn.microsoft.com/Forums/en-US/6aaf0d22-84cf-49ce-9d92-b45a207a571c/get-information-about-the-computers-of-a-network-?forum=csharplanguage - panoskarajohn
3
您可以使用TCP/IP堆栈指纹识别。nmap是一个可以实现这一功能的cli工具(详见此处)。TCP/IP指纹识别并不完美,但应该能够胜任。我没有在C#中找到它的任何实现,这意味着您可能需要将其包装在cli调用中。 - MindSwipe
谢谢@MindSwipe。我会看一下nmap,并尝试将其整合到我的应用程序中。 - Marius
2个回答

1
你正在进行的工作类似于CMDB清单扫描,对于Windows和Linux有不同的策略。首先,决定是使用代理还是无代理方式。
如果你选择代理路线,那么编写一个小的.NET应用程序,公开一个端口用于查询,并为两者提供操作系统特定的实现。然后让IT部门在所有设备上安装它。
无代理方式则稍微棘手一些。首先查找应该为管理功能打开的端口(Windows上的WinRM - 在这里要小心 - 它默认关闭,Linux上的SSH),或任何您知道IT部门默认提供的服务(希望在其基础VM映像中)。如果启用了WinRM/SSH,并且您可以以编程方式查询密码存储库,则可以执行远程登录并运行任何需要提取的其他信息的代码。正如你所说,你没有密码,你能做的最好的办法就是根据暴露的端口猜测。

谢谢 @BlackSpy,根据我的研究,我得出了相同的结论。我们将不使用代理,因此这可能会很棘手。在我们的情况下,指纹路线是最有效的。但我们可能会将其作为备选方案。首要任务是查询这些服务器上的数据库,因为这将是最准确的。 - Marius

0

您可以利用UserAgent字符串

来自MSDN文档:

当您请求网页时,您的浏览器会向托管您正在访问的站点的服务器发送一些标头,如下所示。

GET / HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Accept-Language: en-US
User-Agent: Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Proxy-Connection: Keep-Alive
Host: microsoft.com

平台令牌将描述您的操作系统(也在链接中)

您可以像这样查询

 String ua = Request.UserAgent;  
 if (ua.Contains("Windows NT 10"))
     return "Windows 10";
 else if (ua.Contains("Linux"))
     return "Linux"

链接: https://learn.microsoft.com/zh-cn/previous-versions/windows/internet-explorer/ie-developer/compatibility/ms537503(v=vs.85)?redirectedfrom=MSDN

或者

Request.Headers["User-Agent"].ToString();

1
这需要服务器向您的应用程序发出HTTP请求,有点违背初衷。因为如果您需要在服务器上安装一个程序,那么最好安装一个程序,该程序发送确切的操作系统信息。 - MindSwipe
不需要在服务器上运行自定义应用程序,您只需利用已经随标头传入的信息即可。此外,我们也可以使用Request.Headers["User-Agent"].ToString(); 并解析所需的信息。 - Clint
1
正如@MindSwipe所说,这样是错误的。我的应用程序需要询问远程计算机使用的操作系统。远程计算机不会向我的应用程序发送请求。 - Marius
啊,好的,我的错。你有管理员访问权限或读取远程注册表的权限吗? - Clint
@Clint,假设我没有。我不能依赖WMI。 - Marius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接