使用其他端点
一台计算机可以包含多个端点,在PowerShell中,端点也被称为会话配置(session configurations)。举例来说,在64位机器上启用远程控制,会同时为32位PowerShell和64位PowerShell各启用一个端点,其中64位PowerShell的端点是默认端点。
如果你拥有管理员权限,可以在任何计算机上运行Get-PSSessionConfiguration
命令,获得可用的会话配置列表。
每一个端点(EndPoint)都有一个名称。诸如New-PSSession、Enter-PSSession、Invoke-Command等远程控制命令默认使用其中一个名称为“Microsoft.PowerShell
”的端点。在64位系统中,端点是64位的Shell;在32位系统中,“Microsoft.PowerShell”是32位的Shell。
64位系统有一个运行32位Shell的备用端点:“Microsoft.PowerShell32
”用于兼容性目的。如果希望连接到备用端点,只需要在远程控制命令的-ConfigurationName
参数中指定端点名称。
PS C:\windows\system32> Enter-PSSession -ComputerName printer -ConfigurationName 'microsoft.powershell32'
[printer]: PS C:\Users\rick\Documents>
什么时候会使用备用端点?
- 需要显式通过32位的端点连接到64位的机器,即当需要运行的命令依赖于32位的PowerShell插件时。
另外一种可能是存在自定义端点。当需要执行一些特定任务时,或许需要连接到这些端点上。
创建自定义端点
创建一个自定义端点可以分为以下两步。
1)通过New-PSSessionConfigurationFile
命令,创建一个新的会话配置文件。该文件的扩展名须为
.pssc
。- 该文件用于定义端点的特征,指的是该端点允许运行的命令和功能。
2)通过Register-PSSessionConfiguration
命令载入.pssc
文件,并在WinRm服务中创建新的端点。
- 在注册过程中,可以设置多个可选参数,比如说允许哪个用户可以连接到端点。
- 也可以在必要时通过
Set-PSSessionConfiguration
命令改变设置。
下面是一个使用自定义端点进行授权管理的示例。
- 创建一个只有域中HelpDesk组的成员可以访问的端点。在端点内,启用与网络适配器相关的命令,并且只允许这些命令。
- 我们并不打算给HelpDesk组运行命令的权限,仅仅是让他们可以查看命令。
接下来,配置端点可以在提供的备用凭据下运行命令。因此使得HelpDesk组,可以在自身无须拥有执行命令的权限时执行命令。
创建会话配置
参数说明:-Path
参数是必需的,并且提供的文件名称必须以.pssc
结尾。-ModulesToImport
列出组件(在本例只有一个NetAdapter的组件),表示对于本端点只有该组件可用。-SessionType RestrictedRemoteServer
除了一些必需的命令,移除所有PowerShell的核心命令。- 该列表会很小,仅包括Select-Object、Measure-Object、Get-Command、Get-Help、Exit-PSSession等。
-PowerShellVersion
默认为当前PS版本。在本例中,将该参数包含在内,只是为了完整性。
还有一些以-Visible
开头的参数,比如说-VisibleCmdlets
。正常情况下,当使用-ModulesToImport导入一个组件时,所有该组件中的命令都会对于使用最终端点的人可见。通过只列出你希望人们看到的Cmdlet、别名、函数、提供程序,非常有效地隐藏了其他内容。这是限制人们通过该端口所能做的操作的好办法。
请小心使用visibility参数,这是因为该参数有一点让人迷惑。举例来说,如果你导入由Cmdlet和函数组成的组件,使用VisibleCmdlets仅仅限制能够显示的Cmdlets——却不影响是否显示函数,这意味着这些函数在默认情况下都可见。
注意,没有任何方法可以对命令可用的参数进行限制:PowerShell支持参数级别的限制,但需要在Visual Studio中进行大量编码。还有可以使用的其他高级技巧,比如说创建用于隐藏参数的代理函数。(这些超出初学者范围)
会话注册
创建完会话配置文件之后,可以通过下述命令使配置文件生效。
这就创建了名称为HelpDesk
的新端点。连接时,它会提示我们输入COMPANY\HelpDeskProxyAdmin
账户的密码;该端点运行的所有命令都通过该账户的身份运行,我们需要确保该账户拥有运行网络适配器相关命令的权限。
该过程,需要完成几个“是否继续运行”的提示,建议仔细阅读提示。该命令会停止并启动WinRM服务,这会导致中断其他管理员管理本地机器,所以请小心。
该命令还提供了图形化对话窗口,以指定哪个用户可以连接到端点。之所以会显示对话框,是由于我们使用了-ShowSecurityDescriptorUI
参数,而不是使用复杂的安全描述符定义语言(SDDL)设置权限。
我们将HelpDesk用户组添加在内,并确保该组拥有执行和读权限。执行是所需的最小权限,执行权限将我们计划给该账号的权限赋予端点;读权限是另一个我们需要的权限。
删除会话配置
若要从本地计算机中删除会话配置,请使用Unregister-PSSessionConfiguration
cmdlet。
如:PS C:\> Unregister-PSSessionConfiguration testpoint
可以通过about_Session_Configurations,查看会话配置帮助信息:help about_Session_Configurations
连接到受限的端点
基于完成的内容,可以看到下述输出结果(截断后的),使用新端点的用户只能使用非常有限的命令。
通过这种方式限制某个用户组能够使用的功能非常好。正如我们做的测试那样,他们甚至不必从控制台会话连接到PowerShell,他们可以使用基于PowerShell远程控制的GUI工具。这类工具的底层使用的是上述命令,利用这种技术给予用户使用某些功能的权限再好不过。
启用多跳远程控制
多跳远程控制(multi-hop remoting)指定是在远程的计算机Shell中,继续开启另一个计算机的远程会话。
下图描述了“第二跳”或“多跳”的问题:从计算机A开始,并创建了一个PowerShell会话连接到计算机B。这是第一跳,通常该步骤可以正常工作。但当请求由计算机B再次创建第二跳,或者连接到计算机C时,操作失败。
问题是由于PowerShell将凭据由计算机A委托到计算机B时出现的。所谓委托,是使得计算机B以你的身份运行任务的过程,因此确保你可以在计算机B上做任何权限内的事。默认情况下,委托只能传输一跳。计算机并没有权限将你的凭据委托给第三台计算机,也就是计算机C。
启用多跳委托,需要以下两个步骤:
1)在你的计算机(如计算机A)上,运行Enable- WSManCredSSP -Role Client –DelegateComputer x
。
- 将“x”替换为你希望将身份委托到的计算机名称。可以指定具体的计算机名称,当然也可以使用通配符,但不推荐使用,这会导致一些安全问题。但是可以对整个域进行授权,比如.company.com。
2)在第一跳连接到的计算机(如计算机B)上,运行Enable-WSManCredSSP –Role Server
。
上述命令所做的变更,将会应用到计算机的本地安全策略。也可以通过组策略对象手动进行变更,在较大的域环境中可能需要这么做。
通过Enable-WSManCredSSP
的帮助信息,可以获得更多信息。Don还写过一本书《Secrets of PowerShellRemoting Guide》,在该书中对策略相关的元素进行了更详细的阐述。
深入远程控制身份验证
很多人都会认为身份验证是一个单向的过程:当访问远程控制计算机时,必须在登录该计算机之前提供你的凭据。
但PowerShell远程控制采用了双向身份验证,这意味着远程控制计算机必须向你证明它的身份。比如说,当执行Enter-PSSession –computerName DC01
时,名称为DC01的计算机必须在连接建立完成之前,证明它就是DC01
。
为什么?正常情况下,计算机将会通过域名系统(DNS)将计算机名称(比如说DC01)解析为IP地址。但DNS可能会受到电子欺骗的攻击,因此不难想象,攻击者会攻入并将DC01的入口指向另一个IP地址,即一个受攻击者控制的IP地址。
因此,你连接到的DC01,实际上是一台冒名顶替的计算机,然后将你的凭据委托给这台冒名顶替的计算机!
双向身份验证会防止这类事发生:如果你连接到的计算机,无法证明它就是那台你希望连接到的计算机,远程控制连接将会失败。
双向身份验证默认设置
微软期望更多是在域环境下使用PowerShell。因此可以通过活动目录列出的实际计算机名称连接到计算机,域会为你处理双向身份验证。在访问其他可信任的计算机时也可以由域处理双向身份验证。
该技巧需要为PowerShell提供的计算机名称满足以下两点要求:
- 名称可以被解析为IP地址。
- 名称必须与活动目录中的计算机名称匹配。
提供所在域的计算机名称,而对于可信域则需要提供完全限定名(比如DC01.COMPANY.LOC),这样远程控制通常就会生效。
但如果提供的是IP地址,或者需要提供与DNS中不同的名称(比如CNAME别名),那么默认的双向身份验证将无法正常工作。因此只有如下两种选择:SSL或是“受信任的主机”。
通过SSL实现双向身份验证
要想通过SSL实现双向身份验证,必须获得目标计算机的SSL数字证书。证书颁发给的计算机名称必须与你输入访问的计算机名称相同。也就是说,如果运行Enter-PSSession –computerName DC01.COMPANY.LOC -UseSSL -credential COMPANY\Administrator
,那么安装在DC01上的证书必须颁发给“dc01.company.loc
”,否则整个过程就会失败。注意,-credential
参数在该场景中是强制参数。
在获取到证书之后,还需要将其安装到当前用户下的个人证书存储目录——通过微软管理控制台(Microsoft Management Console, MMC)界面是导入证书的最佳方式。仅仅是双击证书,通常情况下也能够将证书导入到账户的个人目录之下,但不通过MMC导入证书对SSL连接不会生效。
在完成证书安装之后,还需要在计算机上创建一个HTTP侦听器,并告诉侦听器使用刚刚安装的证书。查看Don的《Secrets of PowerShell Remoting Guide》,可以在此书中找到包含截图的详细教程。
通过受信任的主机实现双向身份验证
该技术比使用SSL证书略微简单,需要的配置步骤也会少很多。但该方式更加危险,这是由于该技术主要是对于选定的主机关闭双向身份验证。
在开始之前,你需要能够自信地声明“不会有任何人会冒充这几台主机中的任何一台,或者入侵DNS记录”。对于在内部局域网的计算机来说,或许可以确保这一点。
然后,你仅需一种方式去识别哪些计算机不需要双向验证。在一个域中,这或许是类似“*.COMPANY.COM”这样在Company.com域中的所有主机。
这是需要配置整个域设置的实例,下面是一个操作组策略的指南。该指南对于单机中的本地安全策略同样有效。
在任意GPO或本地计算机策略编辑器中,执行这些步骤:
展开计算机配置——展开管理模板——展开Windows组件——展开Windows远程控制管理——展开WinRM客户端——双击受信任的主机——启用策略并添加信任的主机列表,多个条目可以通过逗号分隔,比如“*.company.com,*.sales.company.com.
”。
Tips:
对于组策略对象中没有这些设置的情况,可以在PowerShell中修改受信任的主机。在Shell中运行help about_remote_troubleshooting
获取帮助。
现在就可以在没有双向身份验证拦截的情况下,连接到这些计算机。所有用于连接到这些计算机的远程控制命令中,必须提供-Credential参
数——如果不这么做,可能会导致连接失败。