基于 Python + Proftpd 实现文件自动备份

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于 Python + Proftpd 实现文件自动备份相关的知识,希望对你有一定的参考价值。

一、环境概述

1.概述

作用:将项目服务器的重要需备份文件自动定期备份至公司内部的服务器

架构:FTP 服务器部署于内网服务器,为被动模式,通过防火墙映射21端口和通信端口,使外网的机器可以访问。客户端为Linux或Windows服务器,通过python脚本(版本为python 2)将本地需要备份的文件定时打包上传至 FTP 服务器

2.服务器配置说明

角色 操作系统 IP 地址 备注
备份客户端 centos 6/7、Windows 192.168.101-103
FTP 服务器 centos 7.4 192.168.1.9 使用 ftp 软件为 proftpd

二、proftpd 服务器部署

1.EPEL 安装

[[email protected] ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm

2.proftpd 与 OpenSSL 安装

[[email protected] ~]# yum install -y proftpd openssl proftpd-utils

3.启动proftpd服务

[[email protected] ~]# systemctl start proftpd.service
[[email protected] ~]# systemctl enable proftpd.service

4.防火墙设置

[[email protected] ~]# firewall-cmd --permanent --zone=public --add-service=ftp
[[email protected] ~]# firewall-cmd --reload

5.ftp用户创建

[[email protected] ~]# groupadd ftpgroup
## 设置 /ftpshare 目录为 proftpd 用户的家目录
[[email protected] ~]# useradd -G ftpgroup proftpd -s /sbin/nologin -d /ftpshare
[[email protected] ~]# passwd proftpd

6.proftpd 服务器配置

[[email protected] ~]# cp /etc/proftpd.conf /etc/proftpd.conf.bak
[[email protected] ~]# vi /etc/proftpd.conf
## 设置被动模式端口为 6000-6100
PassivePorts 6000 6100
## 设置被动模式返回地址为映射的公网地址
MasqueradeAddress xxx.xxx.xxx.xxx
## 设置超时时间为 600
TimeoutIdle 600

7.防火墙开放通信端口

[[email protected] ~]# firewall-cmd --permanent --zone=public --add-port=6000-6100/tcp
[[email protected] ~]# firewall-cmd --reload

8.重启服务

[[email protected] ~]# systemctl restart proftpd.service

三、客户端配置

1.Linux 服务器配置

1.1 创建ftp备份脚本
[[email protected] ~]# cat /opt/backup_to_ftp_for_linux.py 

#!/usr/bin/python
# _*_ coding: utf-8 _*_
# CREATE DATE:2018/10/27
# AUTHOR: Liuzy
# 脚本作用:
## 1.将ftp提供下载的文件下载至本地
## 2.将本地需要备份的文件打包上传至ftp服务器的备份目录下

import shutil, os, datetime, zipfile, sys,  socket
from ftplib import FTP

# 定义当前时间格式
time = datetime.datetime.now()
ytime = time + datetime.timedelta(days=-1)
nowtime = datetime.datetime.now().strftime("%Y%m%d")
yestime = ytime.strftime("%Y%m%d")
# 运行脚本的服务器地址
localhost = ‘xxx.xxx.xxx.xxx‘
# 服务器需要备份的文件列表
backupfiledir = ["/dbbackup/evedayback/",
                 "/dbbackup/eveweekback/"]
backupfiledirname = [yestime+"_table", yestime+"_database"]
# 备份所需信息,包括ftp服务器地址、端口、备份ftp用户名、密码
backupinfo = ["xxx.xxx.xxx.xxx", 21, "proftpd", "Password123"]
# 定义备份文件存放文件夹的名称格式
backupdirname = localhost + ‘_‘ + yestime + ‘_‘ + "backupfile"

class ftpserver:
    def __init__(self, host, port, username, password, localpath):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.localpath = localpath

    def connect(self):
        ftp = FTP()
        ftp.connect(self.host, self.port)
        ftp.login(self.username, self.password)
        return ftp

    def backupfile(self):
        bufsize = 1024
        # 尝试创建备份文件存放文件夹
        try:
            os.mkdir(backupdirname)
        except Exception as e:
            print("目录 %s 已存在" % backupdirname)
        # 拷贝备份文件所在文件夹至指定文件夹
        bcd = os.getcwd()+os.sep+backupdirname+"/"+yestime+"/"
        try:
            shutil.copytree(backupfiledir[0]+backupfiledirname[0], bcd+backupfiledirname[0])
        except OSError:
            print("目录不存在")
        try:
            shutil.copytree(backupfiledir[1]+backupfiledirname[1], bcd+backupfiledirname[1])
        except OSError:
            print("目录不存在")
        print("拷贝文件夹 %s 至目录 %s" % (backupfiledirname, backupdirname))
        # 压缩备份文件夹
        filelist = []
        backupzipname = backupdirname+‘.tar‘
        if os.path.isfile(backupdirname):
            filelist.append(backupdirname)
        else:
            for root,dirs,files in os.walk(backupdirname):
                for name in files:
                    filelist.append(os.path.join(root,name))
        zf = zipfile.ZipFile(backupzipname,"w",zipfile.ZIP_DEFLATED,allowZip64=True)
        for tar in filelist:
            arcname = tar[len(backupdirname):]
            zf.write(tar,arcname)
        zf.close()
        # 连接ftp服务器,备份文件
        ftp = ftpserver.connect(self)
        try:
            ftp.mkd(localhost)
        except Exception as e:
            print("目录 %s 已存在" % localhost)
        fp = open(backupzipname, ‘rb‘)
        print("开始备份文件 %s ... " % backupzipname)
        ftp.storbinary(‘STOR ‘ + localhost + ‘/‘ +  backupzipname, fp, bufsize)
        ftp.set_debuglevel(0)
        fp.close()
        print("成功备份文件 %s 至服务端 %s" % (backupzipname, localhost + ‘/‘ + backupzipname))
        ftp.quit()
        # 删除存放备份文件的临时文件夹与压缩包
        try:
            os.unlink(backupzipname)
            shutil.rmtree(backupdirname)

        except Exception as e:
            print(e)

backup = ftpserver(backupinfo[0], backupinfo[1], backupinfo[2], backupinfo[3], "")
backup.backupfile()
1.2 创建启动 python脚本的 shell 脚本
[[email protected] ~]# cat /opt/backup_ftp.sh
#!/bin/bash
## set backup python scripts path
PY_HOME=/opt/

cd $PY_HOME
nohup ./backup_to_ftp_for_linux.py >/dev/null 2>&1 &
1.3 根据实际需求将脚本加入定时任务
[[email protected] ~]# crontab -e
0 2 * * * /opt/backup_ftp.sh

2.windows 客户端配置

2.1 编写备份 python 脚本
#!/usr/bin/env python
# _*_ coding: utf-8 _*_
# CREATE DATE:2018/10/27
# AUTHOR: Liuzy
# 脚本作用:
## 1.将ftp提供下载的文件下载至本地
## 2.将本地需要备份的文件打包上传至ftp服务器的备份目录下

import shutil, os, datetime, zipfile, sys, socket
from ftplib import FTP

# 定义当前时间
time = datetime.datetime.now()
ytime = time + datetime.timedelta(days=-1)
nowtime = datetime.datetime.now().strftime("%Y%m%d")
yestime = ytime.strftime("%Y%m%d")
# 运行脚本的服务器地址
localhost = socket.gethostbyname(socket.gethostname())
# 服务器需要备份的文件列表
backupfiledir = ["D:/dbbackup/evedayback/",
                 "D:/dbbackup/eveweekback/"]
backupfiledirname = [yestime+"_table", yestime+"_database"]
# 备份所需信息,包括ftp服务器地址、端口、备份ftp用户名、密码
backupinfo = ["xxx.xxx.xxx.xxx", 21, "proftpd", "Password123"]
# 定义备份文件存放文件夹的名称格式
backupdirname = localhost + ‘_‘ + yestime + ‘_‘ + "backupfile"

class ftpserver:
    def __init__(self, host, port, username, password, localpath):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.localpath = localpath

    def connect(self):
        ftp = FTP()
        ftp.connect(self.host, self.port)
        ftp.login(self.username, self.password)
        return ftp

    def backupfile(self):
        bufsize = 1024

        # 尝试创建备份文件存放文件夹
        try:
            os.mkdir(backupdirname)
        except Exception as e:
            print("目录 %s 已存在" % backupdirname)

        # 拷贝备份文件所在文件夹至指定文件夹
        bcd = os.getcwd()+os.sep+backupdirname+"/"+yestime+"/"
        try:
            shutil.copytree(backupfiledir[0]+backupfiledirname[0], bcd+backupfiledirname[0])
        except IOError:
            print("目录不存在")
        except WindowsError:
            print("目录不存在")
        try:
            shutil.copytree(backupfiledir[1]+backupfiledirname[1], bcd+backupfiledirname[1])
        except IOError:
            print("目录不存在")
        except WindowsError:
            print("目录不存在")
        print("拷贝文件夹 %s 至目录 %s" % (backupfiledirname, backupdirname))

        # 压缩备份文件夹
        filelist = []
        backupzipname = backupdirname+‘.tar‘
        if os.path.isfile(backupdirname):
            filelist.append(backupdirname)
        else:
            for root,dirs,files in os.walk(backupdirname):
                for name in files:
                    filelist.append(os.path.join(root,name))
        zf = zipfile.ZipFile(backupzipname,"w",zipfile.ZIP_DEFLATED,allowZip64=True)
        for tar in filelist:
            arcname = tar[len(backupdirname):]
            zf.write(tar,arcname)
        zf.close()

        # 连接ftp服务器,备份文件
        ftp = ftpserver.connect(self)
        try:
            ftp.mkd(localhost)
        except Exception as e:
            print("目录 %s 已存在" % localhost )
        fp = open(backupzipname, ‘rb‘)
        print("开始备份文件 %s ... " % backupzipname)
        ftp.set_debuglevel(2)
        try:
            ftp.storbinary(‘STOR ‘ + localhost + ‘/‘ +  backupzipname, fp, bufsize)
        except:
            print("error")
        # ftp.set_pasv(0)
        ftp.set_debuglevel(0)
        fp.close()
        print("成功备份文件 %s 至服务端 %s" % (backupzipname, localhost + ‘/‘ + backupzipname))
        ftp.quit()

        # 删除存放备份文件的临时文件夹与压缩包
        try:
            os.unlink(backupzipname)
            shutil.rmtree(backupdirname)

        except Exception as e:
            print(e)

backup = ftpserver(backupinfo[0], backupinfo[1], backupinfo[2], backupinfo[3], "")
backup.backupfile()
2.2 使用 pyinstaller 打包脚本为可执行 exe
2.3 将可执行 exe 加入客户端任务计划程序

以上是关于基于 Python + Proftpd 实现文件自动备份的主要内容,如果未能解决你的问题,请参考以下文章

Proftpd快速搭建FTP服务器

限制对 proftpd 用户的访问

关于lampp中的proftpd的一些使用

proftpd测试及mysql弱口令登录

proftpd测试及mysql弱口令登录

Python-基于flask的接口框架