Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

作者:陈计节

个人博客:https://blog.jijiechen.com/post/powershell-remoting/

在 Linux/Unix 世界里 SSH 是个好东西,SSH 是 Secure Shell 的缩写,用它可以很容易连接到指定的服务器,并执行特定命令行。除了支持远程终端,作为一种安全的通信协议,还为很多其他工具的提供安全通信功能(比如 Git)。

在本文里,SSH 主要指代的是基于 SSH 通信协议构建的安全终端连接。SSH 远程连接用起来非常简单,下面就是一个 ssh 的示例:

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

指定服务器地址,即可开启连接——简单到难以置信!然后,接下来的指令就是在目标机器上运行了。工作完成了,要断开连接?照常一个 exit 命令即可终止会话,就像关闭一个终端一样容易!

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

由于 SSH 本身是基于命令行环境的,所以如果要在一批远程服务器上执行任务也很容易,写一个 for 语句,很轻松就能完成:

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

于是,很多人发现,批量管理 Linux 服务器很轻松,即使没有那些功能大而全的工具,只要有管理(使用)单台服务器的经验,再加上 ssh 就可以轻松管理一个集群了。如果希望服务器能够通过远程管理,就需要在服务器上安装配置 openssh-server 了。这在 Linux 上基本也只是几个命令也就轻松搞定了。一切都是如此美好!

Windows 世界的远程管理

当类似的工作回到 Windows 上,人们首先想到的远程管理的方式是远程桌面连接,就是这个窗口:

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

远程桌面连接(RDP)也是一个神器,只要知道网络地址(机器名称),以及用户名和密码,就可以连接到任何一台 Windows 电脑上。连接建立之后,几乎就像在操作本地电脑一样地使用远程电脑。 在实践中我们发现,RDP 的表现相当不错。即使在网络不好的情况下,也能有良好的性能;远程操作的不光是桌面,还有剪贴板和音视频等丰富的资源。另外,RDP 的客户端也是很丰富,不但可以跨平台(包括 macOS、Linux 和手机平板电脑等),还有很多能同时连接多个电脑的工具。下面是在 Mac 上连接 Windows 服务器的效果:

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

基于 WinRM 的 PowerShell Remoting

既然 Windows 上的图形界面无法提供批量的远程管理能力,那么命令行界面呢? 等一等,Windows 的命令行界面?Windows 有命令行界面吗? 大概不少人会有这样的疑问。答案不言自明,Windows 不光内置有命令行系统,而且很强大。只是大部分人不怎么用它而已。在早期,Windows 有命令提示符(cmd),后来 Windows 又添加了基于 .NET 的 PowerShell,大大强化了脚本化编程能力。

幸运的是,包括 PowerShell 的 Windows 的命令行体系提供了完善的远程连接和批量执行的能力。与 SSH 类似,PowerShell Remoting 也只需要知道服务器地址,就可以轻松连接;而要结束会话,也是一样的 exit 命令:

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

另外,PowerShell 中不少命令还专门为远程执行提供了优化,比如 Invoke-Command 等。下面的代码查询两台远程计算机的界面语言(代码引自文档):

Invoke-Command -ComputerName Server01, Server02 -ScriptBlock { Get-UICulture }

输出结果为:

LCID    Name     DisplayName               PSComputerName
---- ---- ----------- --------------
1033 en-US English (United States) server01.corp.fabrikam.com
1033 en-US English (United States) server02.corp.fabrikam.com

PowerShell Remoting 是基于 Windows 内置的远程管理技术 WinRM 提供的。如果希望 Windows 服务器能够通过远程管理,需要在服务器启用 WinRM,并配置防火墙规则:

Enable-PSRemoting -SkipNetworkProfileCheck -Force
Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-PUBLIC" -RemoteAddress Any

完成上述配置之后,客户端使用 PowerShell 就可以使用 Enter-PSSession 等命令连接到服务器上了。

配置无密码 的 PowerShell Remoting 体验

密码是一种简单直观,却不够安全的身份鉴别方法。说它不够安全,主要原因是对于集群中的大量服务器而言,如果要分别使用不同的密码,那么维护密码表就成为一项麻烦事了。但如果都用相同的密码,一旦密码泄漏,整个集群都陷入风险。所以不少人只好选一个折衷,为集群中的计算机使用统一密码的同时,又定时(比如每两个月)集中改一次密码。从而在便利和安全之间取得平衡。但始终,密码登录的方式是不够安全的。 在登录服务器时,SSH 支持使用密码,还支持使用证书公钥(public key)。证书公钥登录的原理是,管理员生成一对密钥,将公钥复制到服务器上,自己持有私钥并保护好私钥的内容。在需要连接服务器时,将在客户端用私钥与服务器进行一系列的登录验证后,开启安全的通信。由于公钥的公开并不会导致私钥(private key)的安全风险,所以这种登录方式并不会有泄漏风险。

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

PowerShell Remoting 的服务端 WinRM 支持两种无密码登录的方式。一种是使用客户端证书登录,身份验证过程与 SSH 很类似。另外它还支持借助 Active Directory 环境进行集中式登录。 要为 WinRM 开启客户端证书登录(Client Certificate),主要步骤有: 在服务端为 WinRM 启用 Client Certificate 登录功能 在服务端为 WinRM 启用 HTTPS 支持,设置防火墙规则 在客户端生成证书,并将证书的公钥(public key)导入到服务器上,并映射到指定的服务器上的用户 在客户端将证书导入本地计算机 使用证书连接到服务器 这些步骤并不复杂,却也没有像配置 SSH 服务端那么简单。所以我把这些脚本都写好了,请转到 GitHub 查看和下载。这里有一篇文章详细介绍了各步骤中要使用的命令。

Windows 上的 SSH?使用 PowerShell Remoting 远程管理 Windows 服务器

除了基于 WinRM 的客户端证书登录,新版本的跨平台 PowerShell 6 还支持基于 OpenSSH 直接提供与 Linux 服务器上的 SSH 完全一致的体验。请转到官方文档了解具体配置方法,更多关于 PowerShell Remoting 的资料,还可以参考这本电子书

在服务器上启用了 WinRM 之后,不光可以支持 PowerShell Remoting 功能,还能为 Windows 服务器提供其他众多远程管理功能。比如,著名的自动化配置软件 Ansible 就可以使用 PowerShell Remoting 一样的方式来为 Windows 服务器提供自动化配置能力,同时也很好地支持了上面介绍的客户端证书登录。 事实证明,经过上述简单的配置,也可以很轻松地对 Windows 服务器进行批量的自动化管理了。

上一篇:AudioEffect中文API


下一篇:ZJOI 2018 一试记