sftp服务器配置
点击此处
依赖
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<dependency>
<groupId>ch.ethz.ganymed</groupId>
<artifactId>ganymed-ssh2</artifactId>
<version>build210</version>
</dependency>
ssh2工具类
package com.tianshl;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* @author tianshl
* @version 2018/5/22 下午1:29
*/
@Component
public class Ssh2Utils {
private Connection connection;
/**
* 登录
*/
public void login(String host, String username, String password) throws Exception {
connection = new Connection(host);
connection.connect();
if(!connection.authenticateWithPassword(username, password)){
throw new Exception("管理员账号或密码错误");
}
}
/**
* 退出
*/
public void logout() {
try {
if (connection != null) connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 执行指令
*/
public String execCommand(final String command) {
final StringBuilder sb = new StringBuilder(256);
Session session = null;
try {
session = connection.openSession();
session.requestPTY("vt100", 80, 24, 640, 480, null);
session.execCommand(command);
long start = System.currentTimeMillis();
BufferedReader br = new BufferedReader(new InputStreamReader(new StreamGobbler(session.getStdout())));
char[] arr = new char[512];
int read;
while (true) {
read = br.read(arr, 0, arr.length);
if (read < 0 || (System.currentTimeMillis() - start) > 5000) break;
sb.append(new String(arr, 0, read));
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
if (session != null) session.close();
}
return sb.toString();
}
}
service
package com.tianshl;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;
/**
* service for sftp
*/
@Service
@Transactional
public class SftpService {
@Value("${sftp.host}")
private String host;
@Value("${sftp.root.username}")
private String username;
@Value("${sftp.root.password}")
private String password;
private final Ssh2Utils ssh2Utils;
public SftpService(Ssh2Utils ssh2Utils) {
this.ssh2Utils = ssh2Utils;
}
/**
* 创建linux用户 创建相关目录 以及 权限设置
*/
private JSONObject createUser (Ssh2Utils ssh2Utils, String sftpUsername) {
JSONObject resp = new JSONObject();
resp.put("success", false);
String home = "/sftp/" + sftpUsername;
try {
String stdOut = ssh2Utils.execCommand("useradd -d " + home + " -m -g sftp -s /bin/false " + sftpUsername);
if (stdOut.contains("useradd: user '" + sftpUsername + "' already exists")) {
ssh2Utils.logout();
resp.put("success", false);
resp.put("msg", "账户名称'" + sftpUsername + "'已存在,请更换其他名称.");
return resp;
}
List<String> command = Lists.newArrayList();
command.add("chown root:sftp " + home);
command.add("chmod 755 " + home);
command.add("mkdir " + home + "/{.ssh,data}");
command.add("chown " + sftpUsername + ":sftp " + home + "/{.ssh,data}");
command.add("chmod 777 " + home + "/data");
command.add("chmod 700 " + home + "/.ssh");
ssh2Utils.execCommand(String.join(";", command));
} catch (Exception e) {
e.printStackTrace();
resp.put("msg", "创建账号失败");
return resp;
}
resp.put("success", true);
return resp;
}
/**
* 生成秘钥
*/
private JSONObject genSecretKey(Ssh2Utils ssh2Utils, String sftpUsername) {
JSONObject resp = new JSONObject();
resp.put("success", false);
String sshDirectory = String.format("/sftp/%s/.ssh", sftpUsername);
List<String> command = Lists.newArrayList();
command.add(String.format("rm -f %s/id_rsa*", sshDirectory));
command.add(String.format("ssh-keygen -f %s/id_rsa -P '' -C '%s'", sshDirectory, sftpUsername));
command.add(String.format("cat %s/id_rsa.pub >> %s/authorized_keys", sshDirectory, sshDirectory));
command.add(String.format("chmod 600 %s/authorized_keys", sshDirectory));
command.add(String.format("chown %s:sftp %s/*", sftpUsername, sshDirectory));
try {
ssh2Utils.execCommand(String.join(";", command));
} catch (Exception e) {
e.printStackTrace();
resp.put("msg", "生成秘钥失败");
return resp;
}
resp.put("success", true);
return resp;
}
/**
* 添加秘钥
*/
private JSONObject addSecretKey(Ssh2Utils ssh2Utils, String sftpUsername, String pubKey) {
JSONObject resp = new JSONObject();
resp.put("success", false);
String sshDirectory = String.format("/sftp/%s/.ssh", sftpUsername);
try {
ssh2Utils.execCommand(String.format("echo '%s' >> %s", pubKey, String.format("%s/authorized_keys", sshDirectory)));
} catch (Exception e) {
e.printStackTrace();
resp.put("msg", "添加秘钥失败");
return resp;
}
resp.put("success", true);
return resp;
}
/**
* 更新秘钥
*/
public BaseDto changeSecretKey(String sftpUsername, HttpServletResponse response, MultipartFile secretKey) {
try {
ssh2Utils.login(host, username, password);
JSONObject resp;
if (secretKey == null) {
resp = genSecretKey(ssh2Utils, sftpUsername);
if (resp.getBoolean("success")) {
downloadSecretKey(id, response);
}
} else {
resp = addSecretKey(ssh2Utils, sftpUsername, new String(secretKey.getBytes()));
}
if (!resp.getBoolean("success")) {
ssh2Utils.logout();
return BaseDto.error(resp.getString("msg"), null);
}
ssh2Utils.logout();
} catch (Exception e){
e.printStackTrace();
}
return BaseDto.success("设置成功", null);
}
/**
* 下载秘钥
*/
public BaseDto downloadSecretKey(String sftpUsername, HttpServletResponse response){
String sshDirectory = String.format("/sftp/%s/.ssh", sftpUsername);
try {
ssh2Utils.login(host, username, password);
String secret = ssh2Utils.execCommand(String.format("cat %s/id_rsa", sshDirectory));
String end = "-----END RSA PRIVATE KEY-----";
secret = secret.substring(0, secret.lastIndexOf(end) + end.length());
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment; filename=\"id_rsa\"");
PrintWriter pw = response.getWriter();
pw.write(secret);
pw.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ssh2Utils.logout();
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 新增sftp账户
*/
public BaseDto save(String sftpUsername, MultipartFile secretKey) {
if (StringUtils.isRealBlank(sftpUsername)) {
return BaseDto.error("账户名称不能为空!", null);
}
try {
ssh2Utils.login(host, username, password);
JSONObject resp = createUser(ssh2Utils, sftpUsername);
if (!resp.getBoolean("success")) {
return BaseDto.error(resp.getString("msg"), null);
}
if (secretKey == null) {
resp = genSecretKey(ssh2Utils, sftpUsername);
if (resp.getBoolean("success")) return null;
} else {
resp = addSecretKey(ssh2Utils, sftpUsername, new String(secretKey.getBytes()));
}
if (!resp.getBoolean("success")) {
return BaseDto.error(resp.getString("msg"), null);
}
} catch (Exception e){
e.printStackTrace();
} finally {
try {
ssh2Utils.logout();
} catch (Exception e) {}
}
return BaseDto.success("创建成功", null);
}