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和Cyber​​duck还提供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. 修改配置
    在这里插入图片描述
[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. 验证
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> 

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

七、高可用方案

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

服务端配置,双向同步时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

客户端配置

客户端登录服务端密码,注意这里只写密码,和服务端的/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 

测试

启动服务端
[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. 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. 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
       }
    }
}

八、监控方案

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. 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

或在kem上直接查看
在这里插入图片描述
日志中应该是如下报错
在这里插入图片描述
解决办法,密钥文件粘贴注意格式,粘贴到kem页面上注意最后一行加回车,避免pod无法启动或正常启动后登录sftp服务器上验证失败。
另外还有一种可能是转码问题,用文本编辑工具处理一下即可。

  1. 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

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

  1. 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#
[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]#

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

  • 配置文件正确挂载,但上传镜像后没有结果文件
    在这里插入图片描述
    如上图的错误为harbor_config.conf配置项未配置正确,harbor地址错误,修改为正确的harbor地址,上传镜像成功。
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值