init repo
This commit is contained in:
commit
cb729381e7
175
backup.py
Normal file
175
backup.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
from Crypto.Cipher import AES
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import string
|
||||||
|
import random
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
|
||||||
|
windows = False
|
||||||
|
if sys.platform == "win32":
|
||||||
|
windows = True
|
||||||
|
print("")
|
||||||
|
print("####################################")
|
||||||
|
print("Program does not run on Windows!")
|
||||||
|
print("Falling back to Testing Mode!")
|
||||||
|
print("####################################")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
def encrypt_val(clear_text, master):
|
||||||
|
enc_secret = AES.new(master[:32])
|
||||||
|
tag_string = (str(clear_text) +
|
||||||
|
(AES.block_size -
|
||||||
|
len(str(clear_text)) % AES.block_size) * "\0")
|
||||||
|
cipher_text = base64.b64encode(enc_secret.encrypt(tag_string))
|
||||||
|
return cipher_text
|
||||||
|
|
||||||
|
def decrypt_val(cipher_text, master):
|
||||||
|
dec_secret = AES.new(master[:32])
|
||||||
|
raw_decrypted = dec_secret.decrypt(base64.b64decode(cipher_text))
|
||||||
|
clear_val = raw_decrypted.rstrip("\0".encode())
|
||||||
|
return clear_val
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Backup Script")
|
||||||
|
parser.add_argument("-c", "--config", help="config file", default="settings.json")
|
||||||
|
parser.add_argument("-t", "--test", help="Start in testing mode", action='store_true', default=False)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.test:
|
||||||
|
print("")
|
||||||
|
print("####################################")
|
||||||
|
print("Program is now running in testing Mode!")
|
||||||
|
print("####################################")
|
||||||
|
print("")
|
||||||
|
windows = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
json_data=open(args.config).read()
|
||||||
|
except Exception as e:
|
||||||
|
sys.exit("Cant open Config File:\n{0}".format(e))
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = json.loads(json_data)
|
||||||
|
except Exception as e:
|
||||||
|
sys.exit("Parser Error in JSON File {0}:\n{1}".format(args.config, e))
|
||||||
|
|
||||||
|
def save_json():
|
||||||
|
global data
|
||||||
|
global args
|
||||||
|
with open(args.config, 'w') as outfile:
|
||||||
|
json.dump(data, outfile, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
|
||||||
|
MASTER_KEY = ""
|
||||||
|
if not "option" in data or not "masterpassword" in data["option"] or data["option"]["masterpassword"] == "":
|
||||||
|
master_pw = ''.join(random.choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for _ in range(16))
|
||||||
|
data["option"]["masterpassword"] = base64.b64encode(master_pw.encode()).decode("utf-8")
|
||||||
|
print("MASTER PASSWORD automaticly generated. !!!DO NOT REMOVE IT FROM THE SETTINGS FILE!!!")
|
||||||
|
save_json()
|
||||||
|
|
||||||
|
MASTER_KEY = data["option"]["masterpassword"]
|
||||||
|
|
||||||
|
ignore = ["option"]
|
||||||
|
|
||||||
|
for server in data:
|
||||||
|
if server in ignore:
|
||||||
|
continue
|
||||||
|
host = server
|
||||||
|
print("")
|
||||||
|
print("")
|
||||||
|
print("")
|
||||||
|
print("--- {0} --".format(host))
|
||||||
|
for type in data[server]["types"]:
|
||||||
|
print("")
|
||||||
|
user = ""
|
||||||
|
authtype, password = ("", "")
|
||||||
|
|
||||||
|
if not "auth" in type:
|
||||||
|
sys.exit("Server {0} has no authentication".format(server))
|
||||||
|
|
||||||
|
if not "destination" in type:
|
||||||
|
sys.exit("Server {0} has no destination directory".format(server))
|
||||||
|
|
||||||
|
if not os.path.isdir(type["destination"]):
|
||||||
|
sys.exit("Destination {0} for Server {1} not found".format(type["destination"], server))
|
||||||
|
|
||||||
|
if not "user" in type["auth"] or type["auth"]["user"] == "":
|
||||||
|
sys.exit("Server {0} has no user".format(server))
|
||||||
|
else:
|
||||||
|
user = type["auth"]["user"]
|
||||||
|
|
||||||
|
if not "password" in type["auth"] or type["auth"]["password"] == "":
|
||||||
|
if not "key" in type["auth"] or type["auth"]["key"] == "":
|
||||||
|
sys.exit("Server {0} has no password or key".format(server))
|
||||||
|
else:
|
||||||
|
authtype, password = ("key", type["auth"]["key"])
|
||||||
|
else:
|
||||||
|
if type["auth"]["password"].endswith(".==="):
|
||||||
|
authtype, password = ("password", decrypt_val((str(type["auth"]["password"])[:-2]).encode(), MASTER_KEY).decode("utf-8"))
|
||||||
|
else:
|
||||||
|
authtype, password = ("password", type["auth"]["password"])
|
||||||
|
encrypted = encrypt_val(type["auth"]["password"], MASTER_KEY).decode("utf-8")
|
||||||
|
print("Encrypted {0}")
|
||||||
|
type["auth"]["password"] = "{0}.===".format(encrypted)
|
||||||
|
save_json()
|
||||||
|
|
||||||
|
print("{0} {1}@{2} using {3} destination is {4}".format(type["type"], user, host, authtype, type["destination"]))
|
||||||
|
|
||||||
|
if type["type"] == "sftp":
|
||||||
|
if not "backup" in type or type["backup"] == "":
|
||||||
|
sys.exit("Server {0} has backup paths".format(server))
|
||||||
|
|
||||||
|
rsync_base = ["rsync", "-zavx", "--ignore-errors", "--delete", "--delete-excluded"]
|
||||||
|
|
||||||
|
bpaths = []
|
||||||
|
expaths = []
|
||||||
|
|
||||||
|
bpaths.extend(type["backup"])
|
||||||
|
|
||||||
|
if "exclude" in type:
|
||||||
|
for exclude in type["exclude"]:
|
||||||
|
rsync_base.extend(["--exclude", exclude])
|
||||||
|
|
||||||
|
for bpath in bpaths:
|
||||||
|
bpath = bpath.strip()
|
||||||
|
full_path = bpath.strip()
|
||||||
|
rsync_cmd = rsync_base[:]
|
||||||
|
if authtype == "key":
|
||||||
|
rsync_cmd.append("-e")
|
||||||
|
rsync_cmd.append("'ssh -i {0} -p22'".format(password))
|
||||||
|
bpath = user + "@" + host + ":" + bpath
|
||||||
|
rsync_cmd.append(bpath)
|
||||||
|
rsync_cmd.append(type["destination"] + os.sep + full_path.replace("/", "_").replace("\\", "_"))
|
||||||
|
print("Running Rsync for {0}".format(bpath))
|
||||||
|
if not windows:
|
||||||
|
os.system(" ".join(rsync_cmd))
|
||||||
|
else:
|
||||||
|
print(" ".join(rsync_cmd))
|
||||||
|
elif type["type"] == "mysql":
|
||||||
|
if not "database" in type or type["database"] == "":
|
||||||
|
sys.exit("Server {0} has database info".format(server))
|
||||||
|
|
||||||
|
tstamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
|
||||||
|
skip = ["information_schema", "performance_schema"]
|
||||||
|
for db in type["database"]:
|
||||||
|
if db in skip:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if db == "all":
|
||||||
|
db = "--all-databases"
|
||||||
|
|
||||||
|
dbbackup_name = "{0}_{1}.{2}".format(tstamp, ("all" if db == "--all-databases" else db), "sql")
|
||||||
|
dbbackup_path = type["destination"] + os.sep + dbbackup_name
|
||||||
|
|
||||||
|
dump_cmd = "mysqldump -u " + user
|
||||||
|
if host != None:
|
||||||
|
dump_cmd += " -h " + "'" + host + "'"
|
||||||
|
if authtype == "password" and password != "":
|
||||||
|
dump_cmd += " -p" + password
|
||||||
|
dump_cmd += " -e --opt -c " + db + " | gzip > " + dbbackup_path + ".gz"
|
||||||
|
print("Dump db, %s to %s." % (db, dbbackup_path))
|
||||||
|
if not windows:
|
||||||
|
os.system(dump_cmd)
|
||||||
|
else:
|
||||||
|
print(dump_cmd)
|
37
settings.json.sample
Normal file
37
settings.json.sample
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"exampleHost": {
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"auth": {
|
||||||
|
"key": "/root/.ssh/id_rsa",
|
||||||
|
"user": "backups"
|
||||||
|
},
|
||||||
|
"backup": [
|
||||||
|
"/var/www/html"
|
||||||
|
],
|
||||||
|
"destination": "/mnt/backups/data",
|
||||||
|
"exclude": [
|
||||||
|
"*.filetype.to.exclude",
|
||||||
|
"*.another.to.exclude",
|
||||||
|
"/path/to/exclude",
|
||||||
|
"/another/path/to/exclude"
|
||||||
|
],
|
||||||
|
"type": "sftp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"auth": {
|
||||||
|
"password": "PlainTextPassword",
|
||||||
|
"user": "root"
|
||||||
|
},
|
||||||
|
"database": [
|
||||||
|
"wordpress",
|
||||||
|
"userlist"
|
||||||
|
],
|
||||||
|
"destination": "/mnt/backups/db",
|
||||||
|
"type": "mysql"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"option": {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user