runsisi's

technical notes

在 Win7 上安装 OpenSSH

2020-01-06 runsisi#ssh

很多时候 Windows 只是用来作为跳板机使用,我们真实需要访问的目的机器实际上是 Linux 机器,如果使用远程桌面来访问 Windows 机器,然后再用 putty 之类的 SSH 客户端远程 Linux 机器的话,非常累赘,特别是当网络不好的时候,远程桌面的卡顿会要人命,而且除非 server 版本,通常 Windows 桌面同时只允许一个用户进行登录,这一点在多人共用环境的情况下非常麻烦。

显然,在 Windows 跳板机上安装上 OpenSSH 套件是一个非常好的主意。

安装

首先从 Win32-OpenSSH release 页面下载对应的 OpenSSH 安装包。

将安装包解压到任意目录,然后以管理员权限打开 PowerShell,并切换到解压后的 OpenSSH 目录:

PS C:\Windows\system32> cd 'D:\Program Files\OpenSSH-Win64'
PS D:\Program Files\OpenSSH-Win64> ls


    Directory: D:\Program Files\OpenSSH-Win64


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-----         2019/6/21      5:42      15539 FixHostFilePermissions.ps1
-----         2019/6/21      5:42      13860 FixUserFilePermissions.ps1
-----         2019/6/21      5:42      15665 install-sshd.ps1
-----         2019/6/21      5:42    1624344 libcrypto.dll
-a---          2020/1/6     18:55       3123 openssh-events.man
-----         2019/6/21      5:42      14299 OpenSSHUtils.psd1
-----         2019/6/21      5:42      40543 OpenSSHUtils.psm1
-----         2019/6/21      5:42     344864 scp.exe
-----         2019/6/21      5:42     346392 sftp-server.exe
-----         2019/6/21      5:42     413464 sftp.exe
-----         2019/6/21      5:42     521008 ssh-add.exe
-----         2019/6/21      5:42     401688 ssh-agent.exe
-----         2019/6/21      5:42     677656 ssh-keygen.exe
-----         2019/6/21      5:42     560408 ssh-keyscan.exe
-----         2019/6/21      5:42     162584 ssh-shellhost.exe
-----         2019/6/21      5:42     941336 ssh.exe
-----         2019/6/21      5:42    1045296 sshd.exe
-----         2019/6/21      5:42       2297 sshd_config_default
-----         2019/6/21      5:42      14006 uninstall-sshd.ps1

执行安装脚本:

PS D:\Program Files\OpenSSH-Win64> powershell.exe -ExecutionPolicy Bypass -File .\install-sshd.ps1
[SC] SetServiceObjectSecurity SUCCESS
[SC] ChangeServiceConfig2 SUCCESS
[SC] ChangeServiceConfig2 SUCCESS
sshd and ssh-agent services successfully installed

配置

在 Windows 防火墙中添加规则放行 22 端口的流量:

fw

最后,启动 SSH 服务:

server

至此,安装工作就全部完成了。

体验

使用 SSH 登录 Windows 跳板机,然后 SSH 登录远程 Linux 机器:

$ ssh runsisi@10.123.123.123
runsisi@10.123.123.123's password:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

runsisi@hust C:\Users\runsisi>ssh runsisi@10.234.234.234
The authenticity of host '10.234.234.234 (10.234.234.234)' can't be established.
ECDSA key fingerprint is SHA256:Uj7dAY42uwHkxJiWrS7LHf43+kz54k+lszs97kyM/rQ.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.234.234.234' (ECDSA) to the list of known hosts.
runsisi@10.234.234.234's password:
Last login: Mon Jan  6 18:30:22 2020 from 10.123.123.123

使用 sftp 访问远程 Windows 跳板机:

$ sftp runsisi@10.123.123.123
runsisi@10.123.123.123's password:
Connected to 10.123.123.123.
sftp> lpwd
Local working directory: /home/runsisi
sftp> pwd
Remote working directory: /C:/Users/10140149

使用 SSH 登录 Windows 跳板机,然后 sftp 访问远程 Linux 机器:

runsisi@hust C:\Users\runsisi>sftp runsisi@10.234.234.234
runsisi@10.234.234.234's password:
Connected to runsisi@10.234.234.234.
sftp> lpwd
Local working directory: c:\users\runsisi
sftp> pwd
Remote working directory: /home/runsisi

注意:SSH/sftp 登录 Windows 跳板机账号为 Windows 账号。

自定义 OpenSSH

$ ssh runsisi@10.123.123.123
runsisi@10.123.123.123's password:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

runsisi@hust C:\Users\runsisi>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\runsisi> cd c:/
PS C:\> ls -Force


    Directory: C:\


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d--hs         2019/7/10     15:36            Config.Msi
d--hs         2009/7/14     13:08            Documents and Settings
d----         2018/8/30      8:04            Intel
d----        2018/12/23     22:49            Packages
d----         2009/7/14     11:20            PerfLogs
d-r--        2018/11/10     16:45            Program Files
d-r--         2019/6/15     16:21            Program Files (x86)
d--h-          2020/1/6     18:04            ProgramData
d----          2019/7/4      8:12            Quarantine
d--hs          2018/8/3      8:09            Recovery
d--hs          2020/1/3      0:02            System Volume Information
d--h-          2020/1/6     18:20            tmp
d-r--          2018/8/3      8:20            Users
d----        2019/12/30      9:48            Windows
-a-hs        2018/12/23     22:49         37 pagefile.dat
-a-hs          2020/1/6     18:13 4157857792 pagefile.sys
-a-hs        2018/12/23     22:49         13 serial.dat


PS C:\> cd ProgramData
PS C:\ProgramData> ls


    Directory: C:\ProgramData


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          2018/8/3      8:31            DsmTraceLog
d----          2018/8/3      8:15            GroupPolicy
d----        2019/12/30      9:49            Local Settings
d---s         2018/8/27      9:40            Microsoft
d----         2019/3/20     13:43            Package Cache
d----          2020/1/6     18:04            ssh

PS C:\ProgramData> cd ssh
PS C:\ProgramData\ssh> ls


    Directory: C:\ProgramData\ssh


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          2020/1/6     18:04            logs
-a---          2020/1/6     19:03          6 sshd.pid
-a---         2019/6/21      5:42       2297 sshd_config
-a---          2020/1/6     18:04       1405 ssh_host_dsa_key
-a---          2020/1/6     18:04        623 ssh_host_dsa_key.pub
-a---          2020/1/6     18:04        537 ssh_host_ecdsa_key
-a---          2020/1/6     18:04        195 ssh_host_ecdsa_key.pub
-a---          2020/1/6     18:04        432 ssh_host_ed25519_key
-a---          2020/1/6     18:04        115 ssh_host_ed25519_key.pub
-a---          2020/1/6     18:04       2622 ssh_host_rsa_key
-a---          2020/1/6     18:04        587 ssh_host_rsa_key.pub

显然通过编辑 sshd_config 就可以自定义配置 SSH 服务端了,比如更改监听端口等(修改配置文件之后记得重启 OpenSSH 服务)。

当然,如果要真正最大化 Windows 的命令行体验,可能需要安装 MinGW 或者 Cygwin 等工具。

公钥登录

我们首先尝试将 SSH 公钥添加到用户 .ssh 目录下的 authorized_keys 文件中:

PS C:\Users\runsisi\.ssh> ls


    Directory: C:\Users\runsisi\.ssh


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          2020/1/6     18:43        176 known_hosts

由于 SSH 对文件、文件夹的权限有严格的要求,所以修复相关的权限:

PS C:\Users\runsisi> cd 'D:\Program Files\OpenSSH-Win64'
PS D:\Program Files\OpenSSH-Win64> powershell.exe -ExecutionPolicy Bypass -File .\FixHostFilePermissions.ps1
  [*] C:\ProgramData\ssh\sshd_config

Need to remove the inheritance before repair the rules.
Shall I remove the inheritace?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): y
Inheritance is removed from 'C:\ProgramData\ssh\sshd_config'.

'NT AUTHORITY\Authenticated Users' should not have access to 'C:\ProgramData\ssh\sshd_config'..
Shall I remove this access?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"): y
'NT AUTHORITY\Authenticated Users' has no more access to 'C:\ProgramData\ssh\sshd_config'.
      Repaired permissions

  [*] C:\ProgramData\ssh\ssh_host_dsa_key
      looks good

  [*] C:\ProgramData\ssh\ssh_host_dsa_key.pub
      looks good

  [*] C:\ProgramData\ssh\ssh_host_ecdsa_key
      looks good

  [*] C:\ProgramData\ssh\ssh_host_ecdsa_key.pub
      looks good

  [*] C:\ProgramData\ssh\ssh_host_ed25519_key
      looks good

  [*] C:\ProgramData\ssh\ssh_host_ed25519_key.pub
      looks good

  [*] C:\ProgramData\ssh\ssh_host_rsa_key
      looks good

  [*] C:\ProgramData\ssh\ssh_host_rsa_key.pub
      looks good

  [*] C:\Users\10140149\.ssh\authorized_keys
      looks good

   Done.

PS D:\Program Files\OpenSSH-Win64> powershell.exe -ExecutionPolicy Bypass -File .\FixUserFilePermissions.ps1
   Done.

但仍然无法使用公钥登录。

因此,编辑 sshd_config 配置文件,打开服务端的日志记录:

# Logging
SyslogFacility LOCAL0
LogLevel DEBUG3

重启 OpenSSH 服务,查看日志如下:

PS C:\Programdata\ssh\logs> ls


    Directory: C:\Programdata\ssh\logs


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          2020/1/7      9:52        468 sshd.log

PS C:\Programdata\ssh\logs> cat .\sshd.log
11280 2020-01-07 09:52:42.265 debug1: trying public key file __PROGRAMDATA__/ssh/administrators_authorized_keys
11280 2020-01-07 09:52:42.266 debug3: Failed to open file:C:/ProgramData/ssh/administrators_authorized_keys error:2
11280 2020-01-07 09:52:42.266 debug1: Could not open authorized keys '__PROGRAMDATA__/ssh/administrators_authorized_keys': No s
uch file or directory
11280 2020-01-07 09:52:42.266 debug3: mm_answer_keyallowed: publickey authentication test: RSA key is not allowed

显然,是因为 SSH 登录所使用的用户(即 runsisi)属于管理员组,OpenSSH 会去 C:/ProgramData/ssh/administrators_authorized_keys 文件中读取用户公钥,因此解决办法很简单,首先创建该文件:

PS C:\programdata\ssh> New-Item -ItemType file administrators_authorized_keys


    Directory: C:\programdata\ssh


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          2020/1/7     10:34          0 administrators_authorized_keys

然后将登录用户的公钥添加到 C:/ProgramData/ssh/administrators_authorized_keys 即可。

如果重启 OpenSSH 服务之后,公钥登录仍然失败,且服务端日志中有类似如下的错误:

11636 2020-01-07 10:17:01.507 debug3: Bad permissions. Try removing permissions for user: NT AUTHORITY\\Authenticated Users (S-
1-5-11) on file C:/ProgramData/ssh/administrators_authorized_keys.
11636 2020-01-07 10:17:01.508 Authentication refused.
11636 2020-01-07 10:17:01.508 debug3: mm_answer_keyallowed: publickey authentication test: RSA key is not allowed

则需要手工修复 administrators_authorized_keys 文件的权限:

// 查看文件权限
PS C:\programdata\ssh> icacls administrators_authorized_keys
administrators_authorized_keys NT AUTHORITY\SYSTEM:(I)(F)
                               BUILTIN\Administrators:(I)(F)
                               NT AUTHORITY\Authenticated Users:(I)(RX)

Successfully processed 1 files; Failed processing 0 files
// 删除继承自文件夹的权限
PS C:\programdata\ssh> icacls administrators_authorized_keys /inheritance:r
processed file: administrators_authorized_keys
Successfully processed 1 files; Failed processing 0 files
PS C:\programdata\ssh> icacls administrators_authorized_keys
administrators_authorized_keys
Successfully processed 1 files; Failed processing 0 files
// 添加正确的权限(使用 OpenSSH 自带的 fix 脚本修复权限,然后照抄当前目录下其它文件的权限即可)
PS C:\programdata\ssh> icacls administrators_authorized_keys /grant 'BUILTIN\Administrators:(F)' /grant 'NT AUTHORITY\SYSTEM:(F)'
processed file: administrators_authorized_keys
Successfully processed 1 files; Failed processing 0 files
PS C:\programdata\ssh> icacls administrators_authorized_keys
administrators_authorized_keys NT AUTHORITY\SYSTEM:(F)
                               BUILTIN\Administrators:(F)

Successfully processed 1 files; Failed processing 0 files

最后记得关闭日志,并重启 OpenSSH 服务。

尝试公钥登录:

$ ssh runsisi@10.123.123.123 -i ~/.ssh/id_rsa -p 2222
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

runsisi@hust C:\Users\runsisi>cls
runsisi@hust C:\Users\runsisi>powershell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\runsisi>

cls 将刷新终端显示,完美:)

如果再配合 SSHFS 在本地访问远程的 Windows 文件系统,简直不要太方便:

$ sshfs -p 2222 10140149@10.123.123.123:d:/ win7
The authenticity of host '[10.123.123.123]:2222 ([10.123.123.123]:2222)' can't be established.
ECDSA key fingerprint is SHA256:9hcTNIprZDxG7ooILOyKd1iZbz45/IBfO5Yb8nSbEzo.
Are you sure you want to continue connecting (yes/no)? yes
$ ls win7/
'~$15下半年述职报告.doc'         boot          Config.Msi   Greensoftware  'Program Files'        'Program Files (x86).old'   setup.exe   squid.conf                   upgrade
 autorun.inf                     bootmgr       cygwin64    '$LBak'         'Program Files.old'    '$RECYCLE.BIN'              sources     support                      Users
'$baksd'                         bootmgr.efi   efi          pagefile.dat   'Program Files (x86)'   serial.dat                 Squid      'System Volume Information'   workingcopy
$ sudo umount win7
$ sshfs -p 2222 10140149@10.123.123.123:/ win7
$ ls win7/
C:  D:  E:

参考资料

How to install OpenSSH on Windows 7 / 10

http://fred151.net/site/2018/09/23/how-to-install-openssh-on-windows-7-10/

Installing SFTP/SSH Server on Windows using OpenSSH

https://winscp.net/eng/docs/guide_windows_openssh_server

Public Key Authentication Windows Port of OpenSSH

https://serverfault.com/questions/873064/public-key-authentication-windows-port-of-openssh

TTY PTY support in Windows OpenSSH

https://github.com/PowerShell/Win32-OpenSSH/wiki/TTY-PTY-support-in-Windows-OpenSSH

About Execution Policies

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-6