日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SFTP服务器的搭建

發(fā)布時間:2023/12/31 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SFTP服务器的搭建 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

SFTP是基于默認的22端口,是SSH內含的協(xié)議,只要啟動了sshd就可以使用。相比于高效率的FTP協(xié)議,SFTP的優(yōu)點是更安全的通信。

一、centos7搭建SFTP

1、創(chuàng)建sftp組,查看組信息

groupadd sftpcat /etc/group

2、創(chuàng)建一個sftp用戶【szysftp】并加入到創(chuàng)建的sftp組中,同時修改【szysftp】用戶的密碼

useradd -g sftp -s /bin/false szysftppasswd szysftp

3、新建目錄,指定為【szysftp】用戶的主目錄

mkdir -p /sftp/szysftpusermod -d /sftp/szysftp szysftp

4、編輯配置文件/etc/ssh/sshd_config

將如下這行注釋

# Subsystem sftp /usr/libexec/openssh/sftp-server

然后在文件末尾添加如下幾行,并保存

Subsystem sftp internal-sftp Match Group sftp ChrootDirectory /sftp/%u ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no

5、設置Chroot目錄權限

chown root:sftp /sftp/szysftp #文件夾所有者必須為root,用戶組可以不是rootchmod 755 /sftp/szysftp #權限不能超過755,否則會導致登錄報錯,可以是755

存在多級目錄設權只設置了第一層目錄問題,如果出現(xiàn)這個問題,可以一級一級目錄設置權限。

6、新建一個目錄供sftp用戶【szysftp】上傳文件,這個目錄所有者為【szysftp】所有組為sftp,所有者有寫入權限所有組無寫入權限

mkdir /sftp/szysftp/uploadchown szysftp:sftp /sftp/szysftp/upload chmod 755 /sftp/szysftp/upload

新建的目錄用作java連接時的目錄,即:

sftp.cd(path)//寫入目錄

7、關閉selinux并重啟sshd服務,然后測試

setenforce 0service sshd restart

8、sftp常用命令

cat /etc/passwd 查看所有用戶 userdel ftpuser 刪除用戶ftpusercd 路徑 進入某路徑 lcd 路徑` 更改本地目錄到某路徑” chgrp group a.txt 將文件a.txt的組更改為group chmod 777 a.txt 將文件a.txt的權限更改為777 chown owner a.txt 將文件a.txt的屬主更改為owner exit 退出 sftp quit 退出 sftp get 遠程路徑 下載文件 ln existingpath linkpath 符號鏈接遠程文件 ls [參數(shù)] [路徑] 顯示遠程目錄列表 lls [參數(shù)] [路徑] 顯示本地目錄列表 mkdir 路徑 創(chuàng)建遠程目錄 lmkdir 路徑 創(chuàng)建本地目錄 mv oldpath newpath 移動遠程文件 put 本地路徑 上傳文件 pwd 顯示遠程工作目錄 lpwd 打印本地工作目錄 rmdir 路徑 刪除遠程目錄 lrmdir 路徑 移除刪除目錄 rm 路徑 刪除遠程文件 lrm 路徑 刪除本地文件

?

二、連接sftp會話

sftp> lcd E:\sql sftp> sftp> cd /home/sql sftp> sftp> put dsm_mysql.sql Uploading dsm_mysql.sql to /home/sql/dsm_mysql.sql100% 331KB 331KB/s 00:00:00 E:\sql\dsm_mysql.sql: 339166 bytes transferred in 0 seconds (331 KB/s) sftp>

三、Java實現(xiàn)文件上傳下載

在配置文件【application.properties】里配置sftp連接參數(shù)

sftp.ip=192.168.*** sftp.user=*** sftp.password=*** sftp.port=22sftp.img.ip=192.168.*** sftp.img.user=*** sftp.img.password=*** sftp.img.port=22 package com.bw.note.util;import com.bw.common.redis.StringRedisService; import com.bw.note.config.interceptor.LoginInterceptor; import com.bw.note.entity.po.DsmFilelist; import com.bw.note.mapper.DictMapper; import com.google.common.base.Strings; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import org.apache.commons.lang.StringUtils; import org.apache.tika.Tika; import org.apache.tika.config.TikaConfig; import org.apache.tika.mime.MimeType; import org.apache.tika.mime.MimeTypeException; import org.apache.tika.mime.MimeTypes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile;import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.nio.file.Paths; import java.text.SimpleDateFormat; import java.util.Date;/*** <文件上傳>* <功能詳細描述>** @author ly* @version [版本號, 2021/06/07 09:51]* @see [相關類/方法]* @since [產(chǎn)品/模塊版本]*/@Component public class FileUploadUtil {private static final TikaConfig TIKA_CONFIG = TikaConfig.getDefaultConfig();private static final MimeTypes MIME_TYPES = TIKA_CONFIG.getMimeRepository();private static final Tika TIKA = new Tika();//指定的服務器地址private static String ip;//用戶名private static String user;//密碼private static String password;//服務器端口private static int port;//指定的服務器地址private static String imgIp;//用戶名private static String imgUser;//密碼private static String imgPassword;//服務器端口 默認private static int imgPort;@Value("${sftp.ip}")public void setIp(String ip) {FileUploadUtil.ip = ip;}@Value("${sftp.user}")public void setUser(String user) {FileUploadUtil.user = user;}@Value("${sftp.password}")public void setPassword(String password) {FileUploadUtil.password = password;}@Value("${sftp.port}")public void setPort(int port) {FileUploadUtil.port = port;}@Value("${sftp.img.ip}")public void setImgIp(String imgIp) {FileUploadUtil.imgIp = imgIp;}@Value("${sftp.img.user}")public void setImgUser(String imgUser) {FileUploadUtil.imgUser = imgUser;}@Value("${sftp.img.password}")public void setImgPassword(String imgPassword) {FileUploadUtil.imgPassword = imgPassword;}@Value("${sftp.img.port}")public void setImgPort(int imgPort) {FileUploadUtil.imgPort = imgPort;}/*** ly* <上傳文件至遠程服務器>* @param bytes 文件字節(jié)流* @param fileName 文件名* @return void* @see [類、類#方法、類#成員]*/public static DsmFilelist sftpUploadFile(byte[] bytes, String fileName,String path, String token) throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");fileName = sdf.format(new Date()) + "_" + fileName;Session session;Channel channel = null;JSch jsch = new JSch();if (port <= 0) {//連接服務器session = jsch.getSession(user, ip);} else {//采用指定的端口連接服務器session = jsch.getSession(user, ip, port);}//如果服務器連接不上,則拋出異常if (session == null) {throw new Exception("session is null");}//設置登陸主機的密碼session.setPassword(password);//設置密碼//設置第一次登陸的時候提示,可選值:(ask | yes | no)session.setConfig("StrictHostKeyChecking", "no");//設置登陸超時時間session.connect(30000);OutputStream outstream = null;try {//創(chuàng)建sftp通信通道channel = (Channel) session.openChannel("sftp");channel.connect(1000);ChannelSftp sftp = (ChannelSftp) channel;//進入服務器指定的文件夾sftp.cd(path);outstream = sftp.put(fileName);outstream.write(bytes);} catch (Exception e) {e.printStackTrace();} finally {//關流操作if (outstream != null) {outstream.flush();outstream.close();}if (session != null) {session.disconnect();}if (channel != null) {channel.disconnect();}}DsmFilelist filelist = new DsmFilelist();filelist.setFileName(fileName);filelist.setFilePath(path+File.separator+fileName);String userId = LoginInterceptor.loginUtilByUserId(token);filelist.setCreateBy(userId);return filelist;}static void upload(){}/*** ly* <上傳圖片至遠程服務器>* @param bytes 文件字節(jié)流* @param fileName 文件名* @return void* @see [類、類#方法、類#成員]*/public static String sftpUploadImg(byte[] bytes, String fileName,String path) throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");fileName = sdf.format(new Date()) + "_" + fileName;Session session;Channel channel = null;JSch jsch = new JSch();if (imgPort <= 0) {//連接服務器session = jsch.getSession(imgUser, imgIp);} else {//采用指定的端口連接服務器session = jsch.getSession(imgUser, imgIp, imgPort);}//如果服務器連接不上,則拋出異常if (session == null) {throw new Exception("session is null");}//設置登陸主機的密碼session.setPassword(imgPassword);//設置密碼//設置第一次登陸的時候提示,可選值:(ask | yes | no)session.setConfig("StrictHostKeyChecking", "no");//設置登陸超時時間session.connect(30000);OutputStream outstream = null;try {//創(chuàng)建sftp通信通道channel = (Channel) session.openChannel("sftp");channel.connect(1000);ChannelSftp sftp = (ChannelSftp) channel;//進入服務器指定的文件夾sftp.cd(path);outstream = sftp.put(fileName);outstream.write(bytes);} catch (Exception e) {e.printStackTrace();} finally {//關流操作if (outstream != null) {outstream.flush();outstream.close();}if (session != null) {session.disconnect();}if (channel != null) {channel.disconnect();}}return path+File.separator+fileName;}/*** ly* <下載遠程服務器文件>* @param fileName 文件名稱* @return byte[]* @see [類、類#方法、類#成員]*/public static byte[] sftpDownloadFile(String fileName,String path) throws Exception {Session session;Channel channel = null;JSch jsch = new JSch();if (port <= 0) {session = jsch.getSession(user, ip);} else {//采用指定的端口連接服務器session = jsch.getSession(user, ip, port);}//如果服務器連接不上,則拋出異常if (session == null) {throw new Exception("session is null");}//設置登陸主機的密碼session.setPassword(password);//設置密碼//設置第一次登陸的時候提示,可選值:(ask | yes | no)session.setConfig("StrictHostKeyChecking", "no");//設置登陸超時時間session.connect(30000);InputStream inputStream = null;byte[] bytes = null;try {//創(chuàng)建sftp通信通道channel = (Channel) session.openChannel("sftp");channel.connect(1000);ChannelSftp sftp = (ChannelSftp) channel;//進入服務器指定的文件夾sftp.cd(path);//列出服務器指定的文件列表// Vector v = sftp.ls("*");// for(int i=0;i<v.size();i++){// System.out.println(v.get(i));// }inputStream = sftp.get(fileName);bytes = readInputStream(inputStream);} catch (Exception e) {e.printStackTrace();} finally {//關流操作if (session != null) {session.disconnect();}if (channel != null) {channel.disconnect();}}return bytes;}//輸入流轉二進制public static byte[] readInputStream(InputStream inputStream) throws IOException {byte[] buffer = new byte[1024];int len = 0;ByteArrayOutputStream bos = new ByteArrayOutputStream();while((len = inputStream.read(buffer)) != -1) {bos.write(buffer, 0, len);}bos.close();return bos.toByteArray();}public static DsmFilelist uploadFile(MultipartFile file, String savePath, String token) {detectFileMimeType(file);DsmFilelist filelist = new DsmFilelist();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String fileName = sdf.format(new Date()) + "_" + file.getOriginalFilename();//文件路徑File storeDirectory = new File(savePath);//沒有則創(chuàng)建if (!storeDirectory.exists()) {storeDirectory.mkdirs();}String path = savePath + File.separator + fileName;File file1 = new File(path);try {file.transferTo(file1);} catch (IOException e) {e.printStackTrace();}filelist.setFileName(file.getOriginalFilename());filelist.setFilePath(file1.getPath());String userId = LoginInterceptor.loginUtilByUserId(token);filelist.setCreateBy(userId);return filelist;}public static void detectFileMimeType(MultipartFile file){// 通過文件名稱截取的后綴名稱String postfix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);String externFileName = null;try {externFileName = getFileExtension(detectFileMimeType(file.getInputStream(), file.getOriginalFilename()), file.getOriginalFilename());if (StringUtils.isEmpty(externFileName)) {throw new RuntimeException("文件格式錯誤");}//是否是允許的類型String simpleActualFileType = externFileName.replace(".", "").trim().toLowerCase();//判斷文件實際類型和擴展名是否一致if (!simpleActualFileType.equals(postfix.replace(".", "").trim().toLowerCase())) {throw new RuntimeException("文件實際類型與上傳類型不一致");}} catch (IOException e) {e.printStackTrace();} catch (MimeTypeException e) {e.printStackTrace();}if (StringUtils.isNotBlank(externFileName) && StringUtils.isNotBlank(postfix)) {if (!(externFileName.toUpperCase().contains("BMP")|| externFileName.toUpperCase().contains("JPG")|| externFileName.toUpperCase().contains("JPEG")|| externFileName.toUpperCase().contains("PNG")|| externFileName.toUpperCase().contains("DOCX")|| externFileName.toUpperCase().contains("PDF")|| externFileName.toUpperCase().contains("XLS")|| externFileName.toUpperCase().contains("XLSX")|| externFileName.toUpperCase().contains("GP")|| externFileName.toUpperCase().contains("DOC")&& externFileName.toUpperCase().contains(postfix.toUpperCase()))){throw new RuntimeException("請上傳!圖片【PNG,JPEG,JPG】;文件【DOCX,PDF,XLS,XLSX,BMP,GP,DOC】類型文件");}}}/*** lzm* <一句話功能簡述>* <功能詳細描述>** @param len 文件長度* @param size 限制大小* @param unit 限制單位(B,K,M,G)* @return boolean* @see [類、類#方法、類#成員]*/public static boolean checkFileSize(Long len, int size, String unit) {double fileSize = 0;if ("B".equals(unit.toUpperCase())) {fileSize = (double) len;} else if ("K".equals(unit.toUpperCase())) {fileSize = (double) len / 1024;} else if ("M".equals(unit.toUpperCase())) {fileSize = (double) len / 1048576;} else if ("G".equals(unit.toUpperCase())) {fileSize = (double) len / 1073741824;}if (fileSize > size) {return false;}return true;}/*** <判斷文件是否是圖片>** @author ly* @version [版本號, 2019/10/22 15:42]* @see [相關類/方法]* @since [產(chǎn)品/模塊版本]*/public static boolean checkImg(InputStream inputStream) {try {Image image = ImageIO.read(inputStream);return image != null;} catch (IOException ex) {return false;}}/*** ly* <一句話功能簡述>* <判斷圖片長寬>** @param file 圖片* @param width 圖片寬度* @param height 圖片高度* @return boolean* @see [類、類#方法、類#成員]*/public static boolean checkImgSize(MultipartFile file, Integer width, Integer height, String savePath) throws IOException {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");String fileName = sdf.format(new Date()) + "_" + file.getOriginalFilename();//文件路徑File storeDirectory = new File(savePath);//沒有則創(chuàng)建if (!storeDirectory.exists()) {storeDirectory.mkdirs();}String path = savePath + File.separator + fileName;File file1 = new File(path);Boolean flag = false;FileInputStream inputStream = null;try (InputStream stream = file.getInputStream();FileOutputStream fs = new FileOutputStream(path)){/*InputStream stream = file.getInputStream();FileOutputStream fs = new FileOutputStream(path);*/byte[] buffer = new byte[1024 * 1024];int bytesum = 0;int byteread = 0;while ((byteread = stream.read(buffer)) != -1) {bytesum += byteread;fs.write(buffer, 0, byteread);fs.flush();}fs.close();stream.close();inputStream = new FileInputStream(file1);BufferedImage sourceImg = ImageIO.read(inputStream);if (width.equals(sourceImg.getWidth()) && height.equals(sourceImg.getHeight())) {return true;}} catch (IOException e) {e.printStackTrace();} finally {inputStream.close();file1.delete();}return false;}public static void setInputStream(InputStream inStream, HttpServletResponse response) {// 循環(huán)取出流中的數(shù)據(jù)byte[] b = new byte[Constant.GLOBAL_ONE_HUNDRED];int len;try {while ((len = inStream.read(b)) > Constant.GLOBAL_INT_ZERO)response.getOutputStream().write(b, Constant.GLOBAL_INT_ZERO, len);inStream.close();} catch (IOException e) {e.printStackTrace();}}/*** detect file mime type using apache tika.** @param inputStream file input stream* @param originalFilename original file name* @return file mime type* @throws IOException if read file failed* @throws MimeTypeException if detect failed*/public static MimeType detectFileMimeType(InputStream inputStream, String originalFilename)throws IOException, MimeTypeException {String contentType = TIKA.detect(inputStream, originalFilename);if (Strings.isNullOrEmpty(contentType)) {return null;}return createMimeType(contentType);}public static MimeType createMimeType(String contentType) throws MimeTypeException {return MIME_TYPES.forName(contentType);}/*** 獲取文件的擴展名. 首先根據(jù)content-type獲取對應的擴展名, 如果無法獲取, 獲取文件名的后綴** @param contentType file content type* @param filename file name* @return file extension, if can not detect, return empty string*/public static String getFileExtension(MimeType contentType, String filename) {String extension = "";if (contentType != null) {extension = contentType.getExtension();}if (Strings.isNullOrEmpty(extension) && !Strings.isNullOrEmpty(filename)) {extension = getFileExtension(filename);}return extension;}/*** 獲取文件擴展名.** @param filename file name* @return file extension or empty string*/public static String getFileExtension(String filename) {int dotIndex = filename.lastIndexOf('.');if (dotIndex != -1) {return filename.substring(dotIndex);}return "";}/*** 獲取文件名. 如果包含路徑, 去除路徑; 如果包含擴展名,去掉擴展名.** @param filePath file path* @return file name*/public static String getFilenameWithoutExtension(String filePath) {String filename = Paths.get(filePath).toFile().getName();int dotIndex = filename.lastIndexOf('.');if (dotIndex != -1) {return filename.substring(0, dotIndex);}return filename;} }

總結

以上是生活随笔為你收集整理的SFTP服务器的搭建的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。