SFtp驗(yàn)證

通過(guò)SFtp的方式訪(fǎng)問(wèn)服務(wù)器的文件,一定程度上對(duì)服務(wù)器的安全性而言有比較大的提升。比方說(shuō):服務(wù)器只開(kāi)啟部分目錄下的訪(fǎng)問(wèn)權(quán)限,或者只開(kāi)啟讀權(quán)限等。

引入依賴(lài)

<dependency>

<groupId>com.jcraft</groupId>

<artifactId>jsch</artifactId>

<version>0.1.54</version>

</dependency>


常見(jiàn)的有兩種登錄方式:

1. ip賬號(hào)密碼

2.密鑰key方式

代碼及方法

package com.hf.zuul.zuul.sftps;

import com.jcraft.jsch.*;

import java.io.*;

import java.util.ArrayList;

import java.util.List;

import java.util.Properties;

import java.util.Vector;

/**

* @author hanfei

* @Date 2020/8/23

*/

public class SFtpMethod {

private ChannelSftpsftp;

? ? private Sessionsession;

? ? private Stringip;

? ? private int port;

? ? private StringuserName;

? ? private Stringpassword;

? ? private static final StringfolderPath ="/usr/local/20200805";

? ? private static final StringfileName ="check_credit_apply__mcaus_6eqfy";

? ? public SFtpMethod(String ip, int port, String userName, String password) {

this.ip = ip;

? ? ? ? this.port = port;

? ? ? ? this.userName = userName;

? ? ? ? this.password = password;

? ? }

/**

* 連接服務(wù)器,賬號(hào)密碼

*/

? ? public void connection(){

JSch jSch =new JSch();

? ? ? ? try {

session = jSch.getSession(userName, ip, port);

? ? ? ? ? ? session.setPassword(password);

? ? ? ? ? ? Properties properties =new Properties();

? ? ? ? ? ? properties.put("StrictHostKeyChecking", "no");

? ? ? ? ? ? session.setConfig(properties);

? ? ? ? ? ? session.connect();

? ? ? ? ? ? sftp = (ChannelSftp)session.openChannel("sftp");

? ? ? ? ? ? sftp.connect();

? ? ? ? }catch (JSchException e) {

e.printStackTrace();

? ? ? ? }

}

/**

* 連接服務(wù)器,密鑰方式

? ? * @param passphrase? ? 密鑰口令

? ? * @param keyFile? 密鑰路徑

*/

? ? public void connection(String passphrase, String keyFile){

JSch jSch =new JSch();

? ? ? ? try {

????????????jSch.addIdentity(keyFile);

? ? ? ? ? ? UserInfo userInfo =new MyUserInfo(passphrase);

? ? ? ? ? ? session = jSch.getSession(userName, ip, port);

? ? ? ? ? ? session.setUserInfo(userInfo);

? ? ? ? ? ? session.setTimeout(300000);

? ? ? ? ? ? Properties properties =new Properties();

? ? ? ? ? ? properties.put("StrictHostKeyChecking", "no");

? ? ? ? ? ? session.setConfig(properties);

? ? ? ? ? ? session.connect();

? ? ? ? ? ? sftp = (ChannelSftp)session.openChannel("sftp");

? ? ? ? ? ? sftp.connect();

? ? ? ? }catch (JSchException e) {

e.printStackTrace();

? ? ? ? }

}

/**

* 獲取所有文件名

*/

? ? public ListgetAllFileNames(){

connection();

? ? ? ? List fileNames =new ArrayList<>();

? ? ? ? try {

Vector entries =sftp.ls(folderPath);

? ? ? ? ? ? for (ChannelSftp.LsEntry entrie :entries) {

String name = entrie.getFilename();

? ? ? ? ? ? ? ? if (!".".equals(name) && !"..".equals(name)) {

fileNames.add(name);

? ? ? ? ? ? ? ? }

}

}catch (SftpException e) {

e.printStackTrace();

? ? ? ? }finally {

close();

? ? ? ? }

return fileNames;

? ? }

/**

* 獲取所有文件名,密鑰方式

*/

? ? public ListgetAllFileNames(String passphrase, String keyFile){

connection(passphrase, keyFile);

? ? ? ? List fileNames =new ArrayList<>();

? ? ? ? try {

Vector entries =sftp.ls(folderPath);

? ? ? ? ? ? for (ChannelSftp.LsEntry entrie :entries) {

String name = entrie.getFilename();

? ? ? ? ? ? ? ? if (!".".equals(name) && !"..".equals(name)) {

fileNames.add(name);

? ? ? ? ? ? ? ? }

}

}catch (SftpException e) {

e.printStackTrace();

? ? ? ? }finally {

close();

? ? ? ? }

return fileNames;

? ? }

/**

* 按行讀取文件

? ? * @return

? ? */

? ? public ListreadByLine(){

connection();

? ? ? ? List lines =new ArrayList<>();

? ? ? ? try {

sftp.cd(folderPath);

? ? ? ? ? ? InputStream in =sftp.get(fileName);

? ? ? ? ? ? BufferedReader buffer =new BufferedReader(new InputStreamReader(in));

? ? ? ? ? ? String line ="";

? ? ? ? ? ? while ((line = buffer.readLine()) !=null) {

lines.add(line);

? ? ? ? ? ? }

}catch (SftpException | IOException e) {

e.printStackTrace();

? ? ? ? }finally {

close();

? ? ? ? }

return lines;

? ? }

/**

* 下載文件

? ? * @param localDir

? ? * @return

? ? */

? ? public FiledownLoadFile(String localDir){

connection();

? ? ? ? File file =null;

? ? ? ? OutputStream out;

? ? ? ? try {

file =new File(localDir);

? ? ? ? ? ? sftp.cd(folderPath);

? ? ? ? ? ? out =new FileOutputStream(file);

? ? ? ? ? ? sftp.get(fileName, out);

? ? ? ? }catch (SftpException | FileNotFoundException e) {

e.printStackTrace();

? ? ? ? }finally {

close();

? ? ? ? }

return file;

? ? }

public void close(){

if (sftp !=null) {

sftp =null;

? ? ? ? }

if (session !=null) {

session =null;

? ? ? ? }

}

public static void main(String[] args) {

SFtpMethod sFtpMethod =new SFtpMethod("",22,"","");

? ? ? ? // 顯示所有文件名

? ? ? ? List fileNames = sFtpMethod.getAllFileNames();

? ? ? ? for (String fileName : fileNames) {

System.out.println(fileName);

? ? ? ? }

//? ? ? ? // 按行讀取文件輸出

? ? ? ? List lines = sFtpMethod.readByLine();

? ? ? ? for (String line : lines) {

System.out.println(line);

? ? ? ? }

//? ? ? ? // 下載文件

? ? ? ? sFtpMethod.downLoadFile("/Users/Downloads/check_credit_apply__mcaus_6eqfy");

//? ? ? ? // 密鑰方式

? ? ? ? List fileNamess = sFtpMethod.getAllFileNames("","");

? ? ? ? for (String fileName : fileNamess) {

System.out.println(fileName);

? ? ? ? }

}

/**

* 身份信息

*/

? ? class MyUserInfoimplements UserInfo{

private Stringpassphrase;

? ? ? ? public MyUserInfo(String passphrase) {

this.passphrase = passphrase;

? ? ? ? }

@Override

? ? ? ? public StringgetPassphrase() {

return null;

? ? ? ? }

@Override

? ? ? ? public StringgetPassword() {

return null;

? ? ? ? }

@Override

? ? ? ? public boolean promptPassword(String s) {

return false;

? ? ? ? }

@Override

? ? ? ? public boolean promptPassphrase(String s) {

return false;

? ? ? ? }

@Override

? ? ? ? public boolean promptYesNo(String s) {

return false;

? ? ? ? }

@Override

? ? ? ? public void showMessage(String s) {

}

}

}

通過(guò)秘鑰方式進(jìn)行sftp連接,需要在本地生成秘鑰:ssh-keygen,然后一路回車(chē)或兩次輸入passphrase。接著在.ssh文件夾下使用命令 ssh-copy-id 賬號(hào)@118.XX.XX.XX(目標(biāo)服務(wù)器ip),將公鑰加入到目標(biāo)服務(wù)器的authorized_keys中,接著登錄服務(wù)器進(jìn)行.ssh目錄,chmod 664 authorized_keys,賦予權(quán)限。如果是mac系統(tǒng)可以使用ssh-keygen -e。

秘鑰文件路徑keyFile是本地的私鑰路徑(包含文件名)。下面簡(jiǎn)單驗(yàn)證一下:

我保持本地私鑰文件位置正確的情況下,改變服務(wù)器的私鑰位置或名字,仍能夠正常訪(fǎng)問(wèn)。


在秘鑰驗(yàn)證時(shí),我將keyFile路徑設(shè)置為一個(gè)本地不存在的文件的路徑,報(bào)錯(cuò)如下:

本地私鑰不存在

我再把參數(shù)keyFile變?yōu)橐粋€(gè)本地存在的文件,但不是私鑰文件位置。報(bào)錯(cuò)如下:

私鑰無(wú)效

我將passphrase參數(shù)設(shè)置任意一個(gè)值,還是可以成功連接。這一點(diǎn)很疑惑,不知道為啥,但成功了就高興。

?properties.put("StrictHostKeyChecking", "no");StrictHostKeyChecking有三種選項(xiàng),no、ask、yes。這三個(gè)選項(xiàng)代表了不同的級(jí)別,yes最高,no最低。在ssh訪(fǎng)問(wèn)服務(wù)器的過(guò)程中,會(huì)將服務(wù)器的公鑰保存到本地的~/.ssh/known_hosts中,每次訪(fǎng)問(wèn)服務(wù)器都會(huì)檢查此公鑰是否發(fā)生變化,如果發(fā)生了變化,則這三個(gè)選項(xiàng)的設(shè)置如下:

no:自動(dòng)將服務(wù)器新的公鑰保存到known_hosts中,并發(fā)出一個(gè)警告;

ask:拒絕連接到服務(wù)器,且發(fā)出一個(gè)警告;

yes:拒絕連接到服務(wù)器,且不發(fā)出警告;

一般在測(cè)試環(huán)境下使用no,生產(chǎn)環(huán)境使用yes或ask。


參考:http://m.itdecent.cn/p/090792e12518

https://juejin.im/post/6844904004493770759

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容