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操作
- public class SftpUtil {
- private final static Logger log = LoggerFactory.getLogger(SftpUtil.class);
- /** SFTP */
- public static final String SFTP = "sftp";
- /** 通道 */
- private ChannelSftp channel;
- /** session */
- private Session session;
- /** 規避多線程並發 */
- private static ThreadLocal<SftpUtil> sftpLocal = new ThreadLocal<SftpUtil>();
- /**
- * 獲取sftpchannel
- *
- * @param connectConfig 連接配置
- * @return
- * @throws Exception
- * @throws JSchException
- */
- private void init(ConnectConfig connectConfig) throws Exception {
- String host = connectConfig.getHost();
- int port = connectConfig.getPort();
- String userName = connectConfig.getUserName();
- //創建JSch對象
- JSch jsch = new JSch();
- //添加私鑰(信任登錄方式)
- if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {
- jsch.addIdentity(connectConfig.getPrivateKey());
- }
- session = jsch.getSession(userName, host, port);
- if (log.isInfoEnabled()) {
- log.info(" JSCH Session created,sftpHost = {}, sftpUserName={}", host, userName);
- }
- //設置密碼
- if (StringUtils.isNotBlank(connectConfig.getPassWord())) {
- session.setPassword(connectConfig.getPassWord());
- }
- Properties config = new Properties();
- config.put("StrictHostKeyChecking", "no");
- session.setConfig(config);
- //設置超時
- session.setTimeout(connectConfig.getTimeout());
- //建立連接
- session.connect();
- if (log.isInfoEnabled()) {
- log.info("JSCH Session connected.sftpHost = {}, sftpUserName={}", host, userName);
- }
- //打開SFTP通道
- channel = (ChannelSftp) session.openChannel(SFTP);
- //建立SFTP通道的連接
- channel.connect();
- if (log.isInfoEnabled()) {
- log.info("Connected successfully to sftpHost = {}, sftpUserName={}", host, userName);
- }
- }
- /**
- * 是否已連接
- *
- * @return
- */
- private boolean isConnected() {
- return null != channel && channel.isConnected();
- }
- /**
- * 獲取本地線程存儲的sftp客戶端
- *
- * @return
- * @throws Exception
- */
- public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {
- SftpUtil sftpUtil = sftpLocal.get();
- if (null == sftpUtil || !sftpUtil.isConnected()) {
- sftpLocal.set(new SftpUtil(connectConfig));
- }
- return sftpLocal.get();
- }
- /**
- * 釋放本地線程存儲的sftp客戶端
- */
- public static void release() {
- if (null != sftpLocal.get()) {
- sftpLocal.get().closeChannel();
- sftpLocal.set(null);
- }
- }
- /**
- * 構造函數
- * <p>
- * 非線程安全,故權限為私有
- * </p>
- *
- * @throws Exception
- */
- private SftpUtil(ConnectConfig connectConfig) throws Exception {
- super();
- init(connectConfig);
- }
- /**
- * 關閉通道
- *
- * @throws Exception
- */
- public void closeChannel() {
- if (null != channel) {
- try {
- channel.disconnect();
- } catch (Exception e) {
- log.error("關閉SFTP通道發生異常:", e);
- }
- }
- if (null != session) {
- try {
- session.disconnect();
- } catch (Exception e) {
- log.error("SFTP關閉 session異常:", e);
- }
- }
- }
- /**
- * 下載文件
- *
- * @param downDir 下載目錄
- * @param src 源文件
- * @param dst 保存后的文件名稱或目錄
- * @throws Exception
- */
- public void downFile(String downDir, String src, String dst) throws Exception {
- channel.cd(downDir);
- channel.get(src, dst);
- }
- /**
- * 刪除文件
- *
- * @param filePath 文件全路徑
- * @throws SftpException
- */
- public void deleteFile(String filePath) throws SftpException {
- channel.rm(filePath);
- }
- @SuppressWarnings("unchecked")
- public List<String> listFiles(String dir) throws SftpException {
- Vector<LsEntry> files = channel.ls(dir);
- if (null != files) {
- List<String> fileNames = new ArrayList<String>();
- Iterator<LsEntry> iter = files.iterator();
- while (iter.hasNext()) {
- String fileName = iter.next().getFilename();
- if (StringUtils.equals(".", fileName) || StringUtils.equals("..", fileName)) {
- continue;
- }
- fileNames.add(fileName);
- }
- return fileNames;
- }
- return null;
- }
- }
說明:
2.1 ConnectConfig包含了建立sftp連接所需要的全部參數信息
2.2 如果按照第一步進行了sftp的信任公鑰配置,則需要通過調用jsch的addIdentity方法將密鑰對中的私鑰id_dsa設置進去- //添加私鑰(信任登錄方式)
- if (StringUtils.isNotBlank(connectConfig.getPrivateKey())) {
- jsch.addIdentity(connectConfig.getPrivateKey());
- }
- /**
- * 獲取本地線程存儲的sftp客戶端
- *
- * @return
- * @throws Exception
- */
- public static SftpUtil getSftpUtil(ConnectConfig connectConfig) throws Exception {
- SftpUtil sftpUtil = sftpLocal.get();
- if (null == sftpUtil || !sftpUtil.isConnected()) {
- sftpLocal.set(new SftpUtil(connectConfig));
- }
- return sftpLocal.get();
- }
- /**
- * 釋放本地線程存儲的sftp客戶端
- */
- public static void release() {
- if (null != sftpLocal.get()) {
- sftpLocal.get().closeChannel();
- sftpLocal.set(null);
- }
- }