基於 Python + Proftpd 實現文件自動備份
阿新 • • 發佈:2019-02-21
centos project ase getcwd upa roo 執行 http 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 安裝
[root@localhost ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
2.proftpd 與 OpenSSL 安裝
[root@localhost ~]# yum install -y proftpd openssl proftpd-utils
3.啟動proftpd服務
[root@localhost ~]# systemctl start proftpd.service [root@localhost ~]# systemctl enable proftpd.service
4.防火墻設置
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-service=ftp
[root@localhost ~]# firewall-cmd --reload
5.ftp用戶創建
[root@localhost ~]# groupadd ftpgroup ## 設置 /ftpshare 目錄為 proftpd 用戶的家目錄 [root@localhost ~]# useradd -G ftpgroup proftpd -s /sbin/nologin -d /ftpshare [root@localhost ~]# passwd proftpd
6.proftpd 服務器配置
[root@localhost ~]# cp /etc/proftpd.conf /etc/proftpd.conf.bak
[root@localhost ~]# vi /etc/proftpd.conf
## 設置被動模式端口為 6000-6100
PassivePorts 6000 6100
## 設置被動模式返回地址為映射的公網地址
MasqueradeAddress xxx.xxx.xxx.xxx
## 設置超時時間為 600
TimeoutIdle 600
7.防火墻開放通信端口
[root@localhost ~]# firewall-cmd --permanent --zone=public --add-port=6000-6100/tcp
[root@localhost ~]# firewall-cmd --reload
8.重啟服務
[root@localhost ~]# systemctl restart proftpd.service
三、客戶端配置
1.Linux 服務器配置
1.1 創建ftp備份腳本
[root@localhost ~]# 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 腳本
[root@localhost ~]# 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 根據實際需求將腳本加入定時任務
[root@localhost ~]# 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 實現文件自動備份