环境:
CentOS 7,OpenSSH_7.4p1
摘要说明:
本篇主要讲述如何进行配置SFTP服务;如何设置多用户及用户目录权限控制;如何控制ssh连接;
步骤:
1.同时配置ssh及Sftp(默认sftp-server)
一般的root用户是同时使用ssh和sftp连接,此时使用的是默认的sftp-server服务;即/usr/libexec/openssh/sftp-server;
a.创建用户组及用户
#创建用户组
groupadd ssh-test
#创建文件夹
mkdir /home/ssh-test
#创建用户
useradd -g ssh-test -d /home/ssh-test/ssh-user1 ssh-user1
#修改密码:
passwd ssh-user1
#进行目录权限设置
chown -R ssh-user1:ssh-test /home/ssh-test/ssh-user1/
chmod 755 /home/ssh-test/ssh-user1/
此时即可进行sftp连接,连接测试如下:
sftp ssh-user1@localhost
此时不能进行ssh连接,若想进行ssh连接需进行下需操作:
b.进行ssh设置
切换到要设置的用户
#切换到用户:su 用户名
su ssh-user1
添加ssh-key:
#使用ssh-keygen -t rsa进行ssh设置,后续一直enter;结束后可使用ls -a查看
bash-4.2$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ssh-test/ssh-user1/.ssh/id_rsa):
Created directory '/home/ssh-test/ssh-user1/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/ssh-test/ssh-user1/.ssh/id_rsa.
Your public key has been saved in /home/ssh-test/ssh-user1/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Z9PKFIqe7WjG2rV6tKhyWnTtNVw5ydZ0bdAXCGUkKfc ssh-user1@iZbp1dham6enej0lrs00riZ
The key's randomart image is:
+---[RSA 2048]----+
| o=++++|
| . +o* .=|
| + O ...|
| o o = E |
| . o S O . |
| . o +.* + |
| ..oo+.o |
| ....=+o. |
| .+o=+oo |
+----[SHA256]-----+
bash-4.2$ ls -a
测试查看是否可以ssh连接:
ssh ssh-user1@localhost
2.配置sftp(internal-sftp服务)
通用的只配置sftp往往使用的是internal-sftp服务;
同样的第一步也是创建用户组及用户:
a.创建用户组及用户
#创建用户组
groupadd sftp-test
#创建文件夹
mkdir /home/sftp-test
#添加用户,并制定不可进行ssh连接
useradd -g sftp-test -s /sbin/nologin -d /home/sftp-test/sftp-user1 sftp-user1
#授权
chown -R sftp-user1:sftp-test /home/sftp-test/sftp-user1/
chmod 755 /home/sftp-test/sftp-user1/
若想创建多用户,只需要在用户组下再创建一个用户即可:
#添加用户,并制定不可进行ssh连接
useradd -g sftp-test -s /sbin/nologin -d /home/sftp-test/sftp-user2 sftp-user2
#授权
chown -R sftp-user2:sftp-test /home/sftp-test/sftp-user2/
chmod 755 /home/sftp-test/sftp-user2/
b.配置sshd_config
使用vi编辑/etc/ssh/sshd_config:
#注释此行
#Subsystem sftp /usr/libexec/openssh/sftp-server
#指定internal-sftp服务
Subsystem sftp internal-sftp
#配置sftp
#下面两行如果不希望该用户能使用端口转发的话就加上,否则删掉
X11Forwarding no
AllowTcpForwarding no
#此处是强制使用sftp连接,开了之后root用户也不可进行ssh连接
#ForceCommand internal-sftp
#指定用户组,也可使用Match User指定用户
Match Group sftp-test
#指定sftp根目录
ChrootDirectory /home/sftp-test
保存后重新启动服务:
systemctl restart sshd
测试连接:
sftp sftp-user1@localhost
3.修改端口号
使用vi编辑/etc/ssh/sshd_config修改端口号:
#将下面这行放开,修改成想要的端口
#Port 22
保存后重启服务:
systemctl restart sshd
指定端口连接测试:
sftp -oPort=指定端口 sftp-user1@localhost
ssh -oPort=指定端口 ssh-user1@localhost
4.java操作sftp
操作sftp工具类如下:
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.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import pers.cc.taf.log.TAFLog;
/**
* SFTP工具类
*
*/
public class SFTPUtil {
/**
* 连接sftp服务器
*
* @param host
* 主机
* @param port
* 端口
* @param username
* 用户名
* @param password
* 密码
* @return
*/
public 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);
TAFLog.info("Session created.");
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
TAFLog.info("Session connected.");
TAFLog.info("Opening Channel.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
TAFLog.info("Connected to " + host + ".");
} catch (Exception e) {
TAFLog.error("sftp链接异常", e);
}
return sftp;
}
/**
* 上传文件
*
* @param directory
* 上传的目录
* @param uploadFile
* 要上传的文件
* @param sftp
*/
public void upload(String directory, String uploadFile, ChannelSftp sftp)
throws Exception {
FileInputStream in = null;
try {
makeDirs(directory, sftp);
sftp.cd(directory);
File file = new File(uploadFile);
in = new FileInputStream(file);
sftp.put(in, file.getName());
TAFLog.info("上传文件路径[" + directory + "/" + file.getName() + "]");
} catch (Exception e) {
throw e;
} finally {
if (in != null) {
in.close();
}
}
}
/**
* 下载文件
*
* @param directory
* 下载目录
* @param downloadFile
* 下载的文件
* @param saveFile
* 存在本地的路径
* @param sftp
*/
public void download(String directory, String downloadFile,
String saveFile, ChannelSftp sftp) throws Exception {
FileOutputStream out = null;
try {
sftp.cd(directory);
File file = new File(saveFile);
out = new FileOutputStream(file);
sftp.get(downloadFile, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
/**
* 删除文件
*
* @param directory
* 要删除文件所在目录
* @param deleteFile
* 要删除的文件
* @param sftp
*/
public void delete(String directory, String deleteFile, ChannelSftp sftp) {
try {
sftp.cd(directory);
sftp.rm(deleteFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* 创建文件夹
*
* @param
* @return
*/
public void makeDirs(String directory, ChannelSftp sftp)
throws SftpException {
String[] dirs = directory.split("/");
if (dirs.length > 1) {
int i = 0;
String temp = "/" + dirs[i];
boolean end = false;
while (!end) {
try {
sftp.ls(temp);
} catch (Exception e) {
sftp.mkdir(temp);
}
i++;
if (i >= dirs.length) {
end = true;
} else {
temp += "/" + dirs[i];
}
}
}
}
/**
* 列出目录下的文件
*
* @param directory
* 要列出的目录
* @param sftp
* @return
* @throws SftpException
*/
@SuppressWarnings("unchecked")
public Vector<LsEntry> listFiles(String directory, ChannelSftp sftp)
throws SftpException {
return sftp.ls(directory);
}
public void disconnect(ChannelSftp sftp) {
if (sftp != null) {
try {
sftp.getSession().disconnect();
} catch (JSchException e) {
TAFLog.error("断开SFTP连接异常", e);
}
}
}
}