使用阿里云产品搭建高可用sftp服务器(ECS主机、SLB负载均衡器、NAS存储)使用的是阿里云的vpc网络环境

服务器架构简图如下:

云服务器nat 云服务器nas搭建_开发工具

A、购买阿里云的NAS存储包,并配置。

1、购买存储包

2、设置NAS存储的访问权限组,新建权限组(授权地址填写两台ECS主机的ip地址)

云服务器nat 云服务器nas搭建_xml_02


3、添加权限组规则

云服务器nat 云服务器nas搭建_xml_03

4、创建文件系统 (协议类型-NFS 绑定存储包)

云服务器nat 云服务器nas搭建_云服务器nat_04


5、创建完文件系统以后 管理文件系统 创建挂载地址以及选择创建的权限组

云服务器nat 云服务器nas搭建_php_05


由于我这边VPC中两台ECS主机在不同的可用区A、B,所以这个VPC在A、B两个可用区都创建了交换机,所以这边可以看到两个文件系统的挂载点 即A、B区的挂载点

云服务器nat 云服务器nas搭建_开发工具_06

B、在VPC网络中购买两台ECS主机分别在A、B可用区并配置

1、登录centos系统安装相关软件,由于ECS主机挂载NAS文件需要安装nfs协议
yum install nfs-utils -y

格式
sudo mount -t nfs -o vers=4.0 <挂载点域名>:<文件系统内目录> <当前服务器上待挂载目标目录\>
2、linux系统挂载NAS存储并在NAS存储上创建目录(由于直接挂载NAS根据的权限是1777 所以先挂载NAS根目录再在NAS根目录中创建目录sftpdir,针对sftpdir目录设置权限)

mount -t nfs -o vers=4.0 443d948306-ieh68.cn-shanghai-finance-1.nas.aliyuncs.com:/  /alidata1
mkdir -p /alidata1/sftp
chmod 755 /alidata1/sftp 
chown root.root /alidata1/sftp
umount  /alidata1

注意:
由于sftp的目录的权限设定有两个要点:

目录开始一直往上到系统根目录为止的目录拥有者都只能是root
目录开始一直往上到系统根目录为止都不可以具有群组写入权限

3、设置开机自启动挂载NAS文件系统
分别登录172.31.93.38、172.31.142.157服务器执行以下命令(两台服务器的NAS挂载地址不一样)
echo 'mount -t nfs -o vers=4.0 443d948306-ieh68.cn-shanghai-finance-1.nas.aliyuncs.com:/sftp /alidata1' >> /etc/rc.d/rc.local

chmod +x /etc/rc.d/rc.local

centos7 系统/etc/rc.d/rc.local没有可执行权限,需要额外赋予

mkdir -pv /alidata1/sftpdir #创建sftp用户的家目录

4、在服务器172.31.93.38配置sftp服务

vim /etc/ssh/sshd_config

\找到如下行,并注释

#Subsystem sftp /usr/libexec/openssh/sftp-server

\修改认证配置

PasswordAuthentication no  修改为yes

在最后添加以下几行

###########sftp###############
Subsystem       sftp    internal-sftp   #这行指定使用sftp服务使用系统自带的internal-sftp   
Match Group sftpusers                    #这行用来匹配用户组
ChrootDirectory /alidata1/sftpdir          #用chroot将用户的根目录指定到 /alidata1/sftpdir,这样用户就只能在 /alidata1/sftpdir下活动
ForceCommand    internal-sftp        #指定sftp命令

5、重启sftp服务

systemctl restart sshd.service

6、在172.31.93.38创建sftp测试用户组以及用户

groupadd -g 500 sftpusers
useradd -G sftpusers -M  -s /sbin/nologin -u 501  admin   #创建sftp用户并不创建家目录
echo  'Admin123' | passwd --stdin admin
mkdir -pv  /alidata1/sftpdir/admin admin     #创建用户家目录
usermod -d  /alidata1/sftpdir/admin admin  #修改用户家目录

chown admin.sftpusers /alidata1/sftpdir/admin   修改家目录权限

7、测试sftp用户登录

sftp  admin@127.0.0.1

两台服务器需要同步的文件如下

1、两台ECS必须创建指定GID的用户组
2、两台ECS也必须创建指定的UID用户
因为NAS存储的权限是根据系统用户的GID以及UID,所以两个系统必须创建相同UID以及GID的用户
注需要使用sersync2软件同步两台ECS主机的用户名文件passwd、passwd- 和用户组文件 group、group- 以及用户的密码 shadown、shadown-文件

客户端连接的时候会因为known_hosts 文件冲突,连接失败。
客户端解决方法:
有以下两个解决方案:

  1. 手动删除修改known_hsots里面的内容;

修改ssh的客户端配置文件 vim /etc/ssh/ssh_config
StrictHostKeyChecking no
因为需要和第三方对接,无法让第三方的生产服务器做ssh客户端的配置要求,所以采用服务端解决方法。
服务端解决方式:
需要同步两台ECS主机下/etc/ssh/下配置文件

C、配置同步服务(以172.31.93.38为准同步文件到172.31.142.157)
1、在172.31.93.38服务器上安装sersync2,下载之后直接解压放到/usr/local/sersync目录之下,sersync目录下有两个文件 confxml.xml 为配置文件 sersync2为服务文件

2、在172.31.142.157服务器上安装rsync服务并修改配置文件/etc/rsyncd.conf

```# /etc/rsyncd: configuration file for rsync daemon mode

#See rsyncd.conf man page for more options.
#configuration example:
#uid = nobody
#gid = nobody
use chroot = yes
max connections = 40
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
*hosts allow = 172.31.93.38*  #允许哪个服务器同步过来
hosts deny = *
#exclude = lost+found/
#transfer logging = yes
#timeout = 900
#ignore nonreadable = yes
#dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

#[ftp]
#path = /home/ftp
#comment = ftp export are
################# 同步etc中配置文件 #######################
*[etc-ssh]    #同步任务名
path = /etc/ssh/ #需要同步到本地的目录
comment = Synchronous directory /etc/ssh/
ignore errors
read only = no
write only = yes*

[etc]    #同步任务名
path = /etc/ #需要同步到本地的目录
comment = Synchronous directory /etc/ssh/
ignore errors
read only = no
write only = yes*
3、重启rsyncd服务  
   systemctl restart rsyncd

4、在172.31.93.38服务器上修改serysnc配置文件
 echo ‘Abcd123’ > /etc/rsync.pas  #创建同步用户的密码文件
 5、修改/usr/local/sersync的配置文件 如下: etc_ssh_confxml.xml
` <?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>
    <debug start="false"/>
    <fileSystem xfs="false"/>
    <filter start="false">
    <exclude expression="(.*)\.svn"></exclude>
    <exclude expression="(.*)\.gz"></exclude>
    <exclude expression="^info/*"></exclude>
    <exclude expression="^static/*"></exclude>
    </filter>
    <inotify>
    <delete start="true"/>
    <createFolder start="true"/>
    <createFile start="false"/>
    <closeWrite start="true"/>
    <moveFrom start="true"/>
    <moveTo start="true"/>
    <attrib start="false"/>
    <modify start="false"/>
    </inotify>

    <sersync>
    <localpath watch="/etc/ssh/"> #同步的目录  
        <remote ip="172.31.142.157" name="etc_ssh"/>  #定义在同步对方的任务名
        <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    </localpath>
    <rsync>
        <commonParams params="-artuz --bwlimit=100"/>
        <auth start="true" users="root" passwordfile="/etc/rsync.pas"/>  #指定同步的用户和密码
        <userDefinedPort start="false" port="874"/><!-- port=874 -->
        <timeout start="false" time="100"/><!-- timeout=100 -->
        <ssh start="false"/>
    </rsync>
    <failLog path="/usr/local/sersync/script/cron_rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
    <crontab start="false" schedule="600"><!--600mins-->
        <crontabfilter start="false">
        <exclude expression="*.php"></exclude>
        <exclude expression="info/*"></exclude>
        </crontabfilter>
    </crontab>
    <plugin start="false" name="command"/>
    </sersync>

    <plugin name="command">
    <param prefix="/bin/sh" suffix="" ignoreError="true"/>  <!--prefix /opt/tongbu/mmm.sh suffix-->
    <filter start="false">
        <include expression="(.*)\.php"/>
        <include expression="(.*)\.sh"/>
    </filter>
    </plugin>

    <plugin name="socket">
    <localpath watch="/opt/tongbu">
        <deshost ip="192.168.138.20" port="8009"/>
    </localpath>
    </plugin>
    <plugin name="refreshCDN">
    <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
        <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
        <sendurl base="http://pic.xoyo.com/cms"/>
        <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
    </localpath>
    </plugin>
</head>`

创建etc_confxml.xml配置文件
`<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>
    <debug start="false"/>
    <fileSystem xfs="false"/>
    <filter start="true">
    <exclude expression="((?!\bpasswd\b|\bpasswd-\b|\bshadow\b|\bshadow-\b|\bgroup\b|\bgroup-\b).)+"></exclude> #指定同步的文件
<!--    <exclude expression="(.*)\.svn"></exclude>
    <exclude expression="(.*)\.gz"></exclude>
    <exclude expression="^info/*"></exclude>
    <exclude expression="^static/*"></exclude>
    <exclude expression="^[a-yA-Y]*"></exclude> -->
    </filter>
    <inotify>
    <delete start="true"/>
    <createFolder start="true"/>
    <createFile start="true"/>
    <closeWrite start="true"/>
    <moveFrom start="true"/>
    <moveTo start="true"/>
    <attrib start="true"/>
    <modify start="true"/>
    </inotify>

    <sersync>
    <localpath watch="/etc">
        <remote ip="172.31.142.157" name="etc"/>
        <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    </localpath>
    <rsync>
        <commonParams params="-atuz --bwlimit=100"/>
        <auth start="true" users="root" passwordfile="/etc/rsync.pas"/>
        <userDefinedPort start="false" port="874"/><!-- port=874 -->
        <timeout start="false" time="100"/><!-- timeout=100 -->
        <ssh start="false"/>
    </rsync>
    <failLog path="/usr/local/sersync/script/etc_rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
    <crontab start="true" schedule="600"><!--600mins-->
        <crontabfilter start="false">
        <exclude expression="*.php"></exclude>
        <exclude expression="info/*"></exclude>
        </crontabfilter>
    </crontab>
    <plugin start="false" name="command"/>
    </sersync>

    <plugin name="command">
    <param prefix="/bin/sh" suffix="" ignoreError="true"/>  <!--prefix /opt/tongbu/mmm.sh suffix-->
    <filter start="false">
        <include expression="(.*)\.php"/>
        <include expression="(.*)\.sh"/>
    </filter>
    </plugin>

    <plugin name="socket">
    <localpath watch="/opt/tongbu">
        <deshost ip="192.168.138.20" port="8009"/>
    </localpath>
    </plugin>
    <plugin name="refreshCDN">
    <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
        <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
        <sendurl base="http://pic.xoyo.com/cms"/>
        <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
    </localpath>
    </plugin>
</head>`

6、编写启动sersync2脚本start.sh  如下

/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/conf/etc_ssh_confxml.xml
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/conf/etc_confxml.xml

7、编写sersync2服务监控脚本 check_sersync.sh

#!/bin/bash
cat /usr/local/sersync/start.sh|grep -v "^#" | grep -v grep | while read line;do
ps -ef | grep "$line"| grep -v grep
if [ $? -ne 0 ];then
$line
fi
done

8、设置定时检查脚本执行
    */5 *  *   *  *  /bin/bash /usr/local/sersync/check_sersync.sh

9、测试同步是否正常

10、测试sftp用户是否轮询登录到两台ECS


转载于:https://blog.51cto.com/gavin0/2069858