当前位置: 首页 > news >正文

Linux中创建SFTP账号

Linux中创建SFTP账号

文章目录

  • Linux中创建SFTP账号
    • 一:背景
    • 二:步骤
      • 1、创建一个sftp用户
      • 2、创建根目录
      • 3、创建用户sjzx_sftp_user目录,这里设置目录名为upload
      • 4、修改配置文件,记得先备份
      • 5、重启sshd服务
      • 6、测试连接
        • 最终效果
      • 7、修改连接port
      • 8、如何删除新增的用户
        • 1. 删除用户
        • 2. 检查配置文件
        • 3. 清理用户的文件
        • 4. 验证是否删除成功
      • 9、如何操作sftp命令
        • 1.查看下载的路径
        • 2.修改下载路径
        • 3.下载文件
        • 4.批量下载
        • 5.下载整个目录
        • 6.查询文件
    • 三:Java代码
    • 四:参考

一:背景

客户需要到我服务器上存取文件,单独给他创建sftp账号。

二:步骤

1、创建一个sftp用户

1.名称zxyh_sftp_user,并修改密码useradd -s /sbin/nologin -M zxyh_sftp_user
passwd zxyh_sftp_user输入密码:mima

2、创建根目录

mkdir /home/zxyh
#需要设置该目录的权限,确保该目录及该目录以上的系统根目录的拥有者都只能是root用户
chown root:root /home/zxyh
#其次要确保该跟目录往上的根目录都不可以具有群组写入权限
chmod 755 /home/zxyh

3、创建用户sjzx_sftp_user目录,这里设置目录名为upload

mkdir /home/zxyh/upload
#同时给该用户赋予sjzx_sftp_user该sftp用户的目录权限:
chown root:zxyh_sftp_user /home/zxyh/upload
#这里的目录sftp的权限也只能是755,否则无法限制目录
chmod 755 /home/zxyh/upload
#最后在upload目录创建一个temp工作目录给sjzx_sftp_user用户用来各种操作
mkdir /home/zxyh/upload/temp
#因为要让用户读写操作,所以权限给777
chmod 777 /home/zxyh/upload/temp

4、修改配置文件,记得先备份

备份:cp -r sshd_config /etc/ssh/sshd_config_bak编辑:vim /etc/ssh/sshd_config

配置内容详细说下:

注释掉这行:#Subsystem sftp /usr/libexec/openssh/sftp-server
image-20250827135254130

然后添加下面的内容:

Subsystem sftp internal-sftp
Match User zxyh_sftp_user                #匹配用户,如果要匹配多个组,多个组之间用逗号分隔
ChrootDirectory /home/zxyh/upload        #用chroot将指定用户的根目录
ForceCommand internal-sftp               #指定sftp命令
X11Forwarding no                         #这两行,如果不希望该用户能使用端口转发的话就加上,否则删掉
AllowTcpForwarding no

image-20250827135518126

验证配置文件准确: sshd -t

5、重启sshd服务

systemctl restart sshd.service
service sshd restart(选其中之一执行)

如果出现了异常报错:Directive ‘UseDNS’ is not allowed within a Match block

image-20250827135623719

解决方法:将后面新增的配置放在最后面

6、测试连接

sftp -oPort=22 username@IP输入服务器ip,以本地举例
1.sftp -oPort=22 zxyh_sftp_user@127.0.0.1
最终效果
1.连接sftp后进入/home/zxyh/upload,不能访问upload以上目录
2.进入咱们给定的/home/zxyh/upload/temp的工作目录,在temp目录内该用户可随意操作

7、修改连接port

image-20250827135200387

1.vim /etc/ssh/sshd_config
2.取消注释的port
3.设置为你想要的端口
4.wq保存
5.重启sshd服务:service sshd restart
6.重新连接:sftp -oPort=8869 zxyh_sftp_user@127.0.0.1说明:修改默认ssh端口号会导致root账号22端口号失效,root账户也用指定的端口号登录即可

8、如何删除新增的用户

删除一个 SFTP 用户主要分为两部分:

  1. 从系统中删除用户账户
  2. 清理该用户的相关目录和数据

以下是具体步骤:


1. 删除用户

使用以下命令删除用户:

sudo userdel -r zxyh_sftp_user
  • 参数说明:

    • userdel:删除用户的命令。
    • -r:同时删除该用户的主目录和邮件文件(如果存在)。
  • 效果:

    • 该命令会从系统中彻底删除用户 zxyh_sftp_user

    • 用户的主目录(如 /home/zxyh/upload/zxyh_sftp_user)也会被删除。

    • 如果希望保留用户的文件,而仅删除用户账户,请省略

      -r
      

      参数:

      bashsudo userdel zxyh_sftp_user
      
2. 检查配置文件

如果在 /etc/ssh/sshd_config 文件中配置了针对该用户的特殊规则(通过 Match User 指令),应当清理对应的配置。例如:

    plaintextMatch User zxyh_sftp_userChrootDirectory /home/zxyh/uploadForceCommand internal-sftpX11Forwarding noAllowTcpForwarding no

删除这部分配置后,记得验证配置并重新加载 SSH 服务:

sshd -t
sudo systemctl restart sshd

3. 清理用户的文件

如果删除用户时没有使用 -r 参数,需要手动删除用户的数据目录,例如:

bashsudo rm -rf /home/zxyh/upload/zxyh_sftp_user
  • 注意: 如果用户的数据目录位于其他位置(例如 /var/sftp/),应确保一并清理。

4. 验证是否删除成功

检查是否还有该用户的信息存在:

bashgetent passwd zxyh_sftp_user
  • 如果没有任何输出,说明用户已经被完全删除。

9、如何操作sftp命令

1.查看下载的路径
lpwd
2.修改下载路径
lcd /tmp
3.下载文件
get a.txt
4.批量下载
get *.txt
5.下载整个目录
get -r /home
6.查询文件
find ~ -name a.txt

三:Java代码

package com.kehua.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.Vector;import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;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工具类* @date 2018年12月11日* @author 杨贤宾* @version 1.0*/
public class SFTPUtil {private transient Logger log = LoggerFactory.getLogger(this.getClass());  private ChannelSftp sftp;  private Session session;  /** SFTP 登录用户名*/    private String username; /** SFTP 登录密码*/    private String password;  /** 私钥 */    private String privateKey;  /** SFTP 服务器地址IP地址*/    private String host;  /** SFTP 端口*/  private int port;  /**  * 构造基于密码认证的sftp对象  */    public SFTPUtil(String username, String password, String host, int port) {  this.username = username;  this.password = password;  this.host = host;  this.port = port;  } /**  * 构造基于秘钥认证的sftp对象 */  public SFTPUtil(String username, String host, int port, String privateKey) {  this.username = username;  this.host = host;  this.port = port;  this.privateKey = privateKey;  }  public SFTPUtil(){}  /** * 连接sftp服务器 */  public void login(){  try {  JSch jsch = new JSch();  if (privateKey != null) {  jsch.addIdentity(privateKey);// 设置私钥  }  session = jsch.getSession(username, host, port);  if (password != null) {  session.setPassword(password);    }  Properties config = new Properties();  config.put("StrictHostKeyChecking", "no");  session.setConfig(config);  session.connect();  Channel channel = session.openChannel("sftp");  channel.connect();  sftp = (ChannelSftp) channel;  } catch (JSchException e) {  e.printStackTrace();}  }    /** * 关闭连接 server  */  public void logout(){  if (sftp != null) {  if (sftp.isConnected()) {  sftp.disconnect();  }  }  if (session != null) {  if (session.isConnected()) {  session.disconnect();  }  }  }  /**  * 将输入流的数据上传到sftp作为文件。文件完整路径=basePath+directory* @param basePath  服务器的基础路径 * @param directory  上传到该目录  * @param sftpFileName  sftp端文件名  * @param in   输入流  */  public void upload(String basePath,String directory, String sftpFileName, InputStream input) throws SftpException{  try {   sftp.cd(basePath);sftp.cd(directory);  } catch (SftpException e) { //目录不存在,则创建文件夹String [] dirs=directory.split("/");String tempPath=basePath;for(String dir:dirs){if(null== dir || "".equals(dir)) continue;tempPath+="/"+dir;try{ sftp.cd(tempPath);}catch(SftpException ex){sftp.mkdir(tempPath);sftp.cd(tempPath);}}}  sftp.put(input, sftpFileName);  //上传文件} /** * 下载文件。* @param directory 下载目录  * @param downloadFile 下载的文件 * @param saveFile 存在本地的路径 */    public void download(String directory, String downloadFile, String saveFile) throws SftpException, FileNotFoundException{  if (directory != null && !"".equals(directory)) {  sftp.cd(directory);  }  File file = new File(saveFile);  sftp.get(downloadFile, new FileOutputStream(file));  }  /**  * 下载文件 * @param directory 下载目录 * @param downloadFile 下载的文件名 * @return 字节数组 */  public byte[] download(String directory, String downloadFile) throws SftpException, IOException{  if (directory != null && !"".equals(directory)) {  sftp.cd(directory);  }  InputStream is = sftp.get(downloadFile);  byte[] fileData = IOUtils.toByteArray(is);  return fileData;  }  /** * 删除文件 * @param directory 要删除文件所在目录 * @param deleteFile 要删除的文件 */  public void delete(String directory, String deleteFile) throws SftpException{  sftp.cd(directory);  sftp.rm(deleteFile);  }  /** * 列出目录下的文件 * @param directory 要列出的目录 * @param sftp */  public Vector<?> listFiles(String directory) throws SftpException {  return sftp.ls(directory);  }  public static void main(String[] args) throws SftpException, IOException {  SFTPUtil sftp = new SFTPUtil("userftp", "khyf3@123", "112.74.59.0", 10001);  sftp.login();  //上传文件测试/*File file = new File("E:\\谷歌下载资源\\linux 安装 mysql.html");  InputStream is = new FileInputStream(file);  sftp.upload("/upload","code", "linux 安装 mysql.html", is);  sftp.logout();  *///下载文件测试sftp.download("/upload/code", "CODE_0000000000000020.png" ,"D:\\2.PNG");sftp.logout();}  
}

四:参考

SFTP服务器的搭建与使用

创建sftp用户并分配操作目录权限

搭建sftp,使用户只能访问特定的目录

http://www.dtcms.com/a/353896.html

相关文章:

  • Netty:现代网络应用的利器
  • 软件定义汽车(SDV)调试——如何做到 适配软件定义汽车(SDV)?(中)
  • 造作AI-你的人工智能创作助手
  • 某中医院信息化能力提升:智能组网设备助力网络架构优化
  • 【日常学习】2025-8-27 测开框架设计模式探索04
  • Element整体操作样式
  • 数据分析编程第五步:数据准备与整理
  • DDD之事件机制(9)
  • 沃丰科技出海客服系统对接沃尔玛全球电商平台,赋能中企出海
  • 升级DrRacket8.10到8.18版本@Ubuntu24.04
  • GitLab 导入/导出仓库
  • 金融 IT 运维痛点突围:用网络管理工具筑牢业务稳定防线(附 OpManager Plus 实践)
  • 【51单片机按键按下数码管秒增计时并LED亮释放停计时LED熄】2022-11-12
  • Android -第二十一次技术总结
  • 使用LLAMA_cpp_python进行qwen2.5-vl-7b-instruct进行推理
  • 【URP】Unity Shader Tags
  • IT66122替代IT66121-富利威
  • Day12 Gin框架学习
  • .NET周刊【8月第3期 2025-08-17】
  • 【C#】获取不重复的编码(递增,非GUID)
  • (LeetCode 面试经典 150 题) 102. 二叉树的层序遍历(广度优先搜索bfs)
  • Miniforge3替代Anaconda的一些经验总结
  • STL库——vector(类模拟实现)
  • 旧物二手回收小程序系统:让闲置旧物焕发新生,创造无限价值
  • Leetcode 深度优先搜索 (14)
  • 胶水研究记录学习1
  • 回顾websocket心跳机制以及断线重连(服务端为node)
  • 数据结构——抽象数据类型(ADT)
  • 浏览器渲染帧管线全景拆解:从像素到屏幕的 16.67 ms 之旅
  • Linux内核bitmap组件详解