【发布时间】:2022-01-21 10:55:58
【问题描述】:
我已经查看了很多类似的问题,但似乎没有一个涵盖这个案例。所以在假设它是重复的之前请检查详细信息。
场景: 我有一个用 C# 编写的面向 .NET Framework 4.7.2 的客户端和服务器应用程序,分别使用 NamedPipeClientStream 和 NamedPipeServerStream 进行通信。
服务器以本地管理员帐户运行,并像这样创建 NamedPipeServerStream:
PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule(new SecurityIdentifier("S-1-5-32-544"), PipeAccessRights.ReadWrite, AccessControlType.Allow));
NamedPipeServerStream mypipe = new NamedPipeServerStream("mypipe", PipeDirection.Out, 1, 0, PipeOptions.WriteThrough, 0, 0, ps);
mypipe.WaitForConnection();
在服务器上,我创建了一个名为“testuser”的本地帐户,它是本地管理员组的成员。当通过网络连接到命名管道时,此帐户用于在客户端进行身份验证。
客户端程序以本地用户身份在通过网络连接的另一台计算机上运行,并创建如下连接:
NamedPipeClientStream mypipe = new NamedPipeClientStream("<ip of server>", "mypipe", PipeDirection.In, PipeOptions.None);
mypipe.Connect();
在 Windows Server 2012 上运行服务器软件时,它可以正常工作。但是在 Windows Server 2016 和 Windows Server 2019 上,我得到了 UnauthorizedAccessException。如果不是我的本地用户“testuser”,而是通过网络使用内置管理员帐户进行身份验证,它在所有三个版本的 windows 服务器上都可以正常工作。
如果我更改管道安全性以使用例如 S-1-5-11 的 SID 以允许“经过身份验证的用户”,它也适用于所有三个版本,但要求是只允许来自本地管理员组的成员通过网络连接到服务器。理想情况下,该帐户是本地帐户还是域帐户应该无关紧要,但我只使用本地帐户进行了测试。
我在服务器上使用事件查看器进行了一些调试,当我的测试用户访问管道时,我可以看到事件 5145(详细文件共享)审核成功,但客户端仍然报告 UnauthorizedAccessException。
有什么方法可以限制只有 Windows Server 2016 和 2019 上本地管理员组成员的访问权限?
【问题讨论】:
-
客户端的
testuser和服务端的testuser有什么关系?这只有在他们都具有相同的密码并且使用 NTLM(本地帐户、非域身份验证)时才有效。为什么不为此使用适当的域帐户? -
@Charlieface testuser 仅作为本地帐户存在于服务器上。在客户端上运行代码时,我必须对服务器进行身份验证才能打开到 SMB 共享“IPC$”的连接以访问命名管道。因此,在客户端上打开一个对话框以输入网络凭据,我在其中提供服务器的本地管理员帐户或我的 testuser 凭据。我希望我的程序能够灵活地在我只能访问本地帐户的凭据的情况下工作。重要的是帐户(本地或域)应该是本地管理员
-
在为远程机器的本地用户输入凭据时,您必须输入
RemoteMachineName\Username。域用户会容易得多,因为两者都会自动识别它。您可以将域用户添加到服务器上的本地管理员。 -
请不要关注域用户部分。我认为这与问题无关,而且我知道我可以提供
RemoteMachineName,但对于例如.\Username来说并不严格要求。 Windows 为我处理它。正如我所说,事件查看器中的日志确认我的身份验证正确。
标签: c# window named-pipes