小型、可移植、可嵌入的 C 语言 SSHv2 客户端与服务器库,支持 SCP、SFTP、端口转发以及面向嵌入式和 IoT 系统的后量子密钥交换。
wolfSSL 的可嵌入 SSH 服务器 wolfSSH 手册
wolfSSH 依赖于 wolfCrypt,它是 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 配置为仅加密选项:--enable-cryptonly。
wolfSSL 的其他构建选项位于 wolfSSH 手册的 第二章。
在 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 包含一个 echoserver,任何客户端都应该能够连接到它。在终端中运行:
$ ./examples/echoserver/echoserver -f
选项 -f 启用仅回显模式。在另一个终端中运行:
$ ssh jill@localhost -p 22222
当提示输入密码时,输入 "upthehill"。服务器将向客户端发送一条预设的横幅:
wolfSSH Example Echo Server
在客户端输入的字符将由服务器回显到屏幕上。如果字符被回显两次,则说明客户端启用了本地回显。echoserver 并不是一个真正的终端,因此 CR/LF 转换不会按预期工作。
以下控制字符将在 echoserver 中触发特殊操作:
克隆仓库后,请确保将测试私钥设置为对用户只读,否则 ssh 会提示你这样做。
$ chmod 0600 ./keys/gretel-key-rsa.pem ./keys/hansel-key-rsa.pem \
./keys/gretel-key-ecc.pem ./keys/hansel-key-ecc.pem
对示例 echoserver 的认证可以使用密码或公钥完成。要使用密码,命令行如下:
$ 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。
请记住,echoserver 在其 wsUserAuth() 回调函数中有几个假账户。(jack、jill、hansel 和 gretel)当启用 shell 支持时,这些假账户将无法使用。它们不存在于系统的 passwd 文件中。用户会通过身份验证,但服务器会报错,因为它们在系统中不存在。你可以将自己的用户名添加到 echoserver 的密码或公钥列表中。该账户将以运行 echoserver 的用户的权限登录到由 echoserver 启动的 shell 中。
wolfSSH 附带了一些示例工具,用于测试目的以及演示与其他 SSH 实现的互操作性。
echoserver 是 wolfSSH 的主力工具。它最初只允许对预设账户之一进行身份验证,并会回显输入的字符。当启用 shell 支持 时,它可以生成用户 shell。它需要机器上存在实际用户名,并需要更新用户身份验证回调函数以验证凭据。echoserver 还可以处理 SCP 和 SFTP 连接。
echoserver 工具接受以下命令行选项:
-1 在单个(一个)连接后退出
-e 期望来自客户端的 ECC 公钥
-E 使用 ECC 私钥
-f 回显输入
-p <num> 接受连接的端口,默认 22222
-N 使用非阻塞套接字
-d <string> 设置 SFTP 连接的主目录
-j <file> 加载要接受的对端公钥
client 建立到 SSH 服务器的连接。在其最简单的模式下,它向服务器发送字符串 "Hello, wolfSSH!",打印响应,然后退出。使用伪终端选项时,client 将成为一个真正的客户端。
client 工具接受以下命令行选项:
-h <host> 要连接的主机,默认 127.0.0.1
-p <num> 要连接的端口,默认 22222
-u <username> 用于身份验证的用户名(必需)
-P <password> 用户名的密码,省略时会提示输入
-e 为用户使用示例 ecc 密钥
-i <filename> 用户私钥的文件名
-j <filename> 用户公钥的文件名
-x 成功连接后退出,不进行
读/写
-N 使用非阻塞套接字
-t 使用伪终端
-c <command> 执行远程命令并管道 stdin/stdout
-a 尝试使用 SSH-AGENT
portfwd 工具建立到 SSH 服务器的连接,并设置本地端口转发的监听器,或请求远程端口转发的监听器。连接后,该工具终止。
portfwd 工具接受以下命令行选项:
-h <host> 要连接的主机,默认 127.0.0.1
-p <num> 要连接的端口,默认 22222
-u <username> 用于身份验证的用户名(必需)
-P <password> 用户名的密码,省略时会提示输入
-F <host> 要转发来源的主机,默认 0.0.0.0
-f <num> 要转发来源的主机端口(必需)
-T <host> 要转发目标的主机,默认为 host
-t <num> 要转发目标的端口(必需)
scpclient(即 wolfscp)建立到 SSH 服务器的连接,并从本地机器复制指定文件或复制指定文件到本地机器。
scpclient 工具接受以下命令行选项:
-H <host> 要连接的主机,默认 127.0.0.1
-p <num> 要连接的端口,默认 22222
-u <username> 用于身份验证的用户名(必需)
-P <password> 用户名的密码,省略时会提示输入
-L <from>:<to> 从本地复制到服务器
-S <from>:<to> 从服务器复制到本地
sftpclient(即 wolfsftp)建立到 SSH 服务器的连接,并允许目录导航、获取和放置文件、创建和删除目录等。
sftpclient 工具接受以下命令行选项:
-h <host> 要连接的主机,默认 127.0.0.1
-p <num> 要连接的端口,默认 22222
-u <username> 用于身份验证的用户名(必需)
-P <password> 用户名的密码,省略时会提示输入
-d <path> 设置默认本地路径
-N 使用非阻塞套接字
-e 使用 ECC 用户身份验证
-l <filename> 本地文件名
-r <filename> 远程文件名
-g 将本地文件名作为远程文件名
-G 将远程文件名作为本地文件名
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 <local_file> [email protected]:<remote_path>
要将同一个文件复制到服务器,但保留时间戳并使用详细模式:
$ scp -v -p -P 22222 <local_file> [email protected]:<remote_path>
要递归地将目录复制到服务器:
$ scp -P 22222 -r <local_dir> [email protected]:<remote_dir>
要将单个文件从服务器复制到本地客户端:
$ scp -P 22222 [email protected]:<remote_file> <local_path>
要递归地将目录从服务器复制到本地客户端:
$ scp -P 22222 -r [email protected]:<remote_dir> <local_path>
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 <username> \
-f 12345 -t 11111
src/wolfssl$ ./examples/client/client -p 12345
默认情况下,wolfSSL 服务器监听端口 11111。客户端设置为尝试连接端口 12345。portfwd 以用户“username”登录,在端口 12345 上打开监听器,并连接到端口 11111 上的服务器。数据包在客户端和服务器之间来回路由。“Hello, wolfSSL!”
portfwd 的源代码提供了如何设置和使用 wolfSSH 中端口转发支持的示例。
echoserver 将处理本地和远程端口转发。要使用 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 客户端和服务器之间进行端口转发,如同前面的示例一样。
wolfSSH 为 SFTP 版本 3 提供服务器端和客户端支持。这允许用户建立加密连接以管理文件系统。
要编译支持 SFTP 的 wolfSSH,请使用 --enable-sftp 构建选项或定义 WOLFSSH_SFTP:
$ ./configure --enable-sftp
$ make
有关完整的 API 用法和实现细节,请参阅 wolfSSH 用户手册。
创建的 SFTP 客户端位于 examples/sftpclient/ 目录中,示例 echoserver 充当 SFTP 服务器。
src/wolfssh$ ./examples/sftpclient/wolfsftp
连接后输入 "help" 可查看支持的命令完整列表。
wolfSSH sftp> help
Commands :
cd <string> change directory
chmod <mode> <path> change mode
get <remote file> <local file> pulls file(s) from server
ls list current directory
mkdir <dir name> creates new directory on server
put <local file> <remote file> push file(s) to server
pwd list current path
quit exit
rename <old> <new> renames remote file
reget <remote file> <local file> resume pulling file
reput <remote file> <local file> resume pushing file
<crtl + c> interrupt get/put cmd
连接到另一系统的示例为
src/wolfssh$ ./examples/sftpclient/wolfsftp -p 22 -u user -h 192.168.1.111