摘要:本文介绍如何实现通过 SSH
远程连接到 PowerShell
。其使用场景主要在 Linux
环境下远程访问 Windows
下的 PowerShell
,从而能够将 Windows
的相关操作和部署脚本自动化。
本文主要参考微软官方文档:PowerShell Remoting Over SSH,同时介绍在配置过程中遇到的问题。该文档十分详细,并且介绍了各种操作系统之间的配置,这里我们主要介绍 Windows
作为服务器,Linux
作为客户端的场景。
另外这篇文章Configure SSH-based PowerShell Core remoting between Windows and Linux也比较详细,可以对比参考。
安装 PowerShell Core for Windows
目前最新的 Windows
已经集成了 PowerShell
,但是这里还是需要单独安装一份,因为这个 PowerShell
将会配置为 SSH
的子系统。而且新安装的 PowerShell
和内置的是独立。
单独安装的好处:
- 版本统一,我们可以使用当前 GitHub 最新的 PowerShell,并且在客户端和服务器端部署一致的版本。
- 配置简单,不需要知道内置的 PowerShell 的属性。
安装过程很简单,一般情况下我们字需要到 GitHub
的 Release
页面上下载 MSI
安装包 PowerShell-版本号-win-x64.msi
,直接下一步就可以了。
默认安装完成后我们会在 C:\Program Files\PowerShell\6-preview
路径下看到 PowerShell
的相关文件。最后一层文件夹是版本号。
安装完成后,我们需要测试一下是否支持 SSH Remoting
1 | Get-Command New-PSSession -syntax |
预期的结果应该包含:
1 | New-PSSession [-HostName] <string[]> [-Name <string[]>] [-UserName <string>] [-KeyFilePath <string>] [-SSHTransport] [<CommonParameters>] |
安装 Win32 OpenSSH
通过 GitHub
的 Release
页面上下载 ZIP
,解压到指定文件夹,一般为:C:\Program Files\OpenSSH
。
然后通过参考官方安装文档 Install Win32 OpenSSH 进行安装,这里使用命令行进行安装
执行安装 PowerShell
脚本
1 | powershell.exe -ExecutionPolicy Bypass -File install-sshd.ps1 |
配置防火墙
1 | # Windows 2012 above |
启动服务,并且配置自动启动
1 | net start sshd |
配置 sshd
这一步是最关键的,也是最容易报错的。
基础配置项
在 Windows
环境下,sshd
的配置文件和相关的证书日志,都会存放在 C:\ProgramData\ssh
下,这点需要注意,安装路径存放这一份默认的配置,这个只是为了恢复使用的。官方的安装手册的第7条有介绍:
To use existing customized sshd_config, you need to copy it from binary location to %programdata%\ssh\sshd_config (Note that %programdata% is a hidden directory).
使用 password authentication
1 | PasswordAuthentication yes |
使用 key authentication
(可选)
1 | PubkeyAuthentication yes |
配置子系统
1 | Subsystem powershell c:/program files/powershell/6.0.4/pwsh.exe -sshs -NoLogo -NoProfile |
这里需要说明,如果遇到问题,可以是因为配置子系统的路径中有空格导致,这也是一个目前还是 Open
的 Issue。可以通过创建 symlink
来解决这个问题。
首先我们将原始 PowerShell
的安装路径创建一个 symlink
,这里注意,如果在 PowerShell
中执行 mklink
需要加 cmd /c
因为这个执行不是 PowerShell
的,参考该回答。
1 | cmd /c mklink /D c:\pwsh "C:\Program Files\PowerShell\6-preview" |
然后我们就用 symlink
来配置子系统,这样就排除了空格的问题。
1 | Subsystem powershell c:\pwsh\pwsh.exe -sshs -NoLogo -NoProfile |
https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH
重启服务
1 | Restart-Service sshd |
问题排查
我们一般通过开启调试日志的方式调试 sshd
,官方有专门的 Troubleshooting 页面,一般我们开启调试配置。
删除原有的日志文件,在配置文件 sshd_config
增加如下条目
1 | SyslogFacility LOCAL0 |
然后重启
1 | Stop-Service sshd |
这时候访问就会产生日志文件,写入 log
文件夹中。
Linux 客户端配置
本人使用 Fedora
,其他的发行版基本是一样的。
首先在 Linux
上安装 PowerShell
, 参考该文:Installing PowerShell Core on Linux。
Ubuntu, Debian
1 | sudo apt-get install -y powershell |
CentOS, RedHat1
2sudo yum install -y powershell
sudo yum install -y powershell-preview
OpenSUSE1
2sudo zypper install powershell
sudo zypper install powershell-preview
Fedora1
2sudo dnf install -y powershell
sudo dnf install -y powershell-preview
安装好后就可以使用 PowerShell
,直接使用 pwsh 命令进入 PowerShell
的命令行窗口。
然后使用如下指令远程连接到服务器:
1 | Enter-PSSession -HostName [IP or HostName] -UserName Administrator |
当然按照官方文档所述,还可以定义 $session
变量,然后通过变量登陆。
1 | $session = New-PSSession -HostName UbuntuVM1 -UserName TestUser |
常见问题
subsystem request failed on channel 0
检查 sshd
的子系统的配置,有可能是空格问题,使用 symlink
配置。
sshd 日志:CreateProcessAsUser failed error:1314
“To resolve this problem, you’ll need to elevate the rights of the account calling CreateProcessAsUser with the “Replace a process level token” right. To do so, open the Control Panel / Administrative Tools / Local Security Policy and add the user account to the “Replace a process level token” right. (You may have to logout or even reboot to have this change take effect.)”
主要就是在 Control Panel / Administrative Tools / Local Security Policy
找到 Replace a process level token
权限,然后将需要远程连接的用户的加入到这个权限中. 需要重启电脑.
总结
通过这个配置,我们就可以针对 Windows
服务器进行 Devops
,比如 GitLab
就支持执行 PowerShell
脚本,参考:Shells supported by GitLab Runner