SFTP详解

2024/11/29 SFTP

# 一、组件功能

安全文件传输协议SFTP(SSH File Transfer Protocol)是文件传输协议(FTP)的安全版本,也是SSH协议的一部分,可通过安全SHELL(SSH)数据流轻松进行数据传输和数据访问。SFTP也被称为SSH文件传输协议。它提供了一个安全的连接来传输文件,并在本地和远程系统上遍历文件系统。SFTP中的加密是通过SSH连接来完成的,文件可以通过WinSCP和SFTP客户端进行传输。

# 二、适用场景

SFTP服务使用标准的SFTP协议实现上传/下载数据,您也可以创建SFTP用户来实现精确的权限控制。在各个不同行业之间或公司不同部门之间进行数据交换时,SFTP服务器提供了一种安全、简单、高效的文件传输方式。

# 三、SFTP优势

  1. 安全:SFTP协议提供了一个安全通道,用于在网络上的主机之间传输文件。
  2. 易用:SFTP是SSH协议的一部分,它是一种远程登录信息。
  3. 权限控制:通过建立独立的ssh用户进行精准权限控制
  4. 兼容性:sftp适用于所有平台
  5. 可靠性:基于SSH来加密传输文件,可靠性高,可断点续传

# 四、SFTP原理

SFTP,代表SSH File Transfer传输Protocol协议,是类似于FTP的网络协议,它允许文件访问,传输和文件管理,但可以通过安全可靠的数据流。

与FTP不同,它不使用单独的命令和数据通道。相反,它在单个连接中以特殊格式的软件包传输文件。名称中的SSH代表Secure SHell协议,SFTP是该协议的扩展。使用SFTP协议时,这提供了更高的安全性。 您可以以与FTP相同的方式使用SFTP,最大的区别是安全连接。 Filezilla和Cyberduck还提供SFTP作为其免费软件包的一部分,您肯定会利用它。

连接到SFTP服务器时,它假定连接正在安全通道上运行。由于客户端用户身份可用于协议,因此无需客户端身份验证。

WordPress是一个很好的示例,该站点允许同时进行FTP和SFTP连接。尝试添加已保存到计算机或服务器的主题时,可能需要通过FTP或SFTP传输该主题。

这是为了避免WordPress拒绝主题在正常传输过程中可能需要的某些代码行。

# 五、SFTP与同类产品对比

最明显的区别就是定义。 SFTP是安全的网络协议,而FTP则不是。另一种可能是协议类型。 FTP是基于TCP / IP的协议。 SFTP是基于SSH的协议。

TCP / IP表示T传输C控制Protocol / I互联网P协议。换句话说,这是控制互联网上所有计算机之间通信的标准协议。

  • FTP在TCP端口21上建立其控制连接,而SFTP在客户端和服务器之间通过SSH协议建立的连接下传输文件。

  • FTP仅以纯文本格式发送数据,而SFTP在将其所有数据发送到主机之前对其进行加密。

  • SFTP还是一个独立的协议,它提供主机到主机的传输,而FTP是一个更为开放的协议。 FTP,Netscape创建了SSL,或S确保S火箭Layer(当前为TLS或Transport Layer S安全性)。然后将SSL应用于FTP以创建FTPS。

这允许通过两个安全变体使用FTP以安全的方式交换数据:FTPS隐式SSL和FTPS显式SSL。两者都使用SSL加密。

最后,大多数人唯一需要担心的唯一关键区别是SFTP提供了一种将文件从一台主机传输到另一台主机的安全方法。 FTP仅通过两个通道(命令和数据通道)提供标准的纯文本传输,而没有加密。

而vsftpd是一个软件程序,是(very secure FTP daemon)的缩写,是一款在Linux发行版中最受推崇的FTP服务器程序,特点是小巧轻快,安全易用,支持ftp协议,但是不支持sftp协议。

# 六、部署方案

# 1.裸金属部署

  1. 添加用户配置目录权限

    [root@db1 conf]# groupadd sftp #新建用户组
    [root@db1 conf]# useradd -g sftp -s /sbin/nologin -M hsi_ftp #添加用户
    [root@db1 conf]# passwd hsi_ftp #设置密码
    Changing password for user hsi_ftp.
    New password: 
    Retype new password: 
    passwd: all authentication tokens updated successfully.
    [root@db1 data]# mkdir -p /data/sftp/hsi_ftp
    [root@db1 data]# usermod -d /data/sftp/hsi_ftp hsi_ftp
    [root@db1 data]# chown root:sftp /data/sftp/ #根目录所有者必须是root否则无法登录
    [root@db1 data]# chown hsi_ftp:sftp /data/sftp/hsi_ftp/ #修改权限
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  2. 修改配置

    [root@db1 data]# vi /etc/ssh/sshd_config
    
    注释行
    #Subsystem      sftp    /usr/libexec/openssh/sftp-server
    
    末尾添加行
    Subsystem       sftp    internal-sftp
    Match Group sftp
    ChrootDirectory /data/sftp
    ForceCommand    internal-sftp
    AllowTcpForwarding no 
    X11Forwarding no
    
    重启
    [root@db1 data]# service sshd restart 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
  3. 验证

    yzb-book:~ yzb$ sftp hsi_ftp@192.168.10.15
    hsi_ftp@192.168.10.15's password: 
    Connected to hsi_ftp@192.168.10.15.
    sftp> ls
    hsi_ftp   
    sftp> cd hsi_ftp
    sftp> put /Users/yzb/Downloads/dfcf.dmg ./
    Uploading /Users/yzb/Downloads/dfcf.dmg to /hsi_ftp/./dfcf.dmg
    /Users/yzb/Downloads/dfcf.dmg                 100%   28MB  11.0MB/s   00:02    
    sftp> ls
    dfcf.dmg  
    sftp> rm dfcf.dmg
    Removing /hsi_ftp/dfcf.dmg
    sftp> ls
    sftp> 
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

# 2.k8s容器化部署

cat sftp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sftp
spec:
  replicas: 2 #可自行修改副本的个数
  selector:
    matchLabels:
      app: sftp
  template:
    metadata:
      labels:
        app: sftp
    spec:
      nodeSelector:
        sftp: "true"
      containers:
      - command: ["/entrypoint", "$(user):$(passwd):::$(path)"]
        image: atmoz/sftp:alpine-3
        name: sftp
        ports:
        - containerPort: 22
          hostPort: 32222
          name: http
          protocol: TCP
        env:
        - name: TZ
          value: "CST-8"
        - name: user
          value: "sftp"
        - name: passwd
          value: "123456"
        - name: path
          value: "upload"
        resources:
          limits:
            cpu: "1"
            memory: 200Mi
          requests:
            cpu: "0.1"
            memory: 100Mi
        securityContext:
          capabilities:
            add: # 添加
            - CAP_SYS_ADMIN
            drop:  # 删除
            - KILL 
        volumeMounts:
        - mountPath: /etc/ssh/ssh_host_ed25519_key
          name: ssh-host-ed25519-key
        - mountPath: /etc/ssh/ssh_host_rsa_key
          name: ssh-host-rsa-key
        - mountPath: "/opt/data"
          name: data
#        - mountPath: "/home/foo/"
#          name: data
#        - mountPath: "/home/bar/"
#          name: data
        - name: users
          mountPath: /etc/sftp
        - name: bindmount
          mountPath: /etc/sftp.d
      volumes:
      - hostPath:
          path: /etc/ssh/ssh_host_ed25519_key
        name: ssh-host-ed25519-key
      - hostPath:
          path: /etc/ssh/ssh_host_rsa_key
        name: ssh-host-rsa-key
      - name: data
        persistentVolumeClaim:
          claimName: pvc-nfs
      - name: users
        configMap:
          name: users-cm
      - name: bindmount
        configMap:
          name: bindmount-cm
---
apiVersion: v1
data:
  user.conf: |
    foo:123:1001:100:/home/sftp/upload
    bar:abc:1002:100:/home/sftp/upload
    baz:xyz:1003:100
kind: ConfigMap
metadata:
  name: user-cm
---
apiVersion: v1
data:
  bind-mount.sh: |
    #!/bin/bash
    # File mounted as: /etc/sftp.d/bindmount.sh
    # Just an example (make your own)

    function bindmount() {
        if [ -d "$1" ]; then
            mkdir -p "$2"
        fi
        mount --bind $3 "$1" "$2"
    }

    # Remember permissions, you may have to fix them:
    # chown -R :users /data/common

    bindmount /opt/data /home/sftp/upload
    bindmount /opt/data /home/foo/upload
    bindmount /opt/data /home/bar/upload
kind: ConfigMap
metadata:
  name: bindmount-cm

kubectl apply -f sftp.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

# 七、高可用方案

SFTP是单节点的服务,本身不支持集群模式,但可组合keepalived、rsync,共享存储,负载均衡等组件,建立起SFTP的高可用方案

  1. 部署sftp 参考部署方案-裸金属部署章节(两台服务器都需要部署)

  2. RSYNC编译安装

    安装前提:需要保持双向同步的服务器主机时间同步
    下载地址:https://download.samba.org/pub/rsync/src/rsync-3.1.3.tar.gz
    解压编译安装
    [root@db1 ~]# tar -zxvf rsync-3.1.3.tar.gz 
    [root@db1 ~]# cd rsync-3.1.3
    [root@db1 rsync-3.1.3]# ./configure --prefix=/usr/local/rsync --disable-ipv6
    [root@db1 rsync-3.1.3]# make && make install
    [root@db1 rsync-3.1.3]# ln -s /usr/local/rsync/bin/rsync /usr/local/bin/rsync
    
    简历需要同步的目录(客户端主机和服务端主机均需要建目录保持一致)
    [root@db1 rsync-3.1.3]# mkdir -p /data/sftp/hsi_ftp/upload/
    [root@db1 rsync-3.1.3]# chown -R hsi_ftp:sftp /data/sftp/hsi_ftp/
    [root@db1 rsync-3.1.3]# chmod -R 777 /data/sftp/hsi_ftp/
    [root@db1 rsync-3.1.3]# vi /etc/xinetd.d/rsync
    将disable = yes 改为 no
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    服务端配置,双向同步时2台服务器是客户端同时也都是服务端

    [root@db1 sftp]# vi /usr/local/rsync/rsyncd.conf 
    pid file = /var/run/rsyncd.pid
    port = 873
    uid = hsi_ftp#服务端系统用户
    gid = sftp#服务端系统用户组
    use chroot = yes
    max connections = 5
    timeout 600
    lock file = /var/run/rsyncd.lock
    log file = /var/run/rsyncd.log
    #secrets file = /usr/local/rsync/rsyncd.secrets 
    motd file = /etc/rsyncd.motd
     
    [hsi_sftp]#名称可以随意
    path = /data/sftp/hsi_ftp/#需要同步的目录,拥有者和用户组必须和上面的pid,gid一致
    #ignore errors
    read only = no#非只读
    write only = no#非只写
    list = yes
    hosts allow = *
    #hosts deny = 0.0.0.0/32
    secrets file = /usr/local/rsync/rsyncd.secrets
    auth users = hsi_ftp  #该用户系统中存在且对后面指定的备份目录拥有权限
    comment = sftp  hsi_sftp
    
    配置帐号密码格式:帐号:密码
    [root@db1 sftp]# vi /usr/local/rsync/rsyncd.secrets 
    hsi_ftp:hsi_ftp
    
    修改配置文件权限
    [root@db1 sftp]# chmod 600 /usr/local/rsync/rsyncd.conf 
    [root@db1 sftp]# chmod 600 /usr/local/rsync/rsyncd.secrets
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32

    客户端配置

    客户端登录服务端密码,注意这里只写密码,和服务端的/usr/local/rsync/rsyncd.secrets文件对应
    [root@db1 sftp]# vi /usr/local/rsync/rsyncd.pass 
    hsi_ftp
    
    修改密码配置文件权限,如果不修改则可能无法使用
    [root@db1 sftp]# chmod 600 /usr/local/rsync/rsyncd.pass 
    
    1
    2
    3
    4
    5
    6

    测试

    启动服务端
    [root@db1 rsync]# rsync --daemon --config=/usr/local/rsync/rsyncd.conf
    
    [root@db2 ~]# rsync -avz --password-file=/usr/local/rsync/rsyncd.pass /data/sftp/hsi_ftp/ hsi_ftp@192.168.10.15::hsi_sftp
    
    sending incremental file list
    upload/
    upload/rsyncd.conf1
    
    sent 463 bytes  received 39 bytes  334.67 bytes/sec
    total size is 492  speedup is 0.98
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
  3. INOTIFY-TOOLS安装(双向同步2台主机分别都要执行操作)

    下载
    [root@db1 upload]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
    
    解压
    [root@db1 upload]# tar -zxvf inotify-tools-3.14.tar.gz 
    [root@db1 upload]# cd inotify-tools-3.14
    [root@db1 inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify
    [root@db1 inotify-tools-3.14]# make && make install
    
    检查是否安装成功
    [root@db1 inotify-tools-3.14]# ls -alh /usr/local/inotify/bin/inotify*
    -rwxr-xr-x. 1 root root 44K Feb 28 14:38 /usr/local/inotify/bin/inotifywait
    -rwxr-xr-x. 1 root root 41K Feb 28 14:38 /usr/local/inotify/bin/inotifywatch
    
    建立软连接
    [root@db1 inotify-tools-3.14]# ln -s /usr/local/inotify/bin/inotifywait /usr/bin/inotifywait
    [root@db1 inotify-tools-3.14]# ln -s /usr/local/inotify/bin/inotifywatch /usr/bin/inotifywatch
    
    配置rsync.sh同步监控脚本
    [root@db1 inotify]# vi /usr/local/inotify/rsync.sh
    # 内容如下
    #!/bin/bash
    src=/data/sftp/hsi_ftp/ #同步目录
    des=hsi_sftp #视情况自己配置,注意与下面的rsync命令结合配置
    user=hsi_ftp
    host="192.168.10.16" #服务端主机ip
    /usr/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e modify,delete,create,attrib $src | while read file
    do
        rsync -vzrtopg --delete --progress --password-file=/usr/local/rsync/rsyncd.pass $src $user@$host::$des 
        echo "$file was rsynced" >> /tmp/rsync.log 2>&1
    done
    [root@db1 inotify]# chmod +x /usr/local/inotify/rsync.sh
    nohup sh /usr/local/inotify/rsync.sh &
    
    #建立守护进程运行rsync.sh脚本
    echo “nohup sh /usr/local/inotify/rsync.sh &>> /etc/rc.local
    
    测试:分别在2台机器/data/sftp/hsi_ftp/目录修改,新增,删除文件查看另一台服务器上是否也同步修改
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
  4. KEEPALIVED配置 安装详见 HTTP://WWW.YANGZB.COM/ARTICLE/16

    vi /usr/local/keepalived/etc/keepalived/keepalived.conf
    
    后添加内容
    virtual_server 192.168.10.160 22 {
        delay_loop 6
        lb_algo rr
        lb_kind DR
        persistence_timeout 50
        protocol TCP
    
        real_server 192.168.10.15 22 {
            weight 1
            TCP_CHECK {
                connect_timeout 3
                retry 3
                delay_before_retry 3
            }
        }
    
        real_server 192.168.10.16 22 {
            weight 1
            TCP_CHECK {
                connect_timeout 3
                retry 3
                delay_before_retry 3
           }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

# 八、监控方案

SFTP成熟的监控方案比较少,因sftp可监控项也比较少

下面以prometheus监控sftp为例,进行演示

  1. 采用https://github.com/billabongrob/sftp-exporter进行sftp指标采集

    docker run -p 9816:9816 --env SFTPHOST=127.0.0.1 --env SFTPUSER=hsi_ftp --env SFTPPASS=123456 ghcr.io/billabongrob/sftp-exporter:latest

  2. prometheus job 添加

    - job_name: 'prome'
         static_configs:
         - targets: ['localhost:9816']
           labels:
             id: sftp-instance
             instance: sftp
    
    1
    2
    3
    4
    5
    6
  3. grafana dashboard

    https://grafana.com/grafana/dashboards/15744-sftp-connectivity/

# 九、常见问题及解决方法

  1. 发布服务时文件启动pod异常排查

    Kubectl logs pod名称 –n 分区名称查看
    [root@vm-paasyy24-097 ~]# kubectl get po -n sftp-images
    NAME                          READY   STATUS    RESTARTS   AGE
    sftp-image-7d4d766b94-ftl6b   1/1     Running   0          131m
    [root@vm-paasyy24-097 ~]# kubectl logs sftp-image-7d4d766b94-ftl6b -n sftp-images
    
    1
    2
    3
    4
    5

    或在kem上直接查看

    日志中应该是如下报错

    解决办法,密钥文件粘贴注意格式,粘贴到kem页面上注意最后一行加回车,避免pod无法启动或正常启动后登录sftp服务器上验证失败。

    另外还有一种可能是转码问题,用文本编辑工具处理一下即可。

  2. Sftp登录sftp服务器报密码错误排查

    日志的结尾部分基本上是如下错误:

    Unable to load host key "/etc/ssh/ssh_host_ed25519_key": invalid format
    Unable to load host key: /etc/ssh/ssh_host_ed25519_key
    Invalid user demo1-admin from 10.248.24.101 port 18416
    Could not get shadow information for NOUSER
    
    1
    2
    3
    4

    解决办法,这个就是ldap服务验证不通过,检查下启动deplayment的ldap相关的环境变量。一定要与kem服务器上application.properties文件中ldap配置部分一致。修改后重启即可。

  3. ftp上传镜像到指定的目录上,未生成result结果文件,在镜像库中查不到

    • 配置文件未正确挂载:

      进入pod容器内或在kem上直接进入容器,查看容器内对应的配置文件,看有没有正常加载,或进入容器挂载在本地的日志的目前查看日志。
      [root@vm-paasyy24-097 ~]# kubectl exec -it sftp-image-7d4d766b94-ftl6b -n sftp-images bash
      kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
      root@sftp-image-7d4d766b94-ftl6b:/home# cd /opt/images/config
      root@sftp-image-7d4d766b94-ftl6b:/opt/images/config# ls -l
      total 0
      lrwxrwxrwx 1 root root 17 Aug  6 15:09 config.ini -> ..data/config.ini
      lrwxrwxrwx 1 root root 25 Aug  6 15:09 harbor_config.conf -> ..data/harbor_config.conf
      lrwxrwxrwx 1 root root 27 Aug  6 15:09 ssh_host_ed25519_key -> ..data/ssh_host_ed25519_key
      lrwxrwxrwx 1 root root 23 Aug  6 15:09 ssh_host_rsa_key -> ..data/ssh_host_rsa_key
      root@sftp-image-7d4d766b94-ftl6b:/opt/images/config#
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      [root@vm-paasyy24-097 ftpdata]# cd logs
      [root@vm-paasyy24-097 logs]# ls -l
      total 5760
      -rw-r--r-- 1 root root       0 Aug  6 14:59 images_error.log
      -rw-r--r-- 1 root root 4799150 Aug  6 17:50 images_info.log
      [root@vm-paasyy24-097 logs]# tail -f images_info.log
      2021-08-06 17:50:32,690 - images_share_main.py[line:210] - INFO:事件触发租户为:pass-uer001-admin,项目为:wzk
      2021-08-06 17:50:32,690 - images_share_main.py[line:210] - INFO:事件触发租户为:pass-uer001-admin,项目为:wzk
      2021-08-06 17:50:32,691 - base.py[line:144] - INFO:Job "addImagesPath (trigger: interval[0:00:05], next run at: 2021-08-06 17:50:37 CST)" executed successfully
      2021-08-06 17:50:32,702 - images_share_harbor_v2.py[line:91] - INFO:调用harbor:10.248.24.215:1121项目接口成功
      2021-08-06 17:50:32,702 - images_share_push.py[line:138] - INFO:##############镜像上传harbor开始 2021-08-06 17:50:32##############
      2021-08-06 17:50:32,702 - images_share_push.py[line:139] - INFO:获取项目列表返回值 200
      2021-08-06 17:50:32,703 - images_share_push.py[line:142] - INFO:10.248.24.215:1121 harbor获取项目列表成功
      2021-08-06 17:50:32,703 - images_share_push.py[line:149] - INFO:已存在的项目列表是 {'123': 11, 'eee': 12, 'google_containers': 6, 'kube_system': 5, 'library': 1, 'paas-admin': 4, 'paas-monitor': 3, 'test': 10, 'test1': 7, 'test2': 8}
      2021-08-06 17:50:32,703 - images_share_push.py[line:151] - INFO:10.248.24.215:1121 harbor eee 项目已存在
      2021-08-06 17:50:32,703 - images_share_push.py[line:237] - INFO:docker开始load镜像。。。。。
      ^C
      [root@vm-paasyy24-097 logs]#
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18

      如果配置文件加载不正常,重新粘贴配置文件,注意格式。重启即可

    • 配置文件正确挂载,但上传镜像后没有结果文件

      如上图的错误为harbor_config.conf配置项未配置正确,harbor地址错误,修改为正确的harbor地址,上传镜像成功。

# 十、创建用户

使用用户组的概念可以更方便地管理多个SFTP用户。以下是基于用户组的SFTP用户创建步骤:

  1. 创建用户组
# 创建一个专门用于SFTP的用户组,例如 sftpUsers:
groupadd sftpUsers
1
2
  1. 创建用户并加入用户组
# 创建一个新用户(例如 sftpuser1),并将其加入 sftpUsers 组:
useradd -m -G sftpUsers sftpuser1
1
2
  1. 设置用户密码
# 为新用户设置密码:
passwd sftpuser1
1
2
  1. 创建SFTP根目录
# 为所有SFTP用户创建一个根目录,例如 /home/sftp:
mkdir -p /home/sftp
1
2
  1. 为每个用户创建子目录
# 在 /home/sftp 下为每个用户创建独立的子目录,例如 sftpuser1:
mkdir -p /home/sftp/sftpuser1/upload
1
2
  1. 设置目录权限
# 确保根目录的权限正确,子目录允许用户上传文件:
sudo chown root:root /home/sftp
sudo chmod 755 /home/sftp
sudo chown sftpuser1:sftpUsers /home/sftp/sftpuser1/upload
1
2
3
4
  1. 配置SSH
# 编辑SSH配置文件 /etc/ssh/sshd_config,(ctrl+o,确定键==保持,ctrl+X==退出)添加以下内容以限制 sftpUsers 组用户只能使用SFTP:
nano /etc/ssh/sshd_config

# 启用SFTP子系统(可选)
Subsystem sftp internal-sftp
# 添加或修改以下内容:
Match Group sftpUsers
    ChrootDirectory /home/sftp/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no
    
# %u 表示用户名,确保每个用户被限制在自己的目录中。
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. 重启SSH服务
# 保存并关闭文件后,重启SSH服务:
systemctl restart sshd
1
2
  1. 测试SFTP连接
# 测试
sftp sftpuser1@localhost
1
2
  1. 添加更多用户
# 如果需要添加更多用户,重复以下步骤:
	# 1.创建用户并加入 sftpUsers 组:
		sudo useradd -m -G sftpUsers sftpuser2
	
	# 2.设置密码:
		sudo passwd sftpuser2

	# 3.创建用户子目录并设置权限:
		sudo mkdir -p /home/sftp/sftpuser2/upload
		sudo chown sftpuser2:sftpUsers /home/sftp/sftpuser2/upload
1
2
3
4
5
6
7
8
9
10