Skip to content
wudream813Public

About

Minimal cross-platform SSH server (shell / exec / SFTP v3) built on libssh + OpenSSL: ConPTY on Windows, POSIX PTY on Linux, jailed SFTP root, Ed25519 host key, PBKDF2 + authorized_keys auth, ANSI stripping. Inspired by WinSSHD.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MiniSSHD (C++ 跨平台版)

参考 WinSSHD 的极简哲学,用 C++17 + libssh + OpenSSL 重写为 Windows / Linux / macOS 全平台可用、可审计的轻量 SSH 服务端。
相对于 WinSSHD 仅支持 Windows,本项目补齐了 Linux/macOS 的 PTY 与文件系统抽象,保留全部核心特性。


1. 特性

能力 WinSSHD (原始) MiniSSHD-C++ (本项目)
协议 SSHv2 (libssh) SSHv2 (libssh 0.11)
主机密钥 Ed25519 自动生成 Ed25519 自动生成,SHA256 指纹
密码认证 PBKDF2-HMAC-SHA256 (600k) 同算法 (OpenSSL),5次/45s 限制
公钥认证 authorized_keys 兼容 OpenSSH,ed25519/rsa/ecdsa
交互终端 ConPTY + PowerShell/cmd 自适应: Linux/macOS posix_openpt 真 PTY;Windows ConPTY (CreatePseudoConsole) → pipe 回落
窗口大小 同步 同步 (TIOCSWINSZ / ResizePseudoConsole)
单命令 ssh host "whoami" 同,超时 30s,file_root 为 cwd
SFTP v3 上传/下载/目录/重命名/删除/属性/断点续传 同,SftpServer 沙箱实现
SCP 现代 scp 经 SFTP (-O 拒绝) 同
沙箱 虚拟根 ..、盘符、重解析点 跨平台沙箱: .. 越界、C:/\\share、symlink 逃逸、父目录遍历、重解析点
ANSI 默认过滤,可 --keep-ansi 0.2.1 起默认保留 ANSI/VT;要过滤显式加 --strip-ansi (仅作用于 PTY 桥接)
并发 16 连接,Job Object 清理 16 连接,std::thread + atomic 计数,SIGTERM/TerminateProcess
配置 %LOCALAPPDATA%\WinSSHD\config.ini 跨平台: Windows %LOCALAPPDATA%\MiniSSHD、macOS ~/Library/Application Support/MiniSSHD、Linux ~/.config/MiniSSHD
CLI --bind/--port/--shell/--file-root/--data-dir 完全兼容,另有 --config/--user/--no-shell/--no-sftp
依赖 编译 libssh+OpenSSL libssh + OpenSSL,vcpkg 或系统包均可

有意未实现 (与 WinSSHD 一致)
旧版 SCP/RCP (scp -O)、SFTP symlink/junction、端口转发/X11/Agent、多 channel 复用、持久化、用户模拟。


2. 系统要求

  • 编译器: C++17 (GCC 11+, Clang 14+, MSVC 2022)
  • CMake: 3.20+
  • 依赖: libssh >=0.10, OpenSSL >=1.1.1 (通过 vcpkg 或系统 apt/brew)
  • 平台:
    • Linux (tested Debian 13, Ubuntu 22.04)
    • macOS 12+ (需 brew install libssh openssl)
    • Windows 10 1809+ (需 ConPTY, 可选 vcpkg 静态 CRT)

3. 编译

Linux / macOS (系统包)

# Debian/Ubuntu
sudo apt install cmake g++ libssh-dev libssl-dev
# macOS
brew install cmake libssh openssl

git clone <this-repo> MiniSSHD-cpp
cd MiniSSHD-cpp
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
./build/minisshd --help

Windows (vcpkg)

git clone https://github.com/microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.bat
.\vcpkg\vcpkg install libssh[core] openssl --triplet x64-windows-static

git clone <this-repo> MiniSSHD-cpp
cd MiniSSHD-cpp
cmake -B build -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
cmake --build build --config Release
.\build\Release\minisshd.exe --help

Linux 交叉编译 Windows (MinGW)

sudo apt install g++-mingw-w64-x86-64-posix cmake ninja-build
./build-mingw-cross.sh  # 参考 WinSSHD 的脚本,或手动:
cmake -B build-mingw --toolchain cmake/toolchains/mingw-w64-x86_64.cmake
cmake --build build-mingw

4. 快速开始

# 首次运行向导 (自动创建数据目录、生成 Ed25519 密钥、设置密码)
./build/minisshd

# 指定参数前台运行
./build/minisshd --bind 127.0.0.1 --port 2222 --keep-ansi --shell "/bin/bash -l"

# 仅本地测试 (推荐)
./build/minisshd --bind 127.0.0.1 --port 2222

# 首次运行也可以直接带上参数:向导会跳过命令行已给出的项,
# 并把 --port/--bind/--file-root/--user 写回新建的 config.ini
./build/minisshd --port 2222 --file-root /srv/sftp-root

0.2.1 起 默认保留 ANSI/VT(不再需要 --keep-ansi),需要过滤时显式加 --strip-ansi; 面向用户的提示、警告与日志已全部中文化,[session] / [server] / [SFTP] / [auth] 这类标签保持 ASCII 以便 grep 与日志采集。

连接

# 交互终端
ssh -p 2222 admin@127.0.0.1
# 单命令
ssh -p 2222 admin@127.0.0.1 "whoami; pwd; ls -l"
# SFTP
sftp -P 2222 admin@127.0.0.1
sftp> put local.zip /uploads/local.zip
sftp> get /result.txt ./result.txt
# 现代 scp (经 SFTP)
scp -P 2222 ./local.zip admin@127.0.0.1:/local.zip
scp -P 2222 admin@127.0.0.1:/result.txt ./result.txt

首次连接核对服务端打印的 SHA256 指纹。

公钥认证

ssh-keygen -t ed25519
./build/minisshd --add-key ~/.ssh/id_ed25519.pub
# 或手动追加到 ~/.config/MiniSSHD/authorized_keys

5. CLI

minisshd [选项]

--config <path>        指定 config.ini 路径 (默认: <data-dir>/config.ini)
--data-dir <path>      数据目录: host key / authorized_keys / 默认配置文件所在
--user <name>          覆盖登录用户名 (写回 config.ini)
--port <1-65535>       覆盖监听端口 (写回 config.ini)
--bind <address>       覆盖监听地址 (写回 config.ini)
--file-root <path>     SFTP 虚拟根, 远程 / 映射至此 (写回 config.ini)
--shell <cmd>          Shell, 如 "powershell", "cmd", "/bin/bash" (仅本次)
--no-shell             本次禁用交互式 shell, exec 通道仍可用 (仅本次)
--no-sftp              本次禁用 SFTP 子系统 (仅本次)
--strip-ansi           过滤终端输出中的 ANSI/VT 序列 (仅本次)
--keep-ansi            保留 ANSI/VT 序列 —— 0.2.1 起的默认行为
--reset-password       重设登录密码 (写回 config.ini) 后退出
--add-key <file.pub>   添加公钥后退出 (--add-pubkey 同义)
--help / --version     帮助 / 版本

写回规则: 只有 --user/--port/--bind/--file-root 会落盘到 config.ini,其余为运行期开关; 值与配置一致时不重复写文件。首次运行的向导同样会直接采用命令行已给出的 --user/--port/--file-root, 不再重复询问,避免"向导把 CLI 值覆盖回旧默认"的情况。

所有交互 (首次运行向导、--reset-password) 都可按 Ctrl+C 取消,取消时不修改 config.ini 并以退出码 130 结束;stdin 结束 (EOF,例如管道喂完) 同样视为取消,不会空转。


6. 数据文件

跨平台路径 (defaultDataDirectory()):

  • Windows: %LOCALAPPDATA%\MiniSSHD\
  • macOS: ~/Library/Application Support/MiniSSHD/
  • Linux: ~/.config/MiniSSHD/ (或 $XDG_CONFIG_HOME/MiniSSHD)

内容:

  • config.ini — username, salt, password_hash, iterations, bind, port, strip_ansi, allow_empty_password, file_root, shell (strip_ansi 自 0.2.1 起默认 0=保留 ANSI;老配置里已写过 1 的会继续生效,可用 --keep-ansi 临时覆盖) password_hash 为空 且 allow_empty_password=1 时才允许空密码登录;只有前者为空会被拒绝启动
  • ssh_host_ed25519_key — Ed25519 私钥 (0600)
  • authorized_keys — OpenSSH 格式公钥

7. 架构

minisshd (C++17)
├── src/main.cpp          CLI + 向导 + 信号处理
├── src/config.{h,cpp}    跨平台路径、PBKDF2、INI 读写
├── src/auth.{h,cpp}      authorized_keys 解析、PBKDF2 校验
├── src/pty.{h} + pty_unix.cpp / pty_win.cpp
│   ├── Unix: posix_openpt + fork + exec + TIOCSWINSZ/SIGWINCH
│   └── Win: ConPTY (CreatePseudoConsole) → pipe 回落
├── src/sftp_server.{h,cpp}
│   ├── SftpSandbox: realPath()/canonical()/checkSymlinkEscape()
│   └── SftpServer: libssh sftp_server_new + 消息循环 (OPEN/CLOSE/READ/WRITE/STAT/MKDIR/...)
├── src/session.{h,cpp}   握手、认证 (5次/45s)、channel 分发 (shell/exec/sftp)
└── src/server.{h,cpp}    监听、16并发、指纹打印、优雅退出

关键设计 (vs WinSSHD):

  • SSH 层: 保留 libssh (WinSSHD 亦用),但去掉 WIN32 限制,新增 WITH_SERVER 编译定义以启用 sftp_server_new。
  • PTY 层: 抽象 IPty 接口,UnixPty 用 posix_openpt (避免 openpty 的 glibc 兼容问题),WinConPty 用 CreatePseudoConsole,失败回落 WinPipePty。
  • 沙箱: 统一 lexically_normal + canonical().relative_to(root) 双重校验,拒绝 C: 盘符与 symlink 逃逸。
  • 安全: OpenSSL PKCS5_PBKDF2_HMAC + RAND_bytes,chmod 600,OPENSSL_cleanse 清理密码。

8. 测试

# 单元 (Python 侧)
pytest tests/ -v  # 若保留 Python 实现

# C++ 集成 (需已编译)
python3 /tmp/test_minisshd.py  # exec + sftp
python3 /tmp/test_shell2.py    # shell + sftp 沙箱

# 手动
./build/minisshd --data-dir /tmp/minisshd_test --bind 127.0.0.1 --port 2222 &
ssh -p 2222 admin@127.0.0.1 "echo ok"
sftp -P 2222 admin@127.0.0.1 <<< $'ls -l /\nput README.md /test.md\n'
kill %1

9. 安全提示

  1. 仅在受控机器运行,勿直接暴露公网。
  2. 优先公钥,强密码;远程权限 = 启动用户,勿用 root/Admin。
  3. 及时 apt/brew upgrade libssh openssl 并重编。
  4. 私钥 0600,共享目录请设严格 ACL。
  5. 空密码:--reset-password 里把密码留空会启用空密码登录 —— 只要猜对用户名即可拿到完整 shell 与整个 file_root。因此它默认关闭,需要两次输入大写 YES 确认,并在启动横幅、 以及每一次空密码成功登录时都打印严重警告。仅建议绑 127.0.0.1 做测试; 关闭方法:再次 --reset-password 设置真实密码 (开关自动回到 0)。

10. 与 WinSSHD 的关系

  • 继承: 配置格式、CLI、认证、沙箱、安全哲学完全对标,可无缝替换。
  • 扩展: 跨平台 PTY、POSIX 文件系统、CMake 统一构建、OpenSSL 替代 BCrypt。
  • 致谢: WinSSHD 的精简设计与 SFTP 沙箱实现。

11. 许可证

本项目采用 MIT License(与 WinSSHD 一致),完整条款见仓库根目录的 LICENSE。

第三方组件许可证(静态发布时需一并尊重,此处列出):

组件 许可证 说明
libssh LGPL-2.1-or-later 本仓库 Release 的静态构建将其静态链接;如需替换/重链,见下方说明
OpenSSL Apache-2.0 含 OpenSSL 例外条款,可与 GPL 程序链接

关于 LGPL 与静态链接:LGPL-2.1 第 6 条要求静态链接的组合作品允许用户重新链接。 若你要分发静态构建,请保留本文件与上游版权说明,并公开可用于重新链接的构建方式 (例如直接用发行版自带的 libssh/OpenSSL 开发包做默认构建,即为动态链接):

cmake -B build -DCMAKE_BUILD_TYPE=Release   # 默认链接系统 libssh/libssl (.so/.dll)
cmake --build build -j

只做源码分发时本条不适用。CMakeLists.txt 里的 MINISSHE_STATIC_LINK 目前是未接线的空选项,不要指望它切换链接方式。

About

Minimal cross-platform SSH server (shell / exec / SFTP v3) built on libssh + OpenSSL: ConPTY on Windows, POSIX PTY on Linux, jailed SFTP root, Ed25519 host key, PBKDF2 + authorized_keys auth, ANSI stripping. Inspired by WinSSHD.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages