SFTP服务器的搭建
生活随笔
收集整理的這篇文章主要介紹了
SFTP服务器的搭建
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
前言
SFTP是基于默認的22端口,是SSH內含的協(xié)議,只要啟動了sshd就可以使用。相比于高效率的FTP協(xié)議,SFTP的優(yōu)點是更安全的通信。
一、centos7搭建SFTP
1、創(chuàng)建sftp組,查看組信息
groupadd sftpcat /etc/group2、創(chuàng)建一個sftp用戶【szysftp】并加入到創(chuàng)建的sftp組中,同時修改【szysftp】用戶的密碼
useradd -g sftp -s /bin/false szysftppasswd szysftp3、新建目錄,指定為【szysftp】用戶的主目錄
mkdir -p /sftp/szysftpusermod -d /sftp/szysftp szysftp4、編輯配置文件/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 no5、設置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 restart8、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服务器的搭建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UG NX 12 草图
- 下一篇: 画手机原型图工具推荐