随着PowerShell和OpenSSH的日渐成熟,在客户终端Windows居多的运维之中,使用Win32-OpenSSH和Powershell来管理一些客户机变成了相当实用的一种解决方案。
OpenSSH 是安全 Shell (SSH) 工具的开放源代码版本,Linux 及其他非 Windows 系统的管理员使用此类工具跨平台管理远程系统。
SSH 基于客户端-服务器体系结构,用户在其中工作的系统是客户端,所管理的远程系统是服务器。 OpenSSH 包含一系列组件和工具,用于提供一种安全且简单的远程系统管理方法,其中包括:
sshd.exe,它是远程所管理的系统上必须运行的 SSH 服务器组件
ssh.exe,它是在用户的本地系统上运行的 SSH 客户端组件
ssh-keygen.exe,为 SSH 生成、管理和转换身份验证密钥
ssh-agent.exe,存储用于公钥身份验证的私钥
ssh-add.exe,将私钥添加到服务器允许的列表中
ssh-keyscan.exe,帮助从许多主机收集公用 SSH 主机密钥
sftp.exe,这是提供安全文件传输协议的服务,通过 SSH 运行
scp.exe 是在 SSH 上运行的文件复制实用工具
本篇重点主要介绍如何在 Windows 上使用 OpenSSH,包括安装以及使用过程当中会出现的问题和解决办法
在 Windows Server 2019 和 Windows 10 1809 中,OpenSSH 客户端和 OpenSSH 服务器是可单独安装的组件。 具有这些 Windows 版本的用户可以直接安装和配置 OpenSSH
但是,很多人使用的Windows版本都是有被精简过的,不一定能直接通过“应用”>“应用和功能”>“管理可选功能”这种办法来直接安装配置。
碰上这种情况最直接的办法就是直接在Github上面下载。
Win32-OpenSSH下载地址(文章所用的版本是v8.1.0.0p1-Beta)
https://github.com/PowerShell/Win32-OpenSSH
PowerShell下载地址(文章所用的版本是v7.1.0)
https://github.com/PowerShell/PowerShell
下载下来的是这样的:
若要配置 OpenSSH 服务器以在 Windows 上首次使用,请以管理员身份启动 PowerShell,然后运行以下命令来启动 SSHD 服务:(有防火墙的需要这样设置,我自己默认都是关闭Windows防火墙)
Start-Service sshd#OPTIONAL but recommended:
Set-Service -Name sshd -StartupType 'Automatic'#Confirm the Firewall rule is configured. It should be created automatically by setup.
Get-NetFirewallRule -Name *ssh*
#There should be a firewall rule named "OpenSSH-Server-In-TCP", which should be enabled#If the firewall does not exist, create one
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
首次使用 SSH(使用密码验证方式)
重点,在直接使用SSH的过程当中,Windows的用户(远程客户端)需要设置密码,Windows通过SSH的验证方式有两种,一种是使用密码,一种密钥对。
在Windows用户(远程客户端)已经有设置密码的情况下可以通过下面的方式进行连接。
在 Windows 上安装 OpenSSH 服务器后,可以从安装了 SSH 客户端的任何 Windows 设备上使用 PowerShell 来快速测试它。 在 PowerShell 中,键入以下命令:
Ssh administrator@D1
到任何服务器的第一个连接都将生成类似以下内容的消息:
The authenticity of host 'servername (10.00.00.001)' can't be established.
ECDSA key fingerprint is SHA256:().
Are you sure you want to continue connecting (yes/no)?
回答必须是“yes”或“no”。 回答 Yes 会将该服务器添加到本地系统的已知 ssh 主机列表中。
系统此时会提示你输入密码。 作为安全预防措施,密码在键入的过程中不会显示。
在连接后,你将看到类似于以下内容的命令 shell 提示符:
Administrator@D1 C:\Users\Administrator>
Windows OpenSSH 服务器使用的默认 shell 是 Windows 命令行解释器,这个默认Shell可以通过注册表进行修改,比方改成PowerShell.
为 Windows 中的 OpenSSH 配置默认 shell
默认命令 shell 提供用户使用 SSH 连接到服务器时看到的体验。 初始默认 Windows 是 Windows Command shell (cmd.exe)。 Windows 还包括了 PowerShell 和 Bash,第三方命令 shell 也可用于 Windows,并可配置为服务器的默认 shell。
在HKEY_LOCAL_MACHINE\SOFTWARE\OpenSSH注册表下添加字符串值DefaultShell,把shell 可执行文件的完整路径添加上去就可以
再次使用 SSH(使用密钥对验证方式)
使用密码方式验证这种方式,简单粗暴,但是假如远程客户端的密码设置有的设置123456,有的设置abcefg等这种乱七八糟的时候,不太可能针对每台机子去记住对应的密码,自然而然的这种通过密钥对的方式就更受维护人员的喜欢。
密钥对验证方式可是理解成,每一台机子都分别安装了一把锁,这把锁只有对应的钥匙才能开启,一把钥匙对应一把锁这个大家都很容易理解,像日常生活当中,锁是当处可见的,可是钥匙却不是那么经常见到,OpenSSH也是可以采取
这样的方式来实现的。下面是官方的说法
关于密钥对
密钥对指的是由特定的身份验证协议使用的公钥和私钥文件。
SSH 公钥身份验证使用不对称加密算法来生成两个密钥文件 – 一个为“私钥”文件,一个为“公钥”文件。 私钥文件等效于密码,在所有情况下都应当保护它们。 如果有人获取了你的私钥,则他们可以像你一样登录到你有权登录的任何 SSH 服务器。 公钥放置在 SSH 服务器上,并且可以共享,不会危害私钥的安全。
将密钥身份验证用于 SSH 服务器时,SSH 服务器和客户端会依据私钥来比较所提供的用户名的公钥。 如果无法依据客户端私钥验证服务器端公钥,则身份验证失败。
可以通过在生成密钥对时要求提供密码来通过密钥对实现多重身份验证(参见下文的密钥生成)。 在身份验证期间,会提示用户输入密码,将使用该密码以及 SSH 客户端上的私钥来对用户进行身份验证。
主机密钥生成
公钥具有特定的 ACL 要求,在 Windows 上,这些要求等同于仅允许管理员和 System 进行访问。(这个是重点)为使此更加简单,
已创建了 OpenSSHUtils PowerShell 模块来正确设置密钥 ACL,并且应当将该模块安装在服务器上
首次使用 sshd 时,将自动生成主机的密钥对。 如果 ssh-agent 正在运行,则密钥将自动添加到本地存储中。
用户密钥生成
若要使用基于密钥的身份验证,首先需要为客户端生成一些公钥/私钥对。 通过 PowerShell 或 cmd,使用 ssh-keygen 生成一些密钥文件。
ssh-keygen
应当会显示如下某些内容
添入相要放密钥对的位置,添写的是包括位置和文件名
接下会要求你输入密钥的密码(建议输入,双重认证更加安全),并要求你再次确认
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
操作完成之后,在刚刚保存密钥对的地方可以找到对应的公钥和私钥
id_rsa这个是私钥(这个就是钥匙,需要远程哪台机子的时候就使用这个),id_rsa.pub这个是公钥(这个就是锁,要先放在远程终端上面)。
部署公钥
若要使用上面创建的用户密钥,需要将公钥放置在服务器上的一个文本文件中,该文件名为 authorized_keys,默认位于 users\username\.ssh\ 下。
如果用户是归属administrators用户组时,匹配的文件位置在C:\programdata\ssh\administrators_authorized_keys
这个可以在OpenSSH配置文件进行修改
至此可以通过OpenSSH进行登录了
在使用的过程当中最经常出现的情况是
像这种权限拒绝是最经常出现的,主要因为是由于默认情况情况,公钥的权限没设置正确,默认情况下公钥的安全属性里面可以看到
在这个安全权限里面多了Authenticated Users用户组,去除掉,安全属性里面仅允许管理员和 System 进行访问。
还有一点,安全的高级安全设置里面,要把启用继承禁用掉!!!
再有一点,要取得公钥文件的所有权!!!
最后,
对于需要频繁进行远程管理的运维来说,有些仅仅只需要一行命令就可以解决问题,决不会想要进行多一步的操作,
在已经有安装了PowerShell和OpenSSH的机子情况下,比方想要重启远程的电脑只需要一行代码,决不会想先SSH登录再输入命令,可以直接采用下面的代码直接进行重启
Invoke-Command -HostName D1 -ScriptBlock { Restart-Computer -Force } -KeyFilePath "D:/id_rsa"
要想实现这种效果,需要在SSHD配置文件添加如下配置:
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo
PowerShell 可执行文件的默认位置是 c:/progra~1/powershell/7/pwsh.exe。 该位置可能因 PowerShell 安装方式而有所不同。
对于包含空格的任何文件路径,必须使用 8.3 短名称。 OpenSSH for Windows 中存在一个 bug,使空格在子系统可执行路径中无效。
然后重启Open SSH Server服务