借鉴以下文章:
sftp的用法:ChannelSftp类_zhougl996的博客-CSDN博客_channelsftp
JSch - Java实现的SFTP(文件上传详解篇) - longyg - 博客园 (cnblogs.com)
linux环境快速搭建sftp服务以及设置免密 - 渐逝的星光 - 博客园 (cnblogs.com)
SFTP创建目录和判断目录是否存在_@小顽皮的博客-CSDN博客_sftp判断目录是否存在
一、部署sftp服务
1、创建sftp组 :
groupadd app
2、创建一个用户,用户名为appadmin :
useradd -g app -s /bin/false appadmin
3、修改密码:
passwd appadmin
4、app组的用户的home目录统一指定到/appadmin下:
mkdir -p /app/appadmin
5、指定appadmin的home为/app/appadmin:
usermod -d /app/appadmin appadmin
6、配置sshd_config:
vi /etc/ssh/sshd_config
6.1、输入/Subsystem搜索到下列内容,然后注释:
# Subsystem app /usr/libexec/openssh/sftp-server
6.2、在文件结尾处添加下面后保存:
Subsystem app internal-sftp Match Group app ChrootDirectory /app/%u ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no
7、设定Chroot目录权限:
chown root:sftp /app/appadmin chmod 755 /app/appadmin
8、建立SFTP用户登入后可写入的目录:
mkdir/app/appadmin/upload
chown sftp_upload:sftp /sftp/sftp_upload/upload
chmod 755 /app/appadmin/upload
9、输入命令:
setenforce 0
10、重启sshd服务:
service sshd restart
11、ifcong查询ip,进行登录:
sftp [email protected]
若需要指定端口
sftp -oPort=22 [email protected]
二、配置ssh免密登录
(本质是将需要登录的服务器的公钥数据加载到需要免密登录的服务器的authorized_keys文件中。【实际是配置ssh免密】)
1.生成公钥私钥
在需要连接sftp的服务器上执行 ssh-keygen -t rsa,称为当前服务器(注意选择好使用用户)
回车两次生成rsa公私钥文件,可打开/home/用户/.ssh/文件夹查看,id_rsa.pub为公钥,id_rsa为私钥,复制id_rsa.pub内容准备。
ssh-keygen -t rsa
2.公钥追加进目标服务器的authorized_keys文件中,三种方式
1)直接手动追加:
在部署sftp服务器上,称为目标服务器,选择将要进行免密连接的用户,打开/home/用户/.ssh/文件夹,新建一个名为authorized_keys的文件,将复制过来的id_rsa.pub中的内容增加到authorized_keys文件中。(如没有则新建文件即可,注意将authorized_keys权限设置为600,.ssh文件夹设置为700)
2)公钥文件拷贝到目标服务器追加:可以使用命令scp /root/.ssh/id_isa.pub [email protected]:/root;
scp /root/.ssh/id_isa.pub [email protected]:/root
登录到目标服务器,进入该用户下的.ssh目录cd ~/.ssh,并公钥导入到authorized_keys信任列表,cat id_isa.pub >> /root/.ssh/authorized_keys
cat id_isa.pub >> /root/.ssh/authorized_keys
更新权限:chmod 600 authorized_keys,自此SSH免密登录配置完成。
3)直接命令连接目标服务器追加:直接使用ssh-copy-id命令去复制公钥自动写入到authorized_keys文件中,这样就不需要接下来的手动复制公钥操作了
ssh-copy-id -i /root/.ssh/id_isa.pub [email protected]
最后就可以sftp [email protected],或者ssh [email protected]
此处注意,需要更改.ssh和authorized_keys的owner,因为sftp_upload只支持sftp协议,所以需要在root账户下创建.ssh和authorized_keys后,执行一下命令:
chown -R sftp_upload:sftp /sftp/sftp_upload/.ssh(这个没有用到,作为记录)
三、代码使用sftp携带私钥登录传输文件
public class SFTPConstants { public static final String SFTP_REQ_HOST = "host"; public static final String SFTP_REQ_PORT = "port"; public static final String SFTP_REQ_USERNAME = "username"; public static final String SFTP_REQ_PASSWORD = "password"; public static final int SFTP_DEFAULT_PORT = 22; public static final String SFTP_REQ_LOC = "location"; public static final String SFTP_PRVKEY_PATH = "prvKey"; public static final String SFTP_PRVKEY_VALUE = "/home/appadmin/.ssh/id_rsa"; } public class SFTPChannel { Session session = null; Channel channel = null; private static final Logger LOG = Logger.getLogger(SFTPChannel.class.getName()); public ChannelSftp getChannel(Map<String, String> sftpDetails, int timeout) throws JSchException { String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST); String port = sftpDetails.get(SFTPConstants.SFTP_REQ_PORT); String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME); String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD); String prvKey = sftpDetails.get(SFTPConstants.SFTP_PRVKEY_PATH); int ftpPort = SFTPConstants.SFTP_DEFAULT_PORT; if (port != null && !port.equals("")) { ftpPort = Integer.valueOf(port); } JSch jsch = new JSch(); // 创建JSch对象
//根据是否使用免密登录,决定是否携带私钥 if(null != prvKey){ jsch.addIdentify(SFTPConatants.SFTP_PRVKEY_VALUE) } session = jsch.getSession(ftpUserName, ftpHost, ftpPort); // 根据用户名,主机ip,端口获取一个Session对象 LOG.debug("Session created."); if (ftpPassword != null) { session.setPassword(ftpPassword); // 设置密码 } Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); // 为Session对象设置properties session.setTimeout(timeout); // 设置timeout时间 session.connect(); // 通过Session建立链接 LOG.debug("Session connected."); LOG.debug("Opening Channel."); channel = session.openChannel("sftp"); // 打开SFTP通道 channel.connect(); // 建立SFTP通道的连接 LOG.debug("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName + ", returning: " + channel); return (ChannelSftp) channel; } public void closeChannel() throws Exception { if (channel != null) { channel.disconnect(); } if (session != null) { session.disconnect(); } } public void makeDir(String path, ChannelSftp sftp){ try{ if(isDirExist(path, sftp){ sftp.cd(path); return; } String[] pathArray = path.split("/"); StringBuffer filePath = new StringBuffer("/"); for(String p : pathArray){ if(StringUtils.isBlank(p)){ continue; } filePath.append(p+"/"); if(isDirExist(filepath)){ sftp.cd(filePath.toString()); }else{ sftp.mkdir(filePath.toString()); sftp.cd(filePath.toString()); } } sftp.cd(path); }catch(Exception e){ e.printStackTrace(); } } public void isDirExist(String path, ChannelSftp sftp){ boolean isDirExist = false; try{ sftpATTRS sftpATTRS = sftp.lstat(path); isDirExist = true; return sftpATTRS.isDir(); }catch(Exception e){ if(e.getMessage().toLowerCase().equals("no such file"){ isDirExist = false; } } return isDirExist; } public void upload(String srcPath, String dstPath, ChannelSftp sftp){ if(!this.isDirExist(dstPath, sftp)){ this.mkdir(dstPath, sftp); } try{ sftp.put(srcPath, dstPath); sftp.quit(); this.closeChannel(); }catch(Exception e){ e.printStackTrace(); } } }
标签:String,sftp,传输,ssh,appadmin,linux,服务器,SFTP,public From: https://www.cnblogs.com/weice-blog/p/16835788.html