前言:公司业务中,需要我方搭建sftp服务器用来三方交换数据,而且其中一方是win10专线,所以还需在本地写上行与下载脚本
一.创建一个组(sftp)
groupadd sftp
(删除使用groupdel)
创建完成后使用cat /etc/group命令组的信息
二.创建一个该组下的用户(mysftp)并加入到创建的组(sftp)中,同时修改用户密码
useradd -g sftp -s /bin/false mysftp
passwd mysftp
三.新建一个目录(/data/sftp/mysftp),将其指定为该用户(mysftp)的home目录
mkdir -p /data/sftp/mysftp
usermod -d /data/sftp/mysftp mysftp
四.编辑配置文件/etc/ssh/sshd_config
vim /etc/ssh/sshd_config# Subsystem sftp /usr/libexec/openssh/sftp-server
并在文件最后面添加如下几行内容然后保存
Subsystem sftp internal-sftp Match Group sftp ChrootDirectory /data/sftp/%u ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no
五.设置chroot目录权限
chown root:sftp /data/sftp/mysftp chmod 755 /data/sftp/mysftp
六.新建一个目录供用户(mysftp)用,这个目录组别为用户组(sftp)并授权
mkdir /data/sftp/mysftp/uploadchown mysftp:sftp /data/sftp/mysftp/uploadchmod 755 /data/sftp/mysftp/upload
七.关闭selinux并重启sshd服务
setenforce 0
service sshd restart
(centos7则 systemctl restart sshd.service)
八.如果需要修改sftp端口,则修改SSH配置文件
vim /etc/ssh/ssh_config
找到#port 22,在其下面加入port 端口号,如port 3322
vim /etc/ssh/sshd_config
找到#port 22,在其下面加入port 端口号,如port 3322
之后重启sshd服务
service sshd restart
(centos7则 systemctl restart sshd.service)
九.常用的sftp相关命令
远程连接:
sftp -oPort=端口号 用户名@地址
十.脚本
下载脚本内容:
D:cd WinSCPWinSCP.exe /console /command "option batch continue" "option confirm off" "open sftp://mysftp:admin123@183.62.232.62:3322" "option transfer binary" "chmod " "get /upload/* C:\Users\Administrator\Desktop\aaa\" "rm /upload/*" "exit" /log=log_file.txt
winscp421.exe /console /command 命令名
“option batch continue” 默认批处理
“option confirm off” 关闭提示信息
“open sftp://user:pwd@ip:port” user:访问用户名 ,pwd:用户密码 ,ip:ip地址,port:端口号 默认22。 IPv6地址需要用[]框起来
“option transfer binary” 使用二进制格式传送
log=log_file.txt 日志文件地址
“exit” ::执行完命令后退出
“get 下载地址 存储目录”
“rm 删除目录”
—————————————————————-分割线—————————————————————
上行脚本内容:
D:cd WinSCPWinSCP.exe /console /command "option batch continue" "option confirm off" "open sftp://mysftp:admin123@183.62.232.62:3322" "option transfer binary" "put C:\Users\Administrator\Desktop\aaa\* /upload/" "exit" /log=log_file.txt
Forfiles /p C:\Users\Administrator\Desktop\aaa /s /m *.* /c "cmd /c del /q /f @path"
命令解释大致同上
“put 上行地址 存储目录”
/p:指定要删除的目录
/s:表示递归搜索子目录
/d:-14表示14天前的文件,-7表示7天前的文件
/m:. 表示所有文件类型,如果要删除特定文件格式,可自行指定(如:只删除txt文件,可写成 *.txt )
/c:自行指定的命令,后面双引号括起来的是删除文件命令
自行指定的命令 “cmd /c del /q /f @path” 中:
/c: 表示执行完批处理命令后,关闭CMD窗口
del: 删除文件的命令
/q:安静模式。删除全局通配符时,不要求确认
/f:强制删除只读文件。
十一.脚本运行WinSCP时的常用命令
call 执行任意远程Shell命令
cd 改变远程工作目录
chmod 改变远程文件权限
close 关闭会话
exit 关闭所有会话并结束程序
get 从远程目录下载文件到本地目录
help 显示帮助
keepuptodate 在一个远程目录连续反映本地目录的改变
lcd 改变本地工作目录
lls 列出本地目录的内容
ln 新建远程符号链接
lpwd 显示本地工作目录
ls 列出远程目录的内容
mkdir 新建远程目录
mv 移动或者重命名远程文件
open 连接到服务器
option 设置或显示脚本选项的值
put 从本地目录上传文件到远程目录
pwd 显示远程工作目录
rm 删除远程文件
rmdir 删除远程目录
session 列出连接的会话或者选择活动会话
synchronize 用一个本地目录同步远程目录
十二.java可用sftp工具类
导包
<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.54</version></dependency>
jsch里有 ChannelShell、ChannelExec、ChannelSftp,前两类用于执行,后一个用于上行下载。
package com.jrzh.common.utils;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
import java.util.Vector;import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;/*** sftp工具,提供连接sftp、上传和下载文件的方法* @author LHF*/
public class SftpUtils {/*** 连接sftp服务器* @param host 主机* @param port 端口* @param username 用户名* @param password 密码* @return*/public static ChannelSftp connect(String host, int port, String username,String password) {ChannelSftp sftp = null;try {JSch jsch = new JSch();jsch.getSession(username, host, port);Session sshSession = jsch.getSession(username, host, port);System.out.println("Session created.");sshSession.setPassword(password);Properties sshConfig = new Properties();sshConfig.put("StrictHostKeyChecking", "no");sshSession.setConfig(sshConfig);sshSession.connect();System.out.println("Session connected.");System.out.println("Opening Channel.");Channel channel = sshSession.openChannel("sftp");channel.connect();sftp = (ChannelSftp) channel;System.out.println("Connected to " + host + ".");} catch (Exception e) {}return sftp;}/*** 上传文件* @param directory 上传的目录* @param uploadFile 要上传的文件* @param sftp*/public static void upload(String directory, String uploadFile, ChannelSftp sftp) {try {sftp.cd(directory);File file=new File(uploadFile);sftp.put(new FileInputStream(file), file.getName());} catch (Exception e) {e.printStackTrace();}}/*** 上传文件夹* @param directory 目标路径* @param oldPath 本地路径* @param sftp*/public static void uploadFolder(String directory, String oldPath, ChannelSftp sftp) {try {//System.out.println(directory);String[] strArr=directory.split("/");//首文件夹路径String topDirectory="";//首文件名称String topFolderName="";if(strArr.length>2){//上一级目录for(int i=0;i<strArr.length-1;i++){topDirectory+="/"+strArr[i];}topDirectory+="/";sftp.cd(topDirectory);//创建首文件夹topFolderName=strArr[strArr.length-1];sftp.mkdir(topFolderName);sftp.cd(directory);File a=new File(oldPath); String[] file=a.list(); File temp=null; for (int i = 0; i < file.length; i++) { if(oldPath.endsWith(File.separator)){ temp=new File(oldPath+file[i]); } else{ temp=new File(oldPath+File.separator+file[i]); } if(temp.isFile()){ File uploadFiled=new File(oldPath+(temp.getName()).toString());sftp.cd(directory);//System.out.println(sftp.pwd());System.out.println("uploadFiled:"+oldPath +(temp.getName()).toString());sftp.put(new FileInputStream(uploadFiled), uploadFiled.getName());} if(temp.isDirectory()){//如果是子文件夹System.out.println("子文件循环");uploadFolder(directory+file[i]+"/",oldPath+file[i]+"/",sftp); } } }else{throw new Exception("目标路径不正确");}} catch (Exception e) {e.printStackTrace();}}/*** 下载文件* @param directory 下载目录* @param downloadFile 下载的文件* @param saveFile 存在本地的路径* @param sftp*/public static void download(String directory, String downloadFile,String saveFile, ChannelSftp sftp) {try {sftp.cd(directory);File file=new File(saveFile);sftp.get(downloadFile, new FileOutputStream(file));} catch (Exception e) {e.printStackTrace();}}public static void downloads(String downloadFile,String saveFile, ChannelSftp sftp) {try {File file=new File(saveFile);sftp.get(downloadFile, new FileOutputStream(file));} catch (Exception e) {e.printStackTrace();}}/*** 删除文件* @param directory 要删除文件所在目录* @param deleteFile 要删除的文件* @param sftp*/public static void delete(String directory, String deleteFile, ChannelSftp sftp) {try {System.out.println(directory);sftp.cd(directory);sftp.rm(deleteFile);} catch (Exception e) {e.printStackTrace();}}public static void deletes(String deleteFile, ChannelSftp sftp) {try {sftp.rm(deleteFile);} catch (Exception e) {e.printStackTrace();}}/*** 列出目录下的文件* @param directory 要列出的目录* @param sftp* @return* @throws SftpException*/public static Vector<?> listFiles(String directory, ChannelSftp sftp) throws SftpException{return sftp.ls(directory);}public static void main(String[] args) throws JSchException {ChannelSftp sftp = SftpUtils.connect("183.62.232.62", 3322, "mysftp", "admin123");SftpUtils.upload("upload", "C:\\Users\\Administrator\\Desktop/kfile.dat", sftp);//SftpUtils.download("upload", "20190808.txt", "C:\\Users\\Administrator\\Desktop\\6.27备份/20190808.txt", sftp);Session session = sftp.getSession();sftp.disconnect();if(session != null){session.disconnect();}}
}