wolfSSL/wolfssh
GitHub: wolfSSL/wolfssh
轻量级、可嵌入的 SSH/SFTP/SCP 实现库,专为嵌入式设备与资源受限环境提供安全的远程访问与文件传输能力。
Stars: 451 | Forks: 101
# WOLFSSH
wolfSSL 的可嵌入 SSH 服务器
[wolfSSH 手册](https://www.wolfssl.com/docs/wolfssh-manual/)
## 依赖项
[wolfSSH](https://www.wolfssl.com/wolfssh/) 依赖于
[wolfCrypt](https://www.wolfssl.com/download/),它是
wolfSSL 的一部分。以下是启用 wolfSSH 所需的 wolfSSL 最简配置。
```
$ cd wolfssl
$ ./configure [OPTIONS] --enable-ssh
$ make check
$ sudo make install
```
在某些系统上,安装后需要运行可选的 ldconfig 命令。
要使用 wolfSSH 中的密钥生成功能,wolfSSL 需要配置
keygen:`--enable-keygen`。
当使用 X.509 证书进行用户认证时,wolfSSL 必须
在启用 TLS 的情况下构建。wolfSSH 使用 wolfSSL 的证书管理器系统
处理 X.509,包括 OCSP 查找。要允许 OCSP,请在
wolfSSL configure 中添加 `--enable-ocsp`。
如果不需要大部分 wolfSSL 代码,可以将 wolfSSL 配置为
crypto only 选项:`--enable-cryptonly`。
wolfSSL 的其他构建选项位于
wolfSSH 手册的[第二章](https://www.wolfssl.com/docs/wolfssl-manual/ch2/)。
## 构建
在 wolfSSH 源代码目录中运行:
```
$ ./autogen.sh (if cloned from GitHub)
$ ./configure --with-wolfssl=[/usr/local]
$ make
$ make check
```
`autogen.sh` 脚本只需在克隆
仓库后首次运行时执行。如果您已经运行过它,或者正在使用
源代码归档中的代码,则应跳过此步骤。
有关在 Windows 下使用 Visual Studio 进行构建的信息,请参阅文件
"ide/winvs/README.md"。
注意:在资源受限的设备上,可能需要将 `DEFAULT_WINDOW_SZ` 设置
为较小的值。在桌面使用场景中,也可以增加该值
以协助大文件传输。默认情况下,通道设置为在发送通道窗口调整消息之前接收
最多 128kB 的数据。
为新通道设置窗口大小的示例如下
`./configure CPPFLAGS="-DDEFAULT_WINDOW_SZ=16384"`
对于 32 位 Linux 平台,您可以通过使用 `CFLAGS=-D_FILE_OFFSET_BITS=64` 编译来添加对大于 2GB 文件的支持。
## 示例
目录 `examples` 包含一个 echo 服务器,任何客户端都应该
能够连接到它。在终端中运行:
```
$ ./examples/echoserver/echoserver -f
```
选项 `-f` 启用仅 echo 模式。在另一个终端中运行:
```
$ ssh jill@localhost -p 22222
```
当提示输入密码时,输入 "upthehill"。服务器将向客户端发送一个
预设 banner:
```
wolfSSH Example Echo Server
```
在客户端输入的字符将被服务器回显到屏幕。
如果字符被回显两次,则说明客户端启用了本地回显。
echo 服务器并不是一个真正的终端,因此 CR/LF
转换将无法按预期工作。
以下控制字符将在 echo 服务器中触发特殊操作:
- CTRL-C:终止连接。
- CTRL-E:打印一些会话统计信息。
- CTRL-F:触发新的密钥交换。
## 测试说明
克隆仓库后,请务必将测试私钥设置为
仅当前用户只读,否则 `ssh` 会提示您进行此操作。
```
$ chmod 0600 ./keys/gretel-key-rsa.pem ./keys/hansel-key-rsa.pem \
./keys/gretel-key-ecc.pem ./keys/hansel-key-ecc.pem
```
对示例 echo 服务器的认证可以通过
密码或公钥完成。要使用密码,命令行为:
```
$ ssh -p 22222 USER@localhost
```
其中 *USER* 和密码对为:
```
jill:upthehill
jack:fetchapail
```
要使用公钥认证,请使用命令行:
```
$ ssh -i ./keys/USER-key-TYPE.pem -p 22222 USER@localhost
```
其中 *USER* 可以是 `gretel` 或 `hansel`,*TYPE* 是 `rsa` 或
`ecc`。
请记住,echo 服务器的 `wsUserAuth()` 回调函数中有几个虚假账户。
当启用 shell 支持时,这些虚假账户将无法工作。它们
不存在于系统的 _passwd_ 文件中。用户将通过认证,
但服务器会报错,因为它们不存在于系统中。您可以将自己的用户名添加到
echo 服务器的密码或公钥列表中。该账户将登录到由 echo 服务器启动的 shell,并具有运行 echo 服务器的用户的权限。
# 示例工具
wolfSSH 附带了一些示例工具,用于测试目的
并演示与其他 SSH 实现的互操作性。
## echoserver
echo 服务器是 wolfSSH 的主力工具。最初它只允许
认证其中一个预设账户,并会重复输入其中的字符。当启用 [shell 支持](#shell-support)时,它可以生成一个用户 shell。它需要机器上的一个实际用户名以及一个更新后的用户认证回调函数来验证凭据。
echo 服务器还可以处理 SCP 和 SFTP 连接。
echo 服务器工具接受以下命令行选项:
```
-1 exit after a single (one) connection
-e expect ECC public key from client
-E use ECC private key
-f echo input
-p port to accept on, default 22222
-N use non-blocking sockets
-d set the home directory for SFTP connections
-j load in a public key to accept from peer
```
## client
客户端建立到 SSH 服务器的连接。在其最简单的模式下,
它向服务器发送字符串 "Hello, wolfSSH!",打印响应,
然后退出。使用伪终端选项,客户端将成为一个真正的客户端。
客户端工具接受以下命令行选项:
```
-h host to connect to, default 127.0.0.1
-p port to connect on, default 22222
-u username to authenticate as (REQUIRED)
-P password for username, prompted if omitted
-e use sample ecc key for user
-i filename for the user's private key
-j filename for the user's public key
-x exit after successful connection without doing
read/write
-N use non-blocking sockets
-t use pseudo terminal
-c executes remote command and pipe stdin/stdout
-a Attempt to use SSH-AGENT
```
## portfwd
portfwd 工具建立到 SSH 服务器的连接,并设置
本地端口转发的监听器,或请求远程端口转发的监听器。连接后,工具终止。
portfwd 工具接受以下命令行选项:
```
-h host to connect to, default 127.0.0.1
-p port to connect on, default 22222
-u username to authenticate as (REQUIRED)
-P password for username, prompted if omitted
-F host to forward from, default 0.0.0.0
-f host port to forward from (REQUIRED)
-T host to forward to, default to host
-t port to forward to (REQUIRED)
```
## scpclient
scpclient,即 wolfscp,建立到 SSH 服务器的连接,并
将指定文件从本地机复制到远端机,或反之。
scpclient 工具接受以下命令行选项:
```
-H host to connect to, default 127.0.0.1
-p port to connect on, default 22222
-u username to authenticate as (REQUIRED)
-P password for username, prompted if omitted
-L : copy from local to server
-S : copy from server to local
```
## sftpclient
sftpclient,即 wolfsftp,建立到 SSH 服务器的连接,并
允许目录导航、获取和放置文件、创建和删除目录等。
sftpclient 工具接受以下命令行选项:
```
-h host to connect to, default 127.0.0.1
-p port to connect on, default 22222
-u username to authenticate as (REQUIRED)
-P password for username, prompted if omitted
-d set the default local path
-N use non blocking sockets
-e use ECC user authentication
-l local filename
-r remote filename
-g put local filename as remote filename
-G get remote filename as local filename
```
# SCP
wolfSSH 包含 scp 的服务器端支持,包括支持
将文件复制“到”服务器和从服务器复制文件“从”。在默认的发送和接收回调下,支持
单文件和递归目录复制。
要编译带有 scp 支持的 wolfSSH,请使用 `--enable-scp` 构建选项
或定义 `WOLFSSH_SCP`:
```
$ ./configure --enable-scp
$ make
```
有关完整的 API 用法和实现细节,请参阅 wolfSSH 用户
手册。
wolfSSH 示例服务器已设置为接受单个 scp 请求,
并在编译 wolfSSH 库时默认编译。要启动
示例服务器,请运行:
```
$ ./examples/server/server
```
客户端可以使用标准的 scp 命令。以下是
几个示例,其中 `scp` 代表您正在使用的 ssh 客户端。
使用默认示例用户 "jill" 将单个文件复制“到”服务器:
```
$ scp -P 22222 jill@127.0.0.1:
```
将同一单个文件复制“到”服务器,但带有时间戳并处于
详细模式:
```
$ scp -v -p -P 22222 jill@127.0.0.1:
```
递归地将目录复制“到”服务器:
```
$ scp -P 22222 -r jill@127.0.0.1:
```
将单个文件从服务器复制“到”本地客户端:
```
$ scp -P 22222 jill@127.0.0.1:
```
递归地将目录从服务器复制“到”本地客户端:
```
$ scp -P 22222 -r jill@127.0.0.1:
```
# 端口转发
wolfSSH 提供对端口转发的支持。这允许用户
设置到另一台服务器的加密隧道,其中 SSH 客户端监听
一个套接字,并将该套接字上的连接转发到服务器上的另一个套接字。
要编译带有端口转发支持的 wolfSSH,请使用 `--enable-fwd` 构建
选项或定义 `WOLFSSH_FWD`:
```
$ ./configure --enable-fwd
$ make
```
有关完整的 API 用法和实现细节,请参阅 wolfSSH 用户
手册。
portfwd 示例工具将创建一个 "direct-tcpip" 样式的通道。这些
说明假设您已让 OpenSSH 的服务器在后台运行,并
启用了端口转发。此示例将 wolfSSL
客户端的端口转发到服务器作为应用程序。它假设所有程序都
在同一台机器上的不同终端中运行。
```
src/wolfssl$ ./examples/server/server
src/wolfssh$ ./examples/portfwd/portfwd -p 22 -u \
-f 12345 -t 11111
src/wolfssl$ ./examples/client/client -p 12345
```
默认情况下,wolfSSL 服务器监听端口 11111。客户端设置为
尝试连接到端口 12345。portfwd 以用户 "username" 登录,在
端口 12345 上打开一个监听器,并连接到端口 11111 上的服务器。数据包
在客户端和服务器之间来回路由。"Hello, wolfSSL!"
portfwd 的源代码提供了一个示例,说明如何设置和使用
wolfSSH 中的端口转发支持。
echo 服务器将处理本地和远程端口转发。要使用
ssh 工具连接,请使用以下命令行之一。您可以从任何地方运行
任一 ssh 命令行:
```
src/wolfssl$ ./examples/server/server
src/wolfssh$ ./examples/echoserver/echoserver
anywhere 1$ ssh -p 22222 -L 12345:localhost:11111 jill@localhost
anywhere 2$ ssh -p 22222 -R 12345:localhost:11111 jill@localhost
src/wolfssl$ ./examples/client/client -p 12345
```
这将允许在 wolfSSL 客户端和服务器之间进行端口转发,就像
上一个示例中那样。
# SFTP
wolfSSH 提供 SFTP 版本 3 的服务器端和客户端支持。这
允许用户建立用于管理文件系统的加密连接。
要编译带有 SFTP 支持的 wolfSSH,请使用 `--enable-sftp` 构建选项或
定义 `WOLFSSH_SFTP`:
```
$ ./configure --enable-sftp
$ make
```
有关完整的 API 用法和实现细节,请参阅 wolfSSH 用户
手册。
创建的 SFTP 客户端位于目录 examples/sftpclient/ 中,
示例 echo 服务器充当 SFTP 服务器。
```
src/wolfssh$ ./examples/sftpclient/wolfsftp
```
连接后输入 "help" 可以看到
支持的命令的完整列表。
```
wolfSSH sftp> help
Commands :
cd change directory
chmod change mode
get pulls file(s) from server
ls list current directory
mkdir creates new directory on server
put push file(s) to server
pwd list current path
quit exit
rename renames remote file
reget resume pulling file
reput resume pushing file
interrupt get/put cmd
```
连接到另一个系统的示例是
```
src/wolfssh$ ./examples/sftpclient/wolfsftp -p 22 -u user -h 192.168.1.111
```
# SHELL 支持
wolfSSH 的示例 echo 服务器现在可以为尝试登录的用户派生一个 shell。目前这仅在 Linux 和 macOS 上进行了测试。文件
echoserver.c 必须被修改,以便在用户认证回调中包含用户的凭据,或者需要更改用户认证回调以验证提供的密码。
要编译带有 shell 支持的 wolfSSH,请使用 `--enable-shell` 构建选项
或定义 `WOLFSSH_SHELL`:
```
$ ./configure --enable-shell
$ make
```
要试用此功能,您可以使用示例 echo 服务器和客户端。
在终端中执行以下操作以启动服务器:
```
$ ./examples/echoserver/echoserver -P :junk
```
在另一个终端中执行以下操作以启动示例客户端:
```
$ ./examples/client/client -t -u -P junk
```
注意,`` 必须是当前登录用户的用户名。
默认情况下,echo 服务器将尝试启动一个 shell。要使用 echo 测试行为,请给 echo 服务器提供命令行选项 `-f`。
```
$ ./examples/echoserver/echoserver -f
```
要将 shell 功能与 wolfsshd 一起使用,请在您的 configure
命令中添加 `--enable-sshd`,并使用以下命令:
```
$ sudo ./apps/wolfsshd/wolfsshd -D -h keys/gretel-key-ecc.pem -p 11111
```
如果它抱怨 `sshd_config` 文件有问题,只需将其复制到另一个文件,
删除它抱怨的有问题的一行,并使用 `-f` 命令
行参数指向新文件。
然后您可以使用 ssh 连接到 `wolfsshd` 服务器:
```
$ ssh @localhost -p 11111
```
注意,`` 必须是当前登录用户的用户名。
# CURVE25519
wolfSSH 现在支持 Curve25519 用于密钥交换。要启用此支持,只需
编译支持 wolfssh 和 Curve25519 的 wolfSSL。
```
$ cd wolfssl
$ ./configure --enable-wolfssh --enable-curve25519
```
构建并安装 wolfSSL 后,您可以直接不带选项进行配置。
```
$ cd wolfssh
$ ./configure
```
wolfSSH 客户端和服务器将自动协商使用 Curve25519。
```
$ ./examples/echoserver/echoserver -f
$ ./examples/client/client -u jill -P upthehill
```
# 后量子
wolfSSH 现在支持后量子算法 ML-KEM(以前称为
Kyber)。它使用 ML-KEM-768 参数集,并与基于 P-256 ECC 曲线的 ECDHE 进行混合。
为了使用此密钥交换,您必须在您的系统上构建并安装 wolfSSL。
以下是一个有效配置的示例:
```
$ ./configure --enable-wolfssh --enable-mlkem
```
之后,只需照常配置并构建 wolfssh:
```
$ ./configure
$ make all
```
wolfSSH 客户端和服务器将自动协商使用与基于 P-256 ECC 曲线的 ECDHE 混合的 ML-KEM-768。
```
$ ./examples/echoserver/echoserver -f
$ ./examples/client/client -u jill -P upthehill
```
在客户端,您将看到以下输出:
Server said: Hello, wolfSSH!
如果您希望看到与 OpenQuantumSafe 的 OpenSSH 分支的互操作性,您
可以在 echo 服务器运行时构建并执行该分支。从
此处下载发布版本:
以下内容足以进行构建和执行:
```
$ tar xmvf openssh-OQS-OpenSSH-snapshot-2021-08.tar.gz
$ cd openssh-OQS-OpenSSH-snapshot-2021-08/
$ ./configure --with-liboqs-dir=/usr/local
$ make all
$ ./ssh -o"KexAlgorithms=mlkem768nistp256-sha256" \
-o"PubkeyAcceptedAlgorithms +ssh-rsa" \
-o"HostkeyAlgorithms +ssh-rsa" \
jill@localhost -p 22222
```
注意:当被提示时,输入密码 "upthehill"。
您可以输入一行文本,当您按回车键时,该行将被回显。
返回。使用 CTRL-C 终止连接。
# 证书支持
wolfSSH 可以在接受 X.509 证书代替仅公钥来
认证用户。
要编译带有 X.509 支持的 wolfSSH,请使用 `--enable-certs` 构建选项
或定义 `WOLFSSH_CERTS`:
```
$ ./configure --enable-certs CPPFLAGS=-DWOLFSSH_NO_FPKI
$ make
```
在这个示例中,我们禁用了 FPKI 检查,因为包含的
"fred" 证书没有所需的 FPKI 扩展。如果移除
标志 WOLFSSH_NO_FPKI,您可以看到证书被拒绝。
要提供 CA 根证书以验证用户证书,请给
echo 服务器提供命令行选项 `-a`。
```
$ ./examples/echoserver/echoserver -a ./keys/ca-cert-ecc.pem
```
echo 服务器和客户端有一个名为 "fred" 的虚假用户,其证书
将用于认证。
使用示例证书 fred-cert.der 的 echo 服务器/客户端连接示例为:
```
$ ./examples/echoserver/echoserver -a ./keys/ca-cert-ecc.pem -K fred:./keys/fred-cert.der
$ ./examples/client/client -u fred -J ./keys/fred-cert.der -i ./keys/fred-key.der
```
# TPM 公钥认证
当使用 TPM 进行客户端公钥认证时,wolfSSH 依赖于
wolfCrypt 和 wolfTPM。您还需要有一个 tpm 模拟器
[wolfTPM](https://www.wolfssl.com/products/wolftpm/)
[wolfSSL](https://www.wolfssl.com/products/wolfssl/)
您需要像这样构建和配置 wolfTPM、wolfSSL 和 wolfSSH:
```
$ cd
$ ./autogen.sh (if cloned from GitHub)
$
$ make
$ make check
wolfSSL
$ ./configure --enable-wolftpm --enable-wolfssh
wolfTPM
$ ./configure --enable-swtpm
wolfSSH
$ ./configure --enable-tpm
```
要使用私有 rsa 密钥测试 TPM,需要在 TPM
模拟器(如 `ibmswtpm2`)中运行服务器。可以按如下方式完成:
```
$ cd src
$ ./tpm_server
```
在启动 echo 服务器之前,您需要运行 keygen 以获取 keyblob,
使用 wolfTPM 中的背书密钥,命令如下:
默认密码为 `ThisIsMyKeyAuth`:
```
$ ./examples/keygen/keygen keyblob.bin -rsa -t -pem -eh
```
自定义密码:
```
$ ./examples/keygen/keygen keyblob.bin -rsa -t -pem -eh -auth=
```
这将生成一个 key.pem TPM 公钥,需要使用此命令将其转换为
ssh-rsa BASE64 用户名格式:
```
$ ssh-keygen -f key.pem -i -m PKCS8 > ../wolfssh/key.ssh
```
目录 `examples` 包含一个 echo 服务器,任何客户端都应该
能够连接到它。从 wolfSSH 打开两个终端实例,并使用您在上一步中创建的 key.ssh 文件运行
服务器:
```
$ ./examples/echoserver/echoserver -s key.ssh
```
在另一个终端中,使用 keyblob 运行客户端。使用主要背书密钥
如果您在 keygen 时使用了默认密码,则必须指定该密码:
```
$ ./examples/client/client -i ../wolfTPM/keyblob.bin -u hansel -K ThisIsMyKeyAuth
```
如果您在 keygen 时使用了自定义密码,则必须指定您使用的密码:
```
$ ./examples/client/client -i ../wolfTPM/keyblob.bin -u hansel -K
```
# WOLFSSH 应用程序
wolfSSH 附带一个服务器守护进程和一个命令行 shell 工具。请查看
apps 目录以获取更多信息。
标签:LangChain, SSH, SSH库, wolfSSL, X.509, 传输加密, 加密, 协议实现, 安全Shell, 客户端加密, 客户端加密, 嵌入式安全, 开源, 文件传输, 服务器, 漏洞扫描器, 物联网安全, 网络安全, 证书认证, 轻量级, 远程访问, 隐私保护