# SFTP **Repository Path**: citybeat2007/sftp ## Basic Information - **Project Name**: SFTP - **Description**: Java 17 + Spring boot 2.7 + 开发的一个SFTP服务器程序,支持多站点、多用户,用户密码可加密亦可密文,支持Windows和Linux部署。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-14 - **Last Updated**: 2026-02-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SFTP服务器使用说明 ## 版权与责任声明 Copyright © 2026 Citybeat. 该项目仅供学习和研究使用。如用于生产环境后果自负。 ## 技术栈 | 组件 | 版本 | 说明 | |------|------|------| | Java | 17 | 运行环境 | | Spring Boot | 2.7.18 | 基础框架 | | Apache Mina SSHD | 2.12.1 | SFTP服务端核心 | | jBCrypt | 0.4 | BCrypt密码加密 | | Lombok | - | 代码简化 | ## 项目结构 ``` SFTP/ ├── src/ │ ├── main/ │ │ ├── java/example/ │ │ │ ├── SftpServerApplication.java # Spring Boot 启动入口 │ │ │ ├── auth/ │ │ │ │ └── ConfigFilePasswordAuthenticator.java # 密码认证器(支持多格式) │ │ │ ├── config/ │ │ │ │ ├── SftpConfigProperties.java # 配置属性类 │ │ │ │ └── TimeZoneConfig.java # 时区配置 │ │ │ ├── fs/ │ │ │ │ ├── VirtualFileSystem.java # 虚拟文件系统实现 │ │ │ │ ├── LoggingFileSystemFactory.java # 日志拦截文件系统工厂 │ │ │ │ └── LoggingFileSystemProvider.java # 日志拦截文件系统提供者 │ │ │ ├── server/ │ │ │ │ ├── HostKeyCommandLine.java # 主机密钥命令行处理 │ │ │ │ ├── HostKeyManager.java # 主机密钥管理器 │ │ │ │ ├── SftpServerInstance.java # SFTP站点实例 │ │ │ │ ├── SftpServerManager.java # SFTP服务管理器 │ │ │ │ ├── SftpAccessEventListener.java # SFTP事件监听器 │ │ │ │ └── SftpAccessLogAppender.java # SFTP访问日志处理(核心) │ │ │ └── util/ │ │ │ ├── BCryptPasswordEncoder.java # BCrypt加密工具 │ │ │ └── PasswordGenerator.java # 密码生成工具 │ │ └── resources/ │ │ ├── application.yml # 主配置文件 │ │ └── logback-spring.xml # 日志配置 │ └── test/ │ └── java/example/ │ ├── auth/ │ ├── server/ │ ├── test/ │ └── util/ └── pom.xml # Maven 配置 ``` ## 构建项目 ### 命令行构建: ```bash # 清理并构建 mvn clean package -DskipTests # 或分步执行 mvn clean mvn compile mvn package -DskipTests ``` ## 启动SFTP服务器 ```bash java -jar target/sftp-server-1.0.0.jar ``` ## 生成加密密码 ### 交互式模式 ```bash java -jar target/sftp-server-1.0.0.jar --generate-password ``` 运行后按提示选择加密算法(MD5/SHA1/SHA256/BCrypt)并输入明文密码,程序将生成加密后的密文。 ### 命令行直接生成 ```bash # 生成 MD5 密文 java -jar target/sftp-server-1.0.0.jar --generate-password --type=MD5 --password=123 # 生成 SHA1 密文 java -jar target/sftp-server-1.0.0.jar --generate-password --type=SHA1 --password=123 # 生成 SHA256 密文 java -jar target/sftp-server-1.0.0.jar --generate-password --type=SHA256 --password=123 # 生成 BCrypt 密文 java -jar target/sftp-server-1.0.0.jar --generate-password --type=BCRYPT --password=123 ``` 支持的加密算法:MD5、SHA1、SHA256、BCrypt ## 主机密钥管理 ### 查看主机密钥状态 ```bash java -jar target/sftp-server-1.0.0.jar --list-host-keys ``` ### 重新生成指定站点的主机密钥 ```bash java -jar target/sftp-server-1.0.0.jar --generate-host-key site1 ``` ### 删除指定站点的主机密钥 ```bash java -jar target/sftp-server-1.0.0.jar --delete-host-key site1 ``` ### 主机密钥特点: - 首次启动时自动生成并保存到文件 - 后续启动时重复使用同一密钥文件 - 客户端只需首次信任服务器密钥 - 每个站点有独立的密钥文件(sftp_host_key_site1, sftp_host_key_site2) - 支持手动管理和重新生成密钥 ## 配置文件 配置文件位于 `src/main/resources/application.yml` ### 主要配置项: - `sftp.sites`: SFTP站点配置(可配置多个站点) - `sftp.users`: 用户账户配置 - `sftp.timezone`: 系统时区设置 ### 用户home-dir配置说明: 用户主目录配置支持两种方式: - **相对路径**:如 `alice`,用户目录为 `站点根目录/alice` - **站点根目录**:填写 `/`,用户将直接使用站点根目录(适用于单用户场景) > ⚠️ 安全提示:系统已启用路径穿越检查,禁止使用绝对路径(如 `/etc`)或包含 `../` 的路径,防止用户逃离站点目录。 ### 密码格式说明: 系统支持多种密码格式,可混合使用: - **明文密码**:直接填写密码,如 `mypassword123` - **MD5密文**:{MD5} + 32位小写哈希,如 `{MD5}202cb962ac59075b964b07152d234b70` - **SHA1密文**:{SHA1} + 40位小写哈希,如 `{SHA1}40bd001563085fc35165329ea1ff5c5ecbdbbeef` - **SHA256密文**:{SHA256} + 64位小写哈希,如 `{SHA256}ecd71870daf21d6c7f480ad4ecdc706af3e34741c963f92e8b6f54ba7abc2dbc` - **BCrypt密文**:{bcrypt} + BCrypt哈希,如 `{bcrypt}$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi` ### 示例用户配置: ```yaml sftp: users: # 使用站点根目录(单用户场景) - username: admin password: "{bcrypt}$2a$10$..." home-dir: / permissions: READ,WRITE,DELETE # 使用用户子目录(多用户场景) - username: alice password: "mypassword123" # 明文密码 home-dir: alice permissions: READ,WRITE,DELETE - username: bob password: "{MD5}202cb962ac59075b964b07152d234b70" # MD5密文 home-dir: bob permissions: READ - username: charlie password: "{SHA1}40bd001563085fc35165329ea1ff5c5ecbdbbeef" # SHA1密文 home-dir: charlie permissions: READ,WRITE - username: david password: "{SHA256}ecd71870daf21d6c7f480ad4ecdc706af3e34741c963f92e8b6f54ba7abc2dbc" # SHA256密文 home-dir: david permissions: READ,WRITE,DELETE ``` ## 使用方法 1. 运行密码生成器生成用户密码 2. 将生成的密码配置到application.yml中 3. (可选)查看或管理主机密钥 4. 启动SFTP服务器 5. 使用SFTP客户端连接(默认端口2222和2223) 6. 客户端首次连接需要信任服务器密钥,之后无需重新信任 7. 访问日志将记录所有操作的正确站点ID和操作状态 ## 默认测试账户 - **alice**: 密码 `mypassword123` (明文) - **bob**: 密码 `123` (MD5密文) > ⚠️ 当前使用明文密码进行测试,生产环境请使用BCrypt加密密码 ## 测试连接 ```bash # 使用sftp命令行客户端测试 sftp -P 2222 alice@localhost # 输入密码: mypassword123 # 或使用bob账户(密码: 123) sftp -P 2222 bob@localhost # 输入密码: 123 ``` ## 访问日志 ### 日志文件 访问日志记录在 `logs/sftp-access.log` 文件中。 ### 日志格式 ``` [时间] site=站点ID operation=操作类型 username=用户名 clientIp=客户端IP path=文件路径 status=操作状态 ``` ### 支持的操作类型 | 操作类型 | 说明 | |---------|------| | LOGIN | 用户登录 | | LOGOUT | 用户退出 | | UPLOAD | 文件上传 | | DOWNLOAD | 文件下载 | | DELETE | 文件删除 | | MKDIR | 创建目录 | | RMDIR | 删除目录 | | RENAME | 文件重命名 | ### 操作状态 - `SUCCESS`: 操作成功 - `FAILED`: 操作失败 ## 更新日志 ### 2026-02-24 - 修复多站点环境下的站点ID错乱问题:登录site1现在正确记录为site1,而不是site2 - 增强操作状态日志记录:现在能够正确记录每个操作的SUCCESS/FAILED状态 - 改进SFTP事件处理和日志记录机制 ### 2026-02-23 - 升级 Apache Mina SSHD 从 2.9.2 到 2.12.1 - 修复上传/下载文件日志记录功能(通过解析 DEBUG 日志实现) - 修复路径匹配问题(统一去掉前导斜杠) - 修复状态判定问题(使用 SSH_FX_OK 状态作为成功标志) - 添加站点名称到所有访问日志