1、SFTP信用公钥配置
1.1 客户端生成密钥对
以DSA举例:
ssh-keygen –t dsa
执行该命令后,在home/用户名/.ssh目录下,会生成id_dsa和id_dsa.pub两个文件
1.2 将id_dsa.pub公钥文件上传至服务端的home/用户名/.ssh目录下
scp id_dsa.pub 用户名@服务端IP:/home/用户名/.ssh
此时还需要输入密码
1.3服务端添加信任公钥
登录服务端,进入到/home/用户名/.ssh目录,将刚刚拷贝的id_dsa.pub文件的内容加入到authorized_keys文件中
cat id_dsa.pub >> authorized_keys
1.4 服务端分别修改authorized_key文件和.ssh的权限为600和700
chmod 600 authorized_keys
chmod 700 .ssh
1.5 测试
在客户端执行:
sftp –oPort=端口 用户名@服务端IP
如果不需要输入密码就可以连上,则说明配置成功
2、基于JSCH库的sftp操作
Java代码
1. public class SftpUtil {
2. private final static Logger log = LoggerFactory.getLogger(SftpUtil.class);
3.
4. /** SFTP */
5. public static final String SFTP = "sftp";
6. /** 通道 */
7. private ChannelSftp channel;
8. /** session */
9. private Session session;
10.
11. /** 规避多线程并发 */
12. private static ThreadLocal<SftpUtil> sftpLocal = new ThreadLocal<SftpUtil>();
13.
14. /**
15. * 获取sftpchannel
16. *
17. * @param connectConfig 连接配置
18. * @return
19. * @throws Exception
20. * @throws JSchException
21. */
22. private void init(ConnectConfig connectConfig) throws Exception {
23. String host = connectConfig.getHost();
24. int port = connectConfig.getPort();
25.
26. String userName = connectConfig.getUserName();
27.
28. //创建JSch对象
29. JSch jsch = new JSch();
30.
31. //添加私钥(信任登录方式)
32. if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {
33. jsch.addIdentity(connectConfig.getPrivateKey());
34. }
35.
36. session = jsch.getSession(userName, host, port);
37. if (log.isInfoEnabled()) {
38. log.info(" JSCH Session created,sftpHost = {}, sftpUserName={}", host, userName);
39. }
40.
41. //设置密码
42. if (StringUtils.isNotBlank(connectConfig.getPassWord())) {
43. session.setPassword(connectConfig.getPassWord());
44. }
45.
46. Properties config = new Properties();
47. config.put("StrictHostKeyChecking", "no");
48. session.setConfig(config);
49. //设置超时
50. session.setTimeout(connectConfig.getTimeout());
51. //建立连接
52. session.connect();
53. if (log.isInfoEnabled()) {
54. log.info("JSCH Session connected.sftpHost = {}, sftpUserName={}", host, userName);
55. }
56.
57. //打开SFTP通道
58. channel = (ChannelSftp) session.openChannel(SFTP);
59. //建立SFTP通道的连接
60. channel.connect();
61. if (log.isInfoEnabled()) {
62. log.info("Connected successfully to sftpHost = {}, sftpUserName={}", host, userName);
63. }
64. }
65.
66. /**
67. * 是否已连接
68. *
69. * @return
70. */
71. private boolean isConnected() {
72. return null != channel && channel.isConnected();
73. }
74.
75. /**
76. * 获取本地线程存储的sftp客户端
77. *
78. * @return
79. * @throws Exception
80. */
81. public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {
82. SftpUtil sftpUtil = sftpLocal.get();
83. if (null == sftpUtil || !sftpUtil.isConnected()) {
84. sftpLocal.set(new SftpUtil(connectConfig));
85. }
86. return sftpLocal.get();
87. }
88.
89. /**
90. * 释放本地线程存储的sftp客户端
91. */
92. public static void release() {
93. if (null != sftpLocal.get()) {
94. sftpLocal.get().closeChannel();
95. sftpLocal.set(null);
96. }
97. }
98.
99. /**
100. * 构造函数
101. * <p>
102. * 非线程安全,故权限为私有
103. * </p>
104. *
105. * @throws Exception
106. */
107. private SftpUtil(ConnectConfig connectConfig) throws Exception {
108. super();
109. init(connectConfig);
110. }
111.
112. /**
113. * 关闭通道
114. *
115. * @throws Exception
116. */
117. public void closeChannel() {
118. if (null != channel) {
119. try {
120. channel.disconnect();
121. } catch (Exception e) {
122. log.error("关闭SFTP通道发生异常:", e);
123. }
124. }
125. if (null != session) {
126. try {
127. session.disconnect();
128. } catch (Exception e) {
129. log.error("SFTP关闭 session异常:", e);
130. }
131. }
132. }
133.
134. /**
135. * 下载文件
136. *
137. * @param downDir 下载目录
138. * @param src 源文件
139. * @param dst 保存后的文件名称或目录
140. * @throws Exception
141. */
142. public void downFile(String downDir, String src, String dst) throws Exception {
143. channel.cd(downDir);
144. channel.get(src, dst);
145. }
146.
147. /**
148. * 删除文件
149. *
150. * @param filePath 文件全路径
151. * @throws SftpException
152. */
153. public void deleteFile(String filePath) throws SftpException {
154. channel.rm(filePath);
155. }
156.
157. @SuppressWarnings("unchecked")
158. public List<String> listFiles(String dir) throws SftpException {
159. Vector<LsEntry> files = channel.ls(dir);
160. if (null != files) {
161. List<String> fileNames = new ArrayList<String>();
162. Iterator<LsEntry> iter = files.iterator();
163. while (iter.hasNext()) {
164. String fileName = iter.next().getFilename();
165. if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) {
166. continue;
167. }
168. fileNames.add(fileName);
169. }
170. return fileNames;
171. }
172. return null;
173. }
174. }
说明:
2.1 ConnectConfig包含了建立sftp连接所需要的全部参数信息
Java代码
1. //添加私钥(信任登录方式)
2. if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {
3. jsch.addIdentity(connectConfig.getPrivateKey());
4. }
Java代码
1. /**
2. * 获取本地线程存储的sftp客户端
3. *
4. * @return
5. * @throws Exception
6. */
7. public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {
8. SftpUtil sftpUtil = sftpLocal.get();
9. if (null == sftpUtil || !sftpUtil.isConnected()) {
10. sftpLocal.set(new SftpUtil(connectConfig));
11. }
12. return sftpLocal.get();
13. }
14.
15. /**
16. * 释放本地线程存储的sftp客户端
17. */
18. public static void release() {
19. if (null != sftpLocal.get()) {
20. sftpLocal.get().closeChannel();
21. sftpLocal.set(null);
22. }
23. }