Centos下SFTP双机高可用环境部署记录

时间:2022-04-23
本文章向大家介绍Centos下SFTP双机高可用环境部署记录,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

SFTP(SSH File Transfer Protocol),安全文件传送协议。有时也被称作 Secure File Transfer Protocol 或 SFTP。它和SCP的区别是它允许用户中断传输, SCP拷贝速度稍快一些。SFTP可以为传输文件提供一种安全的加密方法。 SFTP与FTP有着几乎一样的语法和功能。SFTP 为 SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。其实在SSH软件包中,已经包含了一个叫作SFTP的 安全文件传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接操作,所以从某种意义上来说,SFTP并不 像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用 了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP。

下面说下SFTP+Keepalived双机高可用方案部署记录:
sftp-test01  172.16.51.191
sftp-test02  172.16.51.192
VIP          172.16.51.193

一、sftp-test01服务器操作:
1)查看openssh的版本
使用ssh -V 命令来查看openssh的版本,版本必须大于4.8p1,低于的这个版本需要升级。
[root@sftp-test01 ~]# ssh -V   
OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013

2)创建sftp组
[root@sftp-test01 ~]# groupadd sftp 

3)创建一个sftp用户,用户名为mysftp,密码为mysftp
修改用户密码和修改Linux用户密码是一样的。
[root@sftp-test01 ~]# useradd -g sftp -s /bin/false mysftp
[root@sftp-test01 ~]# passwd mysftp

4)sftp组的用户的home目录统一指定到/data/sftp下,按用户名区分,这里先新建一个mysftp目录,然后指定mysftp的home为/data/sftp/mysftp
[root@sftp-test01 ~]# mkdir -p /data/sftp/mysftp  
[root@sftp-test01 ~]# usermod -d /data/sftp/mysftp mysftp 

5)配置sshd_config
修改或添加下面配置
[root@sftp-test01 ~]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak2
[root@sftp-test01 ~]# vim /etc/ssh/sshd_config
......
#Subsystem  sftp  /usr/libexec/openssh/sftp-server
Subsystem       sftp    internal-sftp
Match Group sftp
ChrootDirectory /data/sftp/%u
ForceCommand    internal-sftp
AllowTcpForwarding no 
X11Forwarding no

设定Chroot目录权限
[root@sftp-test01 ~]# chown root:sftp /data/sftp/mysftp 
[root@sftp-test01 ~]# chmod 755 /data/sftp/mysftp

6)建立SFTP用户登入后可写入的目录
按照上面设置后,在重启sshd服务后,用户mysftp已经可以登录。但使用chroot指定根目录后,根应该是无法写入的,所以要新建一个目录供mysftp上传文件。
这个目录所有者为mysftp,所有组为sftp,所有者有写入权限,而所有组无写入权限。
[root@sftp-test01 ~]# mkdir /data/sftp/mysftp/upload  
[root@sftp-test01 ~]# chown mysftp:sftp /data/sftp/mysftp/upload  
[root@sftp-test01 ~]# chmod 755 /data/sftp/mysftp/upload  

7)关闭防火墙
[root@sftp-test01 ~]# /etc/init.d/iptables stop
[root@sftp-test01 ~]# setenforce 0
setenforce: SELinux is disabled
[root@sftp-test01 ~]# cat /etc/sysconfig/selinux 
.......
SELINUX=disabled

8)重启sshd服务
[root@sftp-test01 ~]# service sshd restart  
Stopping sshd:                                             [  OK  ]
Starting sshd:                                             [  OK  ]

9)验证sftp环境
如下显示,这说明SFTP已经搭建成功
[root@sftp-test01 ~]# sftp mysftp@172.16.51.191
Connecting to 172.16.51.191...
The authenticity of host '172.16.51.191 (172.16.51.191)' can't be established.
RSA key fingerprint is c0:f5:1d:03:3b:00:4a:11:54:8c:a7:a3:6f:77:47:c7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.51.191' (RSA) to the list of known hosts.
mysftp@172.16.51.191's password: 
sftp> ls
upload  
sftp> cd upload
sftp> ls

10)使用FileZilla FTP Client连接SFTP服务器
输入主机IP地址172.16.51.191、用户名mysftp、密码mysftp、端口(默认为22端口)连接SFTP服务器。
连接后,默认的路径是/data/sftp/mysftp

二、sftp-test02服务器需要和上面sftp-test01一样的操作!

三、sftp-test01和sftp-test02两台机器的/data/sftp目录做实时同步(rsync+inotify)
考虑到数据完整性和安全性,实施单向实时同步,即从sftp-test01机器的/data/sftp实时同步到sftp-test02的data/sftp
操作如下:
1)在目标服务器sftp-test02上的部署过程
安装配置rsync服务端
[root@sftp-test02 ~]# yum install rsync xinetd
[root@sftp-test02 ~]# vim /etc/xinetd.d/rsync 
......
   disable  = no
......

启动xineted服务
[root@sftp-test02 ~]#  /etc/init.d/xinetd start
Starting xinetd:                                           [  OK  ]

创建/etc/rsyncd.conf文件
[root@sftp-test02 ~]# vim /etc/rsyncd.conf
[root@sftp-test02 ~]# cat /etc/rsyncd.conf
log file = /var/log/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
secrets file = /etc/rsync.pass
motd file = /etc/rsyncd.Motd

[sftp_upload]
path = /data/sftp
comment = sftp_upload
uid = root
gid = sftp
port=873
use chroot = no
read only = no
list = no
max connections = 200
timeout = 600
auth users = RSYNC_USER
hosts allow = 172.16.51.191

注意:权限不要搞错了!
上面填写的uid是root,gid是sftp,是因为/data/sftp/
[root@sftp-test02 ~]# ll -d /data/sftp
drwxr-xr-x 3 root root 4096 Nov 21 05:21 /data/sftp
[root@sftp-test02 ~]# ll /data/sftp/
total 4
drwxr-xr-x 3 root sftp 4096 Nov 21 07:28 mysftp

创建用户认证文件
[root@sftp-test02 ~]# vim /etc/rsync.pass 
RSYNC_USER:123456@rsync

设置文件权限,即rsyncd.conf和rsync.pass认证文件都是600权限!
[root@sftp-test02 ~]# chmod 600 /etc/rsyncd.conf
[root@sftp-test02 ~]# chmod 600 /etc/rsync.pass

重启rsync服务
[root@sftp-test02 ~]# /etc/init.d/xinetd restart
Stopping xinetd:                                           [  OK  ]
Starting xinetd:                                           [  OK  ]
[root@sftp-test02 ~]# lsof -i:873
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xinetd  3797 root    5u  IPv6  16264      0t0  TCP *:rsync (LISTEN)

2)在源服务器172.16.51.191上的部署过程
[root@sftp-test01 ~]# yum install rsync xinetd
[root@sftp-test01 ~]# vim /etc/xinetd.d/rsync
......
   disable  = no
......
[root@sftp-test01 ~]# /etc/init.d/xinetd start 
Starting xinetd:                                           [  OK  ]
[root@sftp-test01 ~]# lsof -i:873
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
xinetd  3444 root    5u  IPv6  15917      0t0  TCP *:rsync (LISTEN)

创建同步的密码文件,这个文件名可以跟服务端的认证文件不一样,但是里面的密码必须一致!用于rsync同步命令中。
不过,最好两边的文件设置成一样,便于管理
[root@sftp-test01 ~]# cat /etc/rsync.pass
123456@rsync

设置rsync.pass密码文件为600权限
[root@sftp-test01 ~]# chmod 600 /etc/rsync.pass

查看服务器内核是否支持inotify,出现下面的内容,说明服务器内核支持inotify
[root@sftp-test01 ~]# ll /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 Nov 21 08:12 max_queued_events
-rw-r--r-- 1 root root 0 Nov 21 08:12 max_user_instances
-rw-r--r-- 1 root root 0 Nov 21 08:12 max_user_watches

注意:Linux下支持inotify的内核最小为2.6.13,可以输入命令:uname -a查看内核
CentOS 5.X 内核为2.6.18,默认已经支持inotify
[root@sftp-test01 ~]# uname -a
Linux sftp-test01 2.6.32-696.13.2.el6.x86_64 #1 SMP Thu Oct 5 21:22:16 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

下面开始安装inotify-tools
[root@sftp-test01 ~]# yum install make gcc gcc-c++
[root@sftp-test01 ~]# cd /usr/local/src/
[root@sftp-test01 src]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
[root@sftp-test01 src]# tar zxvf inotify-tools-3.14.tar.gz
[root@sftp-test01 src]# cd inotify-tools-3.14
[root@sftp-test01 inotify-tools-3.14]#  ./configure --prefix=/usr/local/inotify
[root@sftp-test01 inotify-tools-3.14]# make && make install

发现已经成功安装inotify-tools了
[root@sftp-test01 inotify-tools-3.14]# ll -d /usr/local/inotify/
drwxr-xr-x 6 root root 4096 Nov 21 08:14 /usr/local/inotify/

设置系统环境变量
[root@sftp-test01 inotify-tools-3.14]# vim /etc/profile
.......
export PATH=$PATH:/usr/local/inotify/bin
[root@sftp-test01 inotify-tools-3.14]# source /etc/profile

添加库文件
[root@sftp-test01 inotify-tools-3.14]# vim /etc/ld.so.conf
......
/usr/local/inotify/lib
[root@sftp-test01 inotify-tools-3.14]# ldconfig 

修改inotify默认参数(inotify默认内核参数值太小)
查看系统默认参数值
[root@sftp-test01 inotify-tools-3.14]# sysctl -a | grep max_queued_events
fs.inotify.max_queued_events = 16384
[root@sftp-test01 inotify-tools-3.14]# sysctl -a | grep max_user_watches
fs.inotify.max_user_watches = 8192
fs.epoll.max_user_watches = 796344
[root@sftp-test01 inotify-tools-3.14]# sysctl -a | grep max_user_instances
fs.inotify.max_user_instances = 128

[root@sftp-test01 inotify-tools-3.14]# sysctl -w fs.inotify.max_queued_events="99999999"
fs.inotify.max_queued_events = 99999999
[root@sftp-test01 inotify-tools-3.14]# sysctl -w fs.inotify.max_user_watches="99999999"
fs.inotify.max_user_watches = 99999999
[root@sftp-test01 inotify-tools-3.14]# sysctl -w fs.inotify.max_user_instances="65535"
fs.inotify.max_user_instances = 65535

参数说明:
max_queued_events:
inotify队列最大长度,如果值太小,会出现"** Event Queue Overflow **"错误,导致监控文件不准确
max_user_watches:
要同步的文件包含多少目录,可以用:find /Data/xqsj_upload -type d | wc -l 统计这些源目录下的目录数,必须保证max_user_watches值大于统计结果(这里/Data/xqsj_upload为同步的源文件目录)
max_user_instances:
每个用户创建inotify实例最大值

接着执行同步操作:
在源服务器上执行rsync首次全量同步的操作(加--delete参数,保持目标目录和源目录下文件绝对一致)
[root@sftp-test01 ~]# rsync -avH --port=873 --progress --delete /data/sftp/ RSYNC_USER@172.16.51.192::sftp_upload --password-file=/etc/rsync.pass

待第一次rsync全量同步完成后,就进行rsync+inotify实时同步脚本操作。
实时同步脚本里添加的是--delete-before参数,而不是--delete参数(第一次全量同步时rsync用的参数),二者区别:
--delete参数:表示rsync同步前,暴力删除目标目录中的所有文件,然后再执行同步操作。
--delete-before参数:表示rsync同步前,会先对目标目录进行一次扫描检索,删除目标目录中对比源目录的多余文件,然后再执行同步操作。显然比--delete参数安全些。

[root@sftp-test01 data]# cd /data/script/
[root@sftp-test01 script]# vim sftp_data_rsync.sh
#!/bin/bash
SRCDIR=/data/sftp/
USER=RSYNC_USER
IP=172.16.51.192
DESTDIR=sftp_upload
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file
do
/usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass
echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1
done

[root@sftp-test01 script]# chmod 755 sftp_data_rsync.sh
[root@sftp-test01 script]# nohup sh sftp_data_rsync.sh &          //按ctrl+c结束
[1] 8807
[root@sftp-test01 script]# ps -ef|grep inotify
root      8808  8807  0 22:55 pts/0    00:00:00 /usr/local/inotify/bin/inotifywait -mrq --timefmt %d/%m/%y %H:%M --format %T %w%f%e -e close_write,modify,delete,create,attrib,move /data/sftp/
root      8811  8451  0 22:55 pts/0    00:00:00 grep inotify

这样,sftp-test01机器的/data/sftp目录下的文件就会自动实时同步到sftp-test02机器的/data/sftp目录下
注意:这是单向实时同步!如果要想做双向实时同步!那就需要在sftp-test02机器上再做个inotify监控脚本(同时,sftp-test01也要做个rsyncd.conf文件)


四、SFTP结合Keepalived做双机高可用
1)下载安装Keepalived(两台机器同样操作)
[root@sftp-test01 ~]# cd /usr/local/src/
[root@sftp-test01 src]# wget http://www.keepalived.org/software/keepalived-1.3.2.tar.gz
[root@sftp-test01 src]# tar -zvxf keepalived-1.3.2.tar.gz 
[root@sftp-test01 src]# cd keepalived-1.3.2
[root@sftp-test01 keepalived-1.3.2]# ./configure && make && make install
[root@sftp-test01 keepalived-1.3.2]# cp /usr/local/src/keepalived-1.3.2/keepalived/etc/init.d/keepalived /etc/rc.d/init.d/
[root@sftp-test01 keepalived-1.3.2]# cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
[root@sftp-test01 keepalived-1.3.2]# mkdir /etc/keepalived
[root@sftp-test01 keepalived-1.3.2]# cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
[root@sftp-test01 keepalived-1.3.2]# cp /usr/local/sbin/keepalived /usr/sbin/
[root@sftp-test01 keepalived-1.3.2]# echo "/etc/init.d/keepalived start" >> /etc/rc.local

2)配置Keepalived.conf文件
[root@sftp-test01 keepalived-1.3.2]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
[root@sftp-test01 keepalived-1.3.2]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
  
global_defs {
notification_email {
wangshibo@wangshibo.com
}
  
notification_email_from notice@wangshibo.com
smtp_server smtp.wangshibo.com
smtp_connect_timeout 30
router_id master-node
}
  
vrrp_script chk_sftp_port { 
    script "/data/chk_sftp.sh"  
    interval 2                 
    weight -5             
    fall 2               
    rise 1   
}
  
vrrp_instance VI_1 {  
    state MASTER 
    interface eth0
    mcast_src_ip 172.16.51.191
    virtual_router_id 51  
    priority 101        
    advert_int 1             
    authentication {         
        auth_type PASS         
        auth_pass 1111        
    }
    virtual_ipaddress {          
        172.16.51.193
    }
 
track_script {                      
   chk_sftp_port      
}
}


sftp-test02服务器作为backup端的Keepalived.conf配置如下:
[root@sftp-test02 keepalived-1.3.2]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
[root@sftp-test02 keepalived-1.3.2]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
  
global_defs {
notification_email {
wangshibo@wangshibo.com
}
  
notification_email_from notice@wangshibo.com
smtp_server smtp.wangshibo.com
smtp_connect_timeout 30
router_id master-node
}
  
vrrp_script chk_sftp_port { 
    script "/data/chk_sftp.sh"  
    interval 2                 
    weight -5             
    fall 2               
    rise 1   
}
  
vrrp_instance VI_1 {  
    state BACKUP
    interface eth0
    mcast_src_ip 172.16.51.192
    virtual_router_id 51  
    priority 99        
    advert_int 1             
    authentication {         
        auth_type PASS         
        auth_pass 1111        
    }
    virtual_ipaddress {          
        172.16.51.193
    }
 
track_script {                      
   chk_sftp_port      
}
}

编写sftp监控脚本(两台机器都要写)
[root@sftp-test01 keepalived-1.3.2]# vim /data/chk_sftp.sh
#!/bin/bash
counter=$(/etc/init.d/sshd status|grep running|wc -l)
if [ "${counter}" = "0" ]; then
    /etc/init.d/sshd start
    sleep 2
    counter=$(/etc/init.d/sshd status|grep running|wc -l)
    if [ "${counter}" = "0" ]; then
        /etc/init.d/keepalived stop
    fi
fi
[root@sftp-test01 keepalived-1.3.2]# chmod 755 /data/chk_sftp.sh

3)两台机器都要启动Keepalived
[root@sftp-test01 ~]# /etc/init.d/keepalived start
[root@sftp-test02 ~]# /etc/init.d/keepalived start

启动后发现sftp-test01已经有了vip资源
[root@sftp-test01 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 02:f6:cb:83:ad:03 brd ff:ff:ff:ff:ff:ff
    inet 172.16.51.191/24 brd 172.16.51.255 scope global eth0
    inet 172.16.51.193/32 scope global eth0
    inet6 fe80::f6:cbff:fe83:ad03/64 scope link 
       valid_lft forever preferred_lft forever


4)高可用测试:
-> 先关闭sftp-test01机器的Keepalived服务,发现vip资源就会自动漂到sftp-test02机器上继续提供服务。
   当sftp-test01机器的Keepalived服务恢复后,vip资源就会自动抢占回来。
-> 关闭sftp-test01机器的ssh服务,通过脚本会自动启动ssh服务,当启动失败后,会强制关闭Keepalived服务,从而实现vip资源的漂移!

注意:
在FileZilla客户端里使用172.16.51.193的vip进行连接。可以在FileZilla客户端的"文件"里建立"新站点",协议”SFTP
登陆类型:正常

===================================================================== 发现上面双向实时同步的高可用方案实施后,文件上传到ftp目录下的状态有点问题,有的文件上传后大小变化严重以至文件损坏,无法打开! 后面将双向实时同步策略关闭,往单个机器上传文件就没问题,判断是rsync+inotify双向实时同步造成的。

调整后的新方案:
编写一个监控vip资源的脚本,当vip在哪台机器上时,就做这台机器到另一台的rsync单向同步操作,并且后台一直运行这个脚本(通过循环语句保证脚本一直运行)
放弃原来的rsync+inotify双向实时同步脚本!

脚本内容如下:
停止之前的rsync+inotify实时监控脚本,然后做两台机器的相互信任关系。

1)第一台机器sftp-test01的操作
[root@sign-test01 ~]# cat /data/script/sftp_vip_monit.sh
#!/bin/bash
while [ "1" = "1" ]
do
  NUM=`ip addr|grep 172.16.51.193|wc -l`
  if [ $NUM -eq 0 ];then
     echo "vip is not at this server" >/dev/null 2>&1
  fi

  if [ $NUM -eq 1 ];then
     /usr/bin/rsync -e "ssh -p22" -avpgolr --progress --delete-before /data/sftp/mysftp/ root@172.16.51.192:/data/sftp/mysftp/
  fi

done


[root@sign-test01 ~]# chmod 755 /data/script/sftp_vip_monit.sh
[root@sign-test01 ~]# nohup sh /data/script/sftp_vip_monit.sh &      //按ctrl+c结束
[root@sign-test01 ~]# ps -ef|grep monit
root     10581 22167  0 19:42 pts/0    00:00:00 grep monit
root     15113     1  8 17:15 ?        00:13:00 sh sftp_vip_monit.sh

2)第二台机器sftp-test02
[root@sign-test02 ~]# cat /data/script/sftp_vip_monit.sh 
#!/bin/bash
while [ "1" = "1" ]
do
  NUM=`ip addr|grep 172.16.51.193|wc -l`
  if [ $NUM -eq 0 ];then
     echo "vip is not at this server" >/dev/null 2>&1
  fi

  if [ $NUM -eq 1 ];then
     /usr/bin/rsync -e "ssh -p22" -avpgolr --progress --delete-before /data/sftp/mysftp/ root@172.16.51.191:/data/sftp/mysftp/
  fi

done

[root@sign-test02 ~]# chmod 755 /data/script/sftp_vip_monit.sh
[root@sign-test02 ~]# nohup sh /data/script/sftp_vip_monit.sh &      //按ctrl+c结束
[root@sign-test02 ~]# ps -ef|grep monit
root     10581 22167  0 19:42 pts/0    00:00:00 grep monit
root     15113     1  8 17:15 ?        00:13:00 sh sftp_vip_monit.sh