Commit 373570bc authored by Björn's avatar Björn

adding

parent b1fa0d5e
[default]
targets = test,g
work_directory = build
#gpg_key_id =
sources=
remote_host=
remote_target=
temp_dir=
[remote]
#remote_username =
#remote_host =
#remote_port =
#remote_directory =
gpg_key_id=
gpg_passphrase=
[mysql]
#mysql_password =
#mysql_username =
remove_older_than=
gpg --list-secret-keys --keyid-format LONG
# backup-tar
A simple bash-script to backup with tar, split and gpg.
## Requirements
### Rsync
For more information show [https://rsync.samba.org/](https://rsync.samba.org/).
### ssh-key
Generate a ssh-key to authenficate on the Remote-Server.
```
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"
```
For more Information show [this help on github](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/).
### optional: gpg
Generate a gpg-key to encrypt your backup. Add the id of the key to the option gpg_key_id. For more Information show [this help on github](https://help.github.com/articles/generating-a-new-gpg-key/).
**Don't forget to export your keys, if the get lost, you will never ever able to restore your data**
## Known Problems
### trust of imported gpg-key
Imported gpg-keys can throw errors, you must set the trust to fix this,
```bash
gpg --edit-key <recipent>
gpg> trust
```
```bash
1 = I don't know or won't say
2 = I do NOT trust
3 = I trust marginally
4 = I trust fully
5 = I trust ultimately
m = back to the main menu
```
```bash
Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
```
### gpg-agent
Cronjob maybe don't load the gpg-agent.
```bash
#!/usr/bin/env bash
envfile="${HOME}/.gnupg/gpg-agent.env"
if test -f "$envfile" && kill -0 $(grep GPG_AGENT_INFO "$envfile" | cut -d: -f 2) 2>/dev/null; then
eval "$(cat "$envfile")"
else
eval "$(gpg-agent --daemon --write-env-file "$envfile")"
fi
export GPG_AGENT_INFO # the env file does not contain the export statement
```
```bash
*/5 * * * * source /home/<username>/.gnupg/gpg-agent.env && export GPG_AGENT_INFO && cd <backup-tar> && ./backup.sh
gpg --list-secret-keys --keyid-format LONG
```
[https://blog.tenak.net/2012/11/2012-11-gpg-agent.html](https://blog.tenak.net/2012/11/2012-11-gpg-agent.html)
## Commands
### ./backup.sh
Start the backup.
### ./restore.sh
If no argument is set, it shows a list of the last backups. To restore a Backup add the filename without file-extension that you want to download.
## Config
This Scripts works with a config-file. Each command has the option "--config-file" to set the path to the
config-file. If you not set the option it will show in the directory of the Script.
### targets
That is the directories and files you want to backup.
### work_directory
The **work_directory** is created during the backup and also if you restore files. If a backup runs and you dump data from
databases these files will write in this directory. After the backup the directory will be deleted. The backup and restore will only starts
if the directory don't exists.
### remote_username
### remote_host
### optional: max_age
The number of days to preserve old backups, if files are older the will be deleted after the backup.
### optional: gpg_key_id
To encrypt data add the id of the gpg-key.
### optional: excludes
Exclude files and directories.
### optional: remote_directory
### optional: remote_port
Port of ssh service on Remote Server, default is set to 22.
### optional: mysql_username
### optional: mysql_password
### optional: mysql_host
Host of mysql, default is set to "localhost"
#!/usr/bin/python3
#
# sending email
# backup
#
# usage: backup.py [-h] [--attachments ATTACHMENTS [ATTACHMENTS ...]]
# [--encrypt ENCRYPT]
......@@ -187,7 +187,7 @@ class BackupFiles:
options = ''
# if destination already exists and --force is not set
# if destination already exists and --force is not set
if (os.path.exists(self._args.destination) and self._args.force == False):
print('Error! Destination exists! Add --force to overwrite!')
exit()
......
#!/usr/bin/python3
#
# sending email
#
# usage: sendmail.py [-h] [--attachments ATTACHMENTS [ATTACHMENTS ...]]
# [--encrypt ENCRYPT]
# message subject
#
# install to use:
#
# apt-get install python-pip
# pip install python-gnupg
#
# nano ~/.bash_profile
# export SMTP_SERVER=""
# export SMTP_PORT=""
# export SMTP_USERNAME=""
# export SMTP_PASSWORD=""
# export SMTP_AUTH_MODE=""
# export SMTP_ENCRYPTION=""
# export SMTP_FROM=""
# export SMTP_TO=""
#
# gpg --import <email>.pub.asc
# gpg --edit-key <email>
# gpg > trust
# Your decision? 5 (Ultimate trust)
#
import argparse
import os
import gnupg
# stuff for sending emails
import smtplib, email
#
#
#
#
class Sendmail:
#
#
#
#
def __init__(self):
self._config = {
'SMTP_PORT': 465
}
self._config_required = [
'SMTP_SERVER',
'SMTP_PORT',
'SMTP_USERNAME',
'SMTP_PASSWORD',
'SMTP_AUTH_MODE',
'SMTP_ENCRYPTION',
'SMTP_FROM',
'SMTP_TO'
]
# adding parser for arguments
parser = argparse.ArgumentParser()
# define arguments
parser.add_argument('message', help='message to send')
parser.add_argument('subject', help='subject for message')
parser.add_argument('--attachments', nargs='+', help='attach files')
parser.add_argument('--encrypt', default=False, type=lambda x: (str(x).lower() in ['true','1', 'yes']), help='encrypt with gpg')
# parsering arguments
self._args = parser.parse_args()
self._validate_arguments(self._args)
self._validate_config()
#
#
#
#
def run(self):
message = self._create_message(self._args, self._config)
if self._args.encrypt:
message = self._encrypt_message(message, self._args, self._config)
self._send(message, self._config)
#
#
#
#
def _validate_config(self):
# adding config values
for key in self._config_required:
# reading environment variables
if key in os.environ:
self._config[key] = os.environ[key]
else:
print('Environment variable "' + key + '" not found!')
exit()
#
#
#
#
def _validate_arguments(self, args):
# if attachments not exists and file also not, exit
if args.attachments:
for attachment in args.attachments:
if not os.path.isfile(attachment):
print('Attachment "' + attachment + '" not found!')
exit()
#
# creating message
#
#
def _create_message(self, args, config):
message = email.MIMEMultipart.MIMEMultipart()
body = email.MIMEText.MIMEText(args.message)
# attach body
message.attach(body)
if args.attachments:
for attachment in args.attachments:
message.attach(self._add_attachment(attachment))
message.add_header('Subject', args.subject)
message.add_header('From', config['SMTP_FROM'])
message.add_header('To', config['SMTP_TO'])
return message
#
# adding attachment and encode to base64
#
#
def _add_attachment(self, attachment):
message = email.MIMEBase.MIMEBase('application', 'octet-stream')
# adding header
message.add_header('Content-Type', 'application/octet-stream', filename=os.path.basename(attachment))
message.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attachment))
message.set_payload(open(attachment, 'rb').read())
email.encoders.encode_base64(message)
return message
#
# encrypt message
#
#
def _encrypt_message(self, message, args, config):
encrypted = email.MIMEBase.MIMEBase('multipart', _subtype='encrypted', protocol='application/pgp-encrypted')
encrypted.add_header('Subject', args.subject)
encrypted.add_header('From', config['SMTP_FROM'])
encrypted.add_header('To', config['SMTP_TO'])
# adding headers
encrypted_header = email.message.Message()
encrypted_header.add_header('Content-Type', 'application/pgp-encrypted')
encrypted_header.add_header('Content-Description', 'PGP/MIME version identification')
encrypted_header.set_payload('Version: 1' + '\n')
# adding message and encrypt
encrypted_message = email.message.Message()
encrypted_message.add_header('Content-Type', 'application/octet-stream')
encrypted_message.add_header('Content-Description', 'OpenPGP encrypted message')
encrypted_message.add_header('Content-Disposition', 'inline')
if (os.getlogin() == 'root'):
gpgpath = '/root/.gnupg'
else:
gpgpath = '/home/' + os.getlogin() + '/.gnupg'
gpg = gnupg.GPG(gnupghome=gpgpath)
message = str(gpg.encrypt(message.as_string(), config['SMTP_TO']))
encrypted_message.set_payload(message)
encrypted.attach(encrypted_header)
encrypted.attach(encrypted_message)
return encrypted
#
# send email
#
# @param config
# @param message
#
def _send(self, message, config):
# Now send the message
try:
if config['SMTP_ENCRYPTION'] == 'ssl' or config['SMTP_ENCRYPTION'] == 'tls':
mailer = smtplib.SMTP_SSL(config['SMTP_SERVER'], config['SMTP_PORT'])
else:
mailer = smtplib.SMTP(config['SMTP_SERVER'], config['SMTP_PORT'])
except Exception as exception:
print('SMTP Error!')
print(exception)
exit()
mailer.login(config['SMTP_USERNAME'], config['SMTP_PASSWORD'])
mailer.sendmail(config['SMTP_FROM'], config['SMTP_TO'], message.as_string())
mailer.close()
# let it rain
sendmail = Sendmail()
sendmail.run()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment