# Part 0. 序

本文始于作者的某些需要接触了 Termux 与 SSH, 在身为小白的摸索当中整理总结出来的一些内容,自身水平有限,行文比较琐碎,如需要请酌情参考.

仅此做个记录,方便路过翻看的人也方便自己后来查阅。本文中笔者主要想使用 SSH 实现手机与 Windows 互访,需要一台搭载 Windows 系统的机器以及一部安装了 Termux App 的安卓手机 / 平板.

# 食用注意

  • 文章结合了互联网与个人实践,部分参考自个人博客、部分国内外论坛及官方文档,所用参考文献均位于文末 "参考文章" 处,请自行查阅.

  • 由于本文主讲 Windows 平台,故如无特别说明,本文在 Windows 平台上的命令操作都在 Windows PowerShell 完成.

  • 文章将尽可能完整地介绍使用 SSH 实现 "手机 / 平板 - PC" 互仿,但前期将主要讨论如何从手机端访问 PC 端,PC 端访问手机端将作为补充内容穿插其中以免内容过于冗杂,行文琐碎,如有不便请见谅.

  • 本文将着重介绍 SSH 的安装使用,至于 Trtmux 的安装与使用详见这里.

# Part 1. SSH 与 SSH 协议

首先,我们来了解一下 SSH 以及 SSH 协议。先看下官方怎么说:

SSH(Secure Shell) 指的是一个软件包,支持在不安全的网络上进行安全的系统管理和文件传输。几乎每个数据中心和每个大型企业都使用它。

SSH 协议使用加密来保护客户端和服务器之间的连接。所有用户身份验证、命令、输出和文件传输都进行了加密,以防止网络中的攻击。

也就是说 (粗略理解), SSH 是一整套加密通讯服务与手段,包括 SSH 加密算法、传输方式、客户端与服务端等。大致过程为:我们先在自己的设备 (称为客户端 Client) 和想要访问的设备 (称为服务端 Server) 上各自部署好 SSH 服务,设定好加密密钥然后就能进行通讯,通讯的内容经 SSH 协议加密后在公共网络中传输,借此实现在不安全的网络环境中通讯.

了解完概念,接下来我们将从零开始尝试在服务端和客户端之间搭建 OpenSSH 服务并使用它.

# Part 2. 服务端的准备

OpenSSH 的操作建议在 PowerShell 上完成,并且最好以管理员身份运行,因为 Powershell 支持一部分 Linux 指令,功能更强大.

  1. 安装 OpenSSH 服务

OpenSSH 服务包括两部分:服务端和客户端,如果你只想将 Windows 作为 SSH 服务端,只需要安装 OpenSSH 服务器即可,反之只选择安装 OpenSSH 客户端。当然也可以一同安装,实现互相访问. Microsoft 官方给出的 Windows 下安装 OpenSSH 服务有三种方法,任选一种即可.

  • 通过内置模块方式安装

最简单的方法,不能保证安装的服务版本使最新的,但开箱即用.

在 "设置 > 应用和功能 > 可选功能 > 添加功能" 中搜索 “OpenSSH 服务器”(若作为客户端则选择 "OpenSSH 客户端"), 勾选前面的框框,然后点击下方的 "安装", 等待自动下载即可.

  • 通过 GitHub 安装

使用此方法可以获取最新的 SSH 版本。项目地址: PowerShell/OpenSSH-Portable

注意:通过 GitHub 安装 OpenSSH 可能不适用参考本文章!

  • 通过 PowerShell 安装

官方教程地址: Microsoft: 通过 PowerShell 安装 OpenSSH

  1. 获取服务端地址与端口号

一般来讲,我们使用 SSH 进行访问时需要知道服务端的 ip 地址还有端口号 (例如 GitHub 的 ip 地址是 140.82.112.4 ).

Windows 上查询当前 ip 地址可以在 Powershell 输入 ipconfig , 并在输出结果中找到以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
Wireless LAN adapter WLAN:

Connection-specific DNS Suffix . :
IPv6 Address. . . . . . . . . . . : xxx:xxx:xxx:xxx:xxx:xxx:xxx:xxx
Temporary IPv6 Address. . . . . . : xxx:xxx:xxx:xxx:xxx:xxx:xxx:xxx
Temporary IPv6 Address. . . . . . : xxx:xxx:xxx:xxx:xxx:xxx:xxx:xxx
Temporary IPv6 Address. . . . . . : xxx:xxx:xxx:xxx:xxx:xxx:xxx:xxx
Link-local IPv6 Address . . . . . : xxx::xxx:xxx:xxx:xxx
IPv4 Address. . . . . . . . . . . : xx.xx.xx.xx
Subnet Mask . . . . . . . . . . . : xx.xx.xx.xx
IPv4 Address. . . . . . . . . . . : xx.xx.xx.xx
Subnet Mask . . . . . . . . . . . : xx.xx.xx.xx
Default Gateway . . . . . . . . . : xx.xx.xx.xx

其中的 IPv4 Address 后的四组数就是本机当前的 ip 地址.

# 对于 DHCP 分配的 ip 地址

由于服务端开启 DHCP 会导致 ip 地址发生变化,使得我们难以连接到服务端,因此在条件允许的情况下为服务端关闭 DHCP.

如果条件不允许 (例如校园网), 可以尝试使用静态 ip. 具体方法为:

在任务栏的 "网络" 处右键,选择 "打开’网络和 Internet’设置", 选择当前连接到的网络,找到 "ip 设置", 选择 "编辑", 将 "自动 (DHCP)“改为" 手动”, 然后打开 "ipv4", ip 地址填入上文获取到的 ip 地址,填写 "子网前缀长度"、“网关”、“首选 DNS"和" 备用 DNS”, 最后点击保存,等待重新连接网络即可.

  • 关于子网前缀长度与网关的关系可以上网搜索,或者从手机处获取.
  1. 查看客户端用户名称

在 PowerShell 中查看当前用户名可以输入以下命令:

1
whoami

返回的格式为 "你的 PC 名 \ 当前登录的用户名"

# Part 3. 客户端的准备

  1. 安装 OpenSSH 服务

Termux 安装 OpenSSH 只需要一条命令即可:

1
2
3
pkg install openssh
# 或者使用下面的简写命令, 两者都是安装 OpenSSH 的命令
pkg i openssh

需要注意的是,Termux 模拟的系统不同于一般的 Linux, 它的SSH 服务端与客户端安装是一起的, 运行上述命令会一同安装好服务端与客户端,而真正的 Linux 系统两者是分开安装的.

  1. 查看本机 ip 地址

在 Termux 终端运行以下命令 (请注意第二个字母是 f 不是 p !):

1
ifconfig

在输出结果中找到以下部分 (通常在最后):

1
2
3
4
5
6
7
8
9
10
wlan0: flags=xxxx<UP,BROADCAST,RUNNING,MULTICAST>  mtu xxxx
inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx broadcast xxx.xxx.xxx.xxx
inet6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx prefixlen xxx scopeid 0x0<global>
inet6 xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx prefixlen xxx scopeid 0x0<global>
inet6 xxxx::xxxx:xxxx:xxxx:xxxx prefixlen xxx scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 1000 (UNSPEC)
RX packets xxxxxx bytes xxxxx (xxx MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets xxxxxx bytes xxxxx (xxxx MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

其中 inet 后的四组数就是本机的 ip 地址.

  1. 查看用户名

与 PowerShell 一样,查看用户名只需要输入以下命令:

1
whoami

返回格式一般类似 "xx_xxx" 这样带下划线的名称,每个用户返回的名称都不一样. 记住这个用户名,后面要用到.

# Part 3. 使用用户名与密码连接

知道了两者的 ip 地址,我们还需要两者开放的端口才能进行通讯。一般情况下,SSH 的数据传输端口默认都是 22, 而手机出于安全考虑,对上数值比较小的端口管的比较严,因此手机上的 SSH 开放的是 8022 端口. 端口号可以在配置文件里自行更改,这里直接使用默认的端口号.

获取了服务端的与客户端的信息后 (ip 地址,端口,用户名), 我们就能够开始尝试连接了:

  • 从 Termux 访问 Windows

首先,以管理员身份在 Windows 的 PowerShell 中输入以下命令启动 ssh 服务:

1
2
# 注意此时Windows是作为服务端, 服务名称应该是sshd而不是ssh
net start sshd

然后在 Termux 输入以下命令即

1
ssh WinUser@win_ip
  • 从 Windows 访问 Termux
1
ssh TermuxUser@termux_ip -p 8022

连接服务端时,需要提供用户名和密码。用户名可以在 Powershell 输入 whoami 获取,返回的结果为 计算机名\当前用户名 ,如果当前用户使用 Microsoft 账户登录,则密码为当前用户 Microsoft 账号的密码;如果当前用户使用本地管理员账户 (域账户), 则密码对应本地管理员账户的登录密码.

# Part 4. 使用免密登录

完成前面的操作之后我们会发现:每一次传输文件都需要输入密码,很是麻烦, 而且可能有人还是对通讯过程的安全性有顾虑。那么,有没有什么办法能做到既不用密码登录又能保证通讯过程安全呢?答案是:有的。所以接下来将介绍如何免密使用 SSH 登录与访问.

# Windows 免密登录 Termux

Windows 使用

# Termux 免密登录 Windows

Tremux 免密登录 Windows 比较特别,由于 SSH 本身对免密登录的账户及文件夹权限限制比较多,所以需要为特定的文件和文件夹设置权限.
然而网络上大多数教程针对的是 Linux 文件夹权限的修改,我最后所找到的解决办法在 Windows 官方文档里 (微软的文档真的给力).

此处按登录的用户在 Windows 中的分组有几种情况:用户为管理员身份 (在 Administrators 组中)、用户为标准用户身份 (不在 Administrators 组中).

# a. 登录用户为标准用户

  1. 确保 Windows 上有名为 ssh 的文件夹,同时用户有权访问该文件夹及子文件夹.

Windows 安装 SSH 服务后,一般会在 C:\ProgramData 下创建一个叫 ssh 的文件夹,存放的是作为 ssh 服务器时的配置。当使用 Windows 作为 ssh 客户端时,一般会在 C:\Users\用户名 下生成一个叫.ssh 的文件夹,用来存放作为 ssh 客户端的配置;如果找不到.ssh 文件夹则需要自己在这个目录下创建一个.

如果没有.ssh 文件夹可以通过以下命令远程创建:

1
2
3
# 这里填的是要登陆服务器的用户名与服务器地址
# 其中的username为用户名, domain1@contoso.com为服务端的ip地址或域名
ssh username@domain1@contoso.com mkdir C:\Users\username\.ssh\
  1. 将本地生成的

    公钥

    发送到 Windows 服务器
1
2
# 将本地生成的公钥发送到服务端的authorized_key中
scp ~\.ssh\id_ed25519.pub user1@domain1@contoso.com:C:\Users\username\.ssh\authorized_keys

# b. 登录用户为管理员

  1. 首先要确保 Windows 上有名为 ssh 的文件夹,如果没有可以通过以下命令远程创建:
1
2
# 即: 要登录Win的用户名@服务器ip地址
ssh user1@domain1@contoso.com mkdir C:\ProgramData\ssh\
  1. 将本地生成的

    公钥

    (带.pub 后缀那个) 发送到 Windows 服务器.

1
scp C:\Users\username\.ssh\id_ed25519.pub user1@domain1@contoso.com:C:\ProgramData\ssh\administrators_authorized_keys

请注意,此时是将公钥存放到 C:\ProgramData\ssh 文件夹而不是用户文件夹,而且要将公钥文件 (含后缀) 改名为 administrators_authorized_keys .

  1. 配置 ACL

在客户端命令如下:

1
ssh --% WinUser@domain1@contoso.com icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

在服务端则直接输入以下命令 (在服务端是全局命令,不需要考虑命令执行的位置):

1
icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
  1. 重启服务端
1
2
net stop sshd
net start sshd

# Part 5. 管理多个服务器 / 客户端用户

当我们通过生成密钥对的方式实现免密登录后,如果要登录的主机比较多,我们就需要记住很多组用户名与 ip 地址,这时候我们就想有一个方法,将每个要访问的服务器 / 客户端的信息贴上一个标签,然后通过输入标签来访问服务器,这就是 config 文件在做的事. config 文件中按规范记录了每个服务器 / 客户端的 ip 地址、用户名、访问端口与密码等,并为每个对象贴上一个可以自定义的标签,我们只需要配置好标签的信息就能直接通过标签进行 SSH 访问,非常方便,下面介绍方法.

config 文件书写格式如下:

1
2
3
4
5
Host github
HostName 140.82.112.4
User git
Port 22
IdentityFile ~/.ssh/id_rsa

或者不使用缩进,其格式如下:

1
2
3
Host github
HostName 140.82.112.4
User git

需要注意的是 config 文件需要自己创建。同时配置文件是放在.ssh 文件夹下, 注意不要搞错了.
而皮质文件可用的具体选项及说明可以一查看官方文档 https://www.ssh.com/academy/ssh/config

1
2
3
4
5
6
Host Termux
HostName 140.233.43.123
Port 8022
User u0_a312
IdentityFile ~/.ssh/id_rsa_MyTermux
passwordAuthentication no

IdentityFile 是指定连接时校验的密钥;passwordAuthentication 是密码认证,如果使用密钥登录(免密登录)则关闭它避免每次连接都要输入密码.

# Windows 配置

1
2
3
4
5
Host termux(别名, 随便起)
HostName Termux的ip
User 登录Termux的用户名
IdentityFile ~/.ssh/私钥a
passwordAuthentication no

# Termux 配置

1
2
3
4
5
HostName win10(别名, 方便自己记)
HostName windows的ip
User 登录Windows的用户名
IdentityFile ~/.ssh/私钥b
passwordAuthentication no

# 连接和使用

在完成了上述配置后,双方开启 sshd 服务就能使用了.

1
2
3
4
5
# Windows连接Termux
ssh Termux

# Termux连接Windows
ssh win10

# 参考文章

  • 【国光的个人博客】Trtmux 高级终端安装配置使用教程

  • 【CSDN(转载)】windows 无法使用 ssh-copy-id 解决办法

  • 【简书(原文)】Windows 下设置 SSH 免密

  • 【superuser】OpenSSH not accepting my login password

  • 【Microsoft】OpenSSH 密钥管理