SFTP 实践
FTP是文件传输协议。如果你想把文件和人共享,最便捷的方式莫过于把文件上传到FTP服务器上,其他人通过FTP客户端程序来下载所需要的文件。
FTP进行文件传输需要通过端口进行。一般所需端口为:
1. 控制链路—TCP端口21。控制器端。用于发送指令给服务器以及等待服务器响应。
2. 数据链路---TCP端口20。数据传输端口。用来建立数据传输通道的。主要用来从客户向服务器发送一个文件、从服务器向客户发送一个文件、从服务器向客户发送文件或目录列表。
FTP为了适应不同的网络环境,支持主动连接和被动连接两种模式。这两种模式都主要针对数据链路进行的,跟控制链路无关。
FTP的安全隐患:
一、FTP服务器软件漏洞。
二、明文口令。
三、FTP旗标。
四、通过FTP服务器进行端口扫描。
五、数据劫持。
FTP的安全策略:
一、使用较比安全的系统和FTP服务软件。
二、使用密文传输用户名和口令。
三、更改服务软件的旗标。
四、加强协议安全性。
SFTP是Secure File Transfer Protocol的缩写,是安全文件传送协议。可以为传输文件提供一种安全的加密方法。跟ftp几乎语法功能一样。
SFTP是SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。它本身没有单独的守护进程,必须使用sshd守护进程来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以使用SFTP是十分安全的。但由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多。在对网络安全性要求更高时,代替FTP使用。
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
注意事项:Session 也需要关闭,否则会造成sshd进程过多,需要重启ssh
package com.xxx.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.util.CollectionUtils;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class SFTPUtil implements Serializable
{
/**
*
*/
private static final long serialVersionUID = -3802033231641386902L;
private Logger logger = LoggerFactory.getLogger(getClass());
private String host;
private String username;
private String password;
private int port;
private ChannelSftp sftp;
private Session sshSession;
private String localPath;
private String remotePath;
private List<String> listPath;
/**
* connect server via sftp
*/
public void connect()
{
try
{
if (sftp != null)
{
sftp = null;
}
JSch jsch = new JSch();
jsch.getSession(username, host, port);
sshSession = jsch.getSession(username, host, port);
logger.info("Session created.");
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
logger.info("Session connected.");
logger.info("Opening Channel.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
logger.info("Connected to " + host + ".");
} catch (Exception e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
}
}
/**
* Disconnect with server
*/
public void disconnect()
{
try
{
if (this.sftp != null)
{
if (this.sftp.isConnected())
{
this.sftp.disconnect();
this.sftp.exit();
sshSession.disconnect();
logger.info("sftp is closed sucess! ");
} else if (this.sftp.isClosed())
{
logger.info("sftp is closed already");
}
}
} catch (Exception e)
{
logger.error("sftp close error ! msg : "
+ ExceptionUtils.getFullStackTrace(e));
}
}
/**
*
* @author cyl
* @date 2016-3-3 下午7:28:48
* @param directory
* @param downloadFile
* @param saveFile
* @param sftp
* @return void
*/
public void download(String directory, String downloadFile, String saveFile)
{
try
{
this.connect();
sftp.cd(directory);
File file = new File(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
} catch (Exception e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} finally
{
this.disconnect();
}
}
public void uploadBatch()
{
try
{
if (CollectionUtils.isEmpty(listPath))
{
logger.error("listPath is null ");
return;
}
this.connect();
// 创建文件,windows连接linux测试时,报错误, linux OS: 使用”/“ 例子:/home/user/XXX
// windows OS: 使用”\“ 例子:C:\Program Files
createDir(this.remotePath);
for (String path : listPath)
{
File file = new File(path);
logger.info("localFile : " + file.getAbsolutePath());
if (file.isFile())
{
logger.info("remotePath:" + this.remotePath);
File rfile = new File(this.remotePath);
String rpath = rfile.getParent();
try
{
this.sftp.cd(remotePath);
} catch (Exception e)
{
logger.error("cd path failed:{}, {}", rpath,
ExceptionUtils.getFullStackTrace(e));
break;
}
this.sftp.put(new FileInputStream(file), file.getName());
logger.info("upload file from path : {} to {}", path,
remotePath);
}
}
} catch (FileNotFoundException e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} catch (SftpException e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} finally
{
this.disconnect();
}
}
public void upload()
{
try
{
this.connect();
File file = new File(localPath);
logger.info("localFile : " + file.getAbsolutePath());
if (file.isFile())
{
logger.info("remotePath:" + this.remotePath);
File rfile = new File(this.remotePath);
String rpath = rfile.getParent();
try
{
this.sftp.cd(remotePath);
} catch (Exception e)
{
logger.error("*******create path failed:{}, {}", rpath,
ExceptionUtils.getFullStackTrace(e));
}
this.sftp.put(new FileInputStream(file), file.getName());
logger.info("=========upload down for " + localPath);
}
} catch (FileNotFoundException e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} catch (SftpException e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} finally
{
this.disconnect();
}
}
/**
* create Directory
*
* @param filepath
* @param sftp
*/
public void createDir(String filepath)
{
boolean bcreated = false;
boolean bparent = false;
File file = new File(filepath);
String ppath = file.getParent();
try
{
this.sftp.cd(ppath);
bparent = true;
} catch (SftpException e1)
{
bparent = false;
}
try
{
if (bparent)
{
try
{
this.sftp.cd(filepath);
bcreated = true;
} catch (Exception e)
{
bcreated = false;
}
if (!bcreated)
{
this.sftp.mkdir(filepath);
bcreated = true;
}
return;
} else
{
createDir(ppath);
this.sftp.cd(ppath);
this.sftp.mkdir(filepath);
}
} catch (SftpException e)
{
logger.error("mkdir failed : {} ,{}", filepath,
ExceptionUtils.getFullStackTrace(e));
}
try
{
this.sftp.cd(filepath);
} catch (SftpException e)
{
logger.error("can not cd into : {}, {}", filepath,
ExceptionUtils.getFullStackTrace(e));
}
}
/**
* get all the files need to be upload or download
*
* @param file
* @return
*/
public List<String> getFileEntryList(String file)
{
ArrayList<String> fileList = new ArrayList<String>();
InputStream in = null;
try
{
in = new FileInputStream(file);
InputStreamReader inreader = new InputStreamReader(in);
LineNumberReader linreader = new LineNumberReader(inreader);
String filepath = linreader.readLine();
while (filepath != null)
{
fileList.add(filepath);
filepath = linreader.readLine();
}
in.close();
} catch (FileNotFoundException e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} catch (IOException e)
{
logger.error(ExceptionUtils.getFullStackTrace(e));
} finally
{
if (in != null)
{
in = null;
}
}
return fileList;
}
/**
* @return the host
*/
public String getHost()
{
return host;
}
/**
* @param host
* the host to set
*/
public void setHost(String host)
{
this.host = host;
}
/**
* @return the username
*/
public String getUsername()
{
return username;
}
/**
* @param username
* the username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* @return the password
*/
public String getPassword()
{
return password;
}
/**
* @param password
* the password to set
*/
public void setPassword(String password)
{
this.password = password;
}
/**
* @return the port
*/
public int getPort()
{
return port;
}
/**
* @param port
* the port to set
*/
public void setPort(int port)
{
this.port = port;
}
/**
* @return the sftp
*/
public ChannelSftp getSftp()
{
return sftp;
}
/**
* @param sftp
* the sftp to set
*/
public void setSftp(ChannelSftp sftp)
{
this.sftp = sftp;
}
/**
* @return the localPath
*/
public String getLocalPath()
{
return localPath;
}
/**
* @param localPath
* the localPath to set
*/
public void setLocalPath(String localPath)
{
this.localPath = localPath;
}
/**
* @return the remotePath
*/
public String getRemotePath()
{
return remotePath;
}
/**
* @param remotePath
* the remotePath to set
*/
public void setRemotePath(String remotePath)
{
this.remotePath = remotePath;
}
public List<String> getListPath()
{
return listPath;
}
public void setListPath(List<String> listPath)
{
this.listPath = listPath;
}
public static void main(String[] args) throws Exception
{
// SFTPUtil ftp = new SFTPUtil();
// ftp.setUsername("root");
// ftp.setHost("10.1.11.11");
// ftp.setPort(22);
// ftp.setPassword("sss");
// ftp.setRemotePath("/tmp/1");
// //
// ftp.setLocalPath("/tmp/2/1.txt");
// // TODO Auto-generated method stub
// ftp.upload();
// ftp.disconnect();
List<String> listPath = new ArrayList<>();
listPath.add("/tmp/exp/data/FLOW_HD_56f115893144372cacda69e4_2016041203580000000.txt");
SFTPUtil ftp = new SFTPUtil();
ftp.setUsername("root");
ftp.setHost("10.1.15.28");
ftp.setPort(22);
ftp.setPassword("sss");
ftp.setRemotePath("/tmp/com1/ss1/ocs1/common1/utils");
ftp.setListPath(listPath);
ftp.connect();
ftp.createDir("/tmp/com1/ss1/ocs1/common1/utils");
ftp.uploadBatch();
//
// ftp.download("/tmp/1", "/tmp/1/1.txt",
// "C:\\Users\\changyuanlong\\Desktop\\a\\2.txt");
}
}