bash – szyfrowana kopia zapasowa bazy danych i archiwum logów

Automatyzując zadania tworzenia kopii zapasowej, warto pamiętać o takich narzędziach jak CRON i języku skryptowym BASH. Przykład dla Ubuntu 20.

Oczywiście ważne jest zabezpieczenie kopii bazy danych, nie trzeba wielkiej wyobraźni aby uświadomić sobie zagrożenia utraty i dostępu do takiej kopii.

O ile w CRON może to wyglądać np tak:

# crontab -e

15 3 * * * /home/wiks/cron_mysql_arch.sh&

lub w osobnym skrypcie dla /etc/cron.d/wiks (z podaniem użytkownika wykonującego skrypt):

# vi /etc/cron.d/wiks

15 3 * * * wiks /home/wiks/cron_mysql_arch.sh&

Czyli raz dziennie, w okolicy 3 nad razem wykonaj skrypt jako użytkownik wiks .

W BASHu zaś (niech to będzie plik o nazwie: cron_mysql_arch.sh ) umieszczam definicje i polecenia do wykonania kopii, spakowania jej i …

#!/bin/bash

DB_BACKUP_PATH='/home/wiks/db_backups'

TODAY=`date +"%Y%m%d"`

MYSQL_HOST='localhost'
MYSQL_PORT='3306'
MYSQL_USER='cron_dbarch'
MYSQL_PASSWORD='????????????'
MYSQL_DB_NAME='baza_danych'

DB_BACKUP_PATH_TODAY=${DB_BACKUP_PATH}/${TODAY}

mkdir -p ${DB_BACKUP_PATH_TODAY}

mysqldump --no-tablespaces --single-transaction -h ${MYSQL_HOST} \
        -P ${MYSQL_PORT} \
        -u ${MYSQL_USER} \
        -p${MYSQL_PASSWORD} \
        ${MYSQL_DB_NAME} | gzip > ${DB_BACKUP_PATH_TODAY}/${MYSQL_DB_NAME}_${TODAY}.sql.gz

Warto zabezpieczyć ten plik, ograniczając możliwość podejrzenia: chmod 700 oraz umżliwiając bycie wykonywalnym: chmod +x

chmod 700 cron_mysql_arch.sh
chmod +x cron_mysql_arch.sh

Skrypt loguje się do bazy danych MySQL jako użytkownik cron_dbarch (też warto starannie dobrać uprawnienia -nie zbyt duże), i pobiera bazę danych, kompresując ją za pomocą gzip. wcześniej utworzył sobie katalog o nazwie zależnej od aktualnej daty, do tego zaś katalogu tworzy spakowany plik bazy danych, o nazwie będącej połączeniem nazwy tej bazy z datą.

Utworzony folder dla jednego dnia, można wykorzystać również jako pojemnik np. na kopie logów (gdyby uznano, że warto je mieć również zarchiwizowane dla potencjalnych prób wyjaśniania niewyjaśnionego…). Korzystając z pomysłu poniższego, czyli archiwizowania codziennego logów np Django, warto zadbać o ich codzienną rotację [ 'logging.handlers.TimedRotatingFileHandler', 'when': 'D' ].

# logi apache:
echo 'kopia logów Apache2 (2)'
mkdir -p ${DB_BACKUP_PATH_TODAY}/var_log/apache2
cp /var/log/apache2/web_access.log ${DB_BACKUP_PATH_TODAY}/var_log/apache2/
cp /var/log/apache2/web_error.log ${DB_BACKUP_PATH_TODAY}/var_log/apache2/

# albo:

# logi django:
echo 'kopia logów Django (2)'
mkdir -p ${DB_BACKUP_PATH_TODAY}/django_logs
cp /home/wiks/Django/logs/debug.log ${DB_BACKUP_PATH_TODAY}/django_logs/

Gdy mam już paczkę, którą chciałbym odesłać na półkę, zapewniając, że będę mógł odzyskać jej zawartość, ale nikt poza mną nie będzie w stanie tego zrobić (nawet jak pozna miejsce półki)… spakuję paczkę do jednego pliku i zaszyfruję. Oczywiście usuwając folder i niezaszyfrowaną paczkę:

echo 'pakuję wszystko razem'
tar -zcvf ${DB_BACKUP_PATH_TODAY}.tar ${DB_BACKUP_PATH_TODAY}

echo 'usuwam folder po spakowaniu i skopiowaniu'
rm -rf ${DB_BACKUP_PATH_TODAY}

echo 'encryption...'
gpg --batch --yes -e -r qr@qrgo.pl ${DB_BACKUP_PATH_TODAY}.tar

echo 'usuwam spakowany po zakodowaniu'
rm -rf ${DB_BACKUP_PATH_TODAY}.tar

Pakowanie, usuwanie folderu – jasne, teraz kilka słów o kodowaniu.

gpg używa tutaj klucza publicznego skojarzonego z adresem email qr@qrgo.pl

Taki klucz mógłby być wytworzony na komputerze, który tworzy tą kopię zapasową, wtedy komputer miałby również klucz prywatny i byłby w stanie nie tylko szyfrować, ale również niezaprzeczalnie podpisać zaszyfrowany plik.

Tak się jednak nie stało, klucze zostały utworzone w innym miejscu, tutaj jedynie zaimportowałem klucz publiczny.

wiks@qrgo:/home/wiks/Django$ gpg --import pub_key.asc 
gpg: key 7A619650AE5B0EE0: public key "QRgo.pl team <qr@qrgo.pl>" imported
gpg: Total number processed: 1
gpg:               imported: 1


wiks@qrgo:/home/wiks/Django$ gpg -e -r qr@qrgo.pl plik.test
gpg: 7A619650AE5B0EE0: There is no assurance this key belongs to the named user
sub  cv25519/7A619650AE5B0EE0 2020-12-23 QRgo.pl team <qr@qrgo.pl>
 Primary key fingerprint: 7630 9D31 B660 D1E4 A4A4  8EF5 E038 254A 1AE7 8E43
      Subkey fingerprint: 44B8 945F E9E2 4441 EC79  35E3 7A61 9650 AE5B 0EE0

you may answer the next question with yes.

Use this key anyway? (y/N) y

Zaimportowanie klucza sprawiło, że jest on dla gpg niewiarygodny, dlatego przy każdej próbie użycia go do szyfrowania, otrzymamy pytanie 'czy na pewno chcę go użyć?'. -cała automatyzacja prysnęła jak bańka mydlana…

Należy na komputerze na którym zaimportowano dany klucz publiczny, wyedytować go gpg –edit-key <email> i zmienić zaufanie na absolutne – wybierając jak w poniższym przykładzie '5′ :

gpg --edit-key qr@qrgo.pl

[...]

gpg> trust
sec  ed25519/E038254A1AE78E43
     utworzono: 2020-12-23  wygasa: 2025-12-22  użycie: SC  
     zaufanie: absolutne     poprawność: absolutne
ssb  cv25519/7A619650AE5B0EE0
     utworzono: 2020-12-23  wygasa: 2025-12-22  użycie: E   
[   absolutne   ] (1). QRgo.pl team <qr@qrgo.pl>

Zastanów się jak bardzo ufasz temu użytkownikowi w kwestii sprawdzania
tożsamości innych użytkowników (czy sprawdzi on odciski kluczy pobrane
z różnych źródeł, dokumenty potwierdzające tożsamość, itd.).

  1 = nie wiem albo nie powiem
  2 = NIE ufam
  3 = mam ograniczone zaufanie
  4 = mam pełne zaufanie
  5 = ufam absolutnie
  m = powrót do głównego menu

Decyzja? 

Należy pamiętać, że importujemy klucz jako ten użytkownik, który będzie reprezentowany przez CRON wykonujący archiwizację i szyfrowanie. I jako ten użytkownik edytować klucz i ustawić zaufanie do niego jako pełne.

Plik wynikowy będzie miał zatem rozszerzenie *.tar.gpg i będzie dość bezpieczny, nawet jeśli ktoś pozna miejsce półki i go skopiuje, nie będzie w stanie nic zrobić bez klucza prywatnego.

Dodaj komentarz

Translate »