<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-sftp</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
这个版本很重要 jsch 0.1.55可以连接服务端,0.1.54有一处源码不一致就连不了, 报verify false,需要修改sftp服务器的hostkey算法或ec算法长度keysize为256才能连。
如果使用ganymed-ssh2 这种,就需要进一步配置kex和host key算法
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
sftp:
# 开启
enabled: true
# 地址 端口
host: 127.0.0.1
port: 1234
# 存储的文件路径
base-path: /opt/sftpdir
# 账密map,1~n组
user-pwd:
root: root
root2: root2
package com.mysftp.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Map;
@Data
@ConfigurationProperties(prefix = "sftp")
public class SftpConfig {
private boolean enabled = true;
private String host;
private int port;
private String basePath;
private Map<String, String> userPwd;
}
package com.mysftp.config;
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.shell.ProcessShellCommandFactory;
import org.apache.sshd.sftp.server.SftpSubsystemFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Map;
@ConditionalOnProperty(prefix = "sftp", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(SftpConfig.class)
@Configuration
public class SftpServerConfiguration {
private final SftpConfig sftpConfig;
public SftpServerConfiguration(SftpConfig sftpConfig) {
this.sftpConfig = sftpConfig;
}
@Bean
public void sftpServer() {
//创建SshServer对象
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setHost(sftpConfig.getHost());
//配置端口
sshd.setPort(sftpConfig.getPort());
//设置默认的签名文件,如果文件不存在会创建
// sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Paths.get("E:\\tmp1\\key")));
// sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(Paths.get("/opt/key")));
Map<String, String> userPwd = sftpConfig.getUserPwd();
//设置用户名和密码进行登录验证
sshd.setPasswordAuthenticator((username, password, serverSession) -> {
//这里可以增加逻辑从数据库或其他方式校验用户名和密码
//返回true则校验成功否则失败
return userPwd.containsKey(username) && password.equals(userPwd.get(username));
});
//设置sftp子系统
sshd.setSubsystemFactories(Arrays.asList(new SftpSubsystemFactory()));
//设置sfp默认的访问目录
Path dir = Paths.get(sftpConfig.getBasePath());
sshd.setFileSystemFactory(new VirtualFileSystemFactory(dir.toAbsolutePath()));
//给每个用户分配不同的访问目录
// sshd.setFileSystemFactory(new VirtualFileSystemFactory(dir.toAbsolutePath()) {
// @Override
// public Path getUserHomeDir(SessionContext session) throws IOException {
// String username = session.getUsername();
// Path homeDir = getUserHomeDir(username);
// if (homeDir == null) {
// //这里给每个用户修改为默认目录+用户名+dir的目录格式
// //可以根据实际的需求修改此处的代码
// homeDir = getDefaultHomeDir().resolve(username + "dir");
// setUserHomeDir(username, homeDir);
// }
// File file = new File(String.valueOf(homeDir));
// file.mkdirs();
// return homeDir;
// }
// });
//设置ssh的shell环境
// sshd.setShellFactory((c) -> {
// ServerSession session = c.getSession();
// String username = session.getUsername();
// //除了root以外的的用户都不允许远程登录
// if ("root".equals(username)) {
// return InteractiveProcessShellFactory.INSTANCE.createShell(c);
// } else {
// return null;
// }
// });
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
sshd.setCommandFactory(new ProcessShellCommandFactory());
//启动ssh服务
try {
sshd.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
官网:https://mina.apache.org/sshd-project/
GitHub:https://github.com/apache/mina-sshd
https://gitee.com/mirrors/mina-sshd/
https://github.com/apache/mina-sshd/tree/master/sshd-sftp
https://github.com/apache/mina-sshd/tree/master/sshd-spring-sftp
https://github.com/apache/mina-sshd
https://github.com/apache/mina-sshd/blob/master/docs/sftp.md
https://github.com/apache/mina-sshd/blob/master/docs/server-setup.md
https://zhuanlan.zhihu.com/p/349738684?utm_source=wechat_session&utm_medium=social&utm_oi=547928202685915136&utm_campaign=shareopn