文章目录
- 一、组件功能
- 二、适用场景
- 三、SFTP优势
- 四、SFTP原理
- 五.SFTP与同类产品对比
- 六、部署方案
- 1.裸金属部署
- 2.k8s容器化部署
- 七、高可用方案
- 八、监控方案
- 九、常见问题及解决方法
一、组件功能
安全文件传输协议SFTP(SSH File Transfer Protocol)是文件传输协议(FTP)的安全版本,也是SSH协议的一部分,可通过安全SHELL(SSH)数据流轻松进行数据传输和数据访问。SFTP也被称为SSH文件传输协议。它提供了一个安全的连接来传输文件,并在本地和远程系统上遍历文件系统。SFTP中的加密是通过SSH连接来完成的,文件可以通过WinSCP和SFTP客户端进行传输。
二、适用场景
SFTP服务使用标准的SFTP协议实现上传/下载数据,您也可以创建SFTP用户来实现精确的权限控制。在各个不同行业之间或公司不同部门之间进行数据交换时,SFTP服务器提供了一种安全、简单、高效的文件传输方式。
三、SFTP优势
- 安全:SFTP协议提供了一个安全通道,用于在网络上的主机之间传输文件。
- 易用:SFTP是SSH协议的一部分,它是一种远程登录信息。
- 权限控制:通过建立独立的ssh用户进行精准权限控制
- 兼容性:sftp适用于所有平台
- 可靠性:基于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.裸金属部署
- 添加用户配置目录权限
[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/ #修改权限
- 修改配置
[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
- 验证
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: sftptemplate:metadata:labels:app: sftpspec:nodeSelector:sftp: "true"containers:- command: ["/entrypoint", "$(user):$(passwd):::$(path)"]image: atmoz/sftp:alpine-3name: sftpports:- containerPort: 22hostPort: 32222name: httpprotocol: TCPenv:- name: TZvalue: "CST-8"- name: uservalue: "sftp"- name: passwdvalue: "123456"- name: pathvalue: "upload"resources:limits:cpu: "1"memory: 200Mirequests:cpu: "0.1"memory: 100MisecurityContext:capabilities:add: # 添加- CAP_SYS_ADMINdrop: # 删除- KILL volumeMounts:- mountPath: /etc/ssh/ssh_host_ed25519_keyname: ssh-host-ed25519-key- mountPath: /etc/ssh/ssh_host_rsa_keyname: ssh-host-rsa-key- mountPath: "/opt/data"name: data
# - mountPath: "/home/foo/"
# name: data
# - mountPath: "/home/bar/"
# name: data- name: usersmountPath: /etc/sftp- name: bindmountmountPath: /etc/sftp.dvolumes:- hostPath:path: /etc/ssh/ssh_host_ed25519_keyname: ssh-host-ed25519-key- hostPath:path: /etc/ssh/ssh_host_rsa_keyname: ssh-host-rsa-key- name: datapersistentVolumeClaim:claimName: pvc-nfs- name: usersconfigMap:name: users-cm- name: bindmountconfigMap:name: bindmount-cm
---
apiVersion: v1
data:user.conf: |foo:123:1001:100:/home/sftp/uploadbar:abc:1002:100:/home/sftp/uploadbaz: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" ]; thenmkdir -p "$2"fimount --bind $3 "$1" "$2"}# Remember permissions, you may have to fix them:# chown -R :users /data/commonbindmount /opt/data /home/sftp/uploadbindmount /opt/data /home/foo/uploadbindmount /opt/data /home/bar/upload
kind: ConfigMap
metadata:name: bindmount-cmkubectl apply -f sftp.yaml
七、高可用方案
SFTP是单节点的服务,本身不支持集群模式,但可组合keepalived、rsync,共享存储,负载均衡等组件,建立起SFTP的高可用方案
- 部署sftp
参考部署方案-裸金属部署章节(两台服务器都需要部署) - 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_sftpsending incremental file list
upload/
upload/rsyncd.conf1sent 463 bytes received 39 bytes 334.67 bytes/sec
total size is 492 speedup is 0.98
- 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
dorsync -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/目录修改,新增,删除文件查看另一台服务器上是否也同步修改
- KEEPALIVED配置 安装详见 HTTP://WWW.YANGZB.COM/ARTICLE/16
vi /usr/local/keepalived/etc/keepalived/keepalived.conf后添加内容
virtual_server 192.168.10.160 22 {delay_loop 6lb_algo rrlb_kind DRpersistence_timeout 50protocol TCPreal_server 192.168.10.15 22 {weight 1TCP_CHECK {connect_timeout 3retry 3delay_before_retry 3}}real_server 192.168.10.16 22 {weight 1TCP_CHECK {connect_timeout 3retry 3delay_before_retry 3}}
}
八、监控方案
SFTP成熟的监控方案比较少,因sftp可监控项也比较少
下面以prometheus监控sftp为例,进行演示
-
采用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 -
prometheus job 添加
- job_name: 'prome'static_configs:- targets: ['localhost:9816']labels:id: sftp-instanceinstance: sftp
- grafana dashboard
https://grafana.com/grafana/dashboards/15744-sftp-connectivity/
九、常见问题及解决方法
- 发布服务时文件启动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服务器上验证失败。
另外还有一种可能是转码问题,用文本编辑工具处理一下即可。
- 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配置部分一致。修改后重启即可。
- 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地址,上传镜像成功。