Czasami nieuniknione jest uruchamianie serwerów baz danych MySQL w publicznej lub jawnej sieci. Jest to typowa konfiguracja we współdzielonym środowisku hostingu, w którym serwer jest skonfigurowany z wieloma usługami i często działa na tym samym serwerze, co serwer bazy danych. Dla tych, którzy mają tego rodzaju konfigurację, zawsze powinieneś mieć jakąś ochronę przed cyberatakami, takimi jak odmowa usługi, hacking, cracking, naruszenia danych; wszystko to może spowodować utratę danych. Są to rzeczy, których zawsze chcemy uniknąć w naszym serwerze bazodanowym.
Oto kilka wskazówek, które możemy zrobić, aby poprawić nasze bezpieczeństwo MySQL lub MariaDB.
Regularnie skanuj serwery bazy danych
Ochrona przed wszelkimi złośliwymi plikami na serwerze jest bardzo ważna. Regularnie skanuj serwer w poszukiwaniu wirusów, programów szpiegujących, złośliwego oprogramowania lub rootkitów, zwłaszcza jeśli serwer bazy danych znajduje się w tej samej lokalizacji, co inne usługi, takie jak serwer poczty, HTTP, FTP, DNS, WebDAV, telnet i tak dalej. Zwykle większość problemów związanych z atakami hakerskimi w bazach danych pochodzi z warstwy aplikacji, z którą ma do czynienia sieć publiczna. Dlatego ważne jest, aby przeskanować wszystkie pliki, zwłaszcza pliki WWW/aplikacje, ponieważ są one jednym z punktów wejścia do serwera. Jeśli te zostaną naruszone, haker może dostać się do katalogu aplikacji i mieć możliwość odczytania plików aplikacji. Mogą one zawierać poufne informacje, na przykład dane logowania do bazy danych.
ClamAV to jedno z najbardziej znanych i zaufanych rozwiązań antywirusowych dla różnych systemów operacyjnych, w tym Linux. Jest darmowy i bardzo łatwy w instalacji oraz posiada dość dobry mechanizm wykrywania, aby szukać niechcianych rzeczy na twoim serwerze. Zaplanuj okresowe skanowanie w zadaniu cron, na przykład:
0 3 * * * /bin/freshclam ; /bin/clamscan / --recursive=yes -i > /tmp/clamav.log ; mail -s clamav_log_`hostname` [email protected] < /tmp/clamav.log
Powyższe zaktualizuje bazę danych wirusów ClamAV, przeskanuje wszystkie katalogi i pliki oraz wyśle e-mail o stanie wykonania i zgłosi codziennie o 3 nad ranem.
Używaj bardziej rygorystycznych ról i uprawnień użytkowników
Podczas tworzenia użytkownika MySQL nie zezwalaj wszystkim hostom na dostęp do serwera MySQL za pomocą hosta z symbolami wieloznacznymi (%). Powinieneś przeskanować swój host MySQL i poszukać wartości hosta z symbolami wieloznacznymi, jak pokazano w poniższej instrukcji:
mysql> SELECT user,host FROM mysql.user WHERE host = '%';
+---------+------+
| user | host |
+---------+------+
| myadmin | % |
| sbtest | % |
| user1 | % |
+---------+------+
Z powyższych danych wyjściowych określ lub usuń wszystkich użytkowników, którzy mają tylko wartość „%” w kolumnie Host. Użytkownicy, którzy potrzebują zdalnego dostępu do serwera MySQL, mogą zostać zmuszeni do korzystania z metody tunelowania SSH, która nie wymaga zdalnej konfiguracji hosta dla użytkowników MySQL. Większość klientów administracyjnych MySQL, takich jak MySQL Workbench i HeidiSQL, można skonfigurować tak, aby łączyły się z serwerem MySQL za pomocą tunelowania SSH, dzięki czemu można całkowicie wyeliminować zdalne połączenie dla użytkowników MySQL.
Ponadto ogranicz przywilej SUPER tylko do użytkowników z hosta lokalnego lub łączących się przez plik typu socket UNIX. Zachowaj ostrożność podczas przypisywania uprawnienia FILE użytkownikom innym niż root, ponieważ umożliwia ono odczytywanie i zapisywanie plików na serwerze za pomocą instrukcji LOAD DATA INFILE i SELECT ... INTO OUTFILE. Każdy użytkownik, któremu przyznano to uprawnienie, może również czytać lub zapisywać dowolny plik, który serwer MySQL może odczytywać lub zapisywać.
Zmień domyślne ustawienia bazy danych
Odchodząc od domyślnych ustawień, nazewnictwa i konfiguracji, możemy zredukować wektor ataku do kilku fałd. Poniższe działania to kilka przykładów domyślnych konfiguracji, które administratorzy baz danych mogą łatwo zmienić, ale często pomijane w związku z MySQL:
- Zmień domyślny port MySQL na inny niż 3306.
- Zmień nazwę użytkownika root MySQL na inną niż „root”.
- Wymuś wygaśnięcie hasła i skróć czas życia hasła dla wszystkich użytkowników.
- Jeśli MySQL znajduje się w tym samym miejscu co serwery aplikacji, wymuś połączenie tylko przez plik gniazda UNIX i przestań nasłuchiwać na porcie 3306 dla wszystkich adresów IP.
- Wymuszaj szyfrowanie klient-serwer i szyfrowanie replikacji serwer-serwer.
Właściwie omówiliśmy to szczegółowo w tym poście na blogu, Jak zabezpieczyć serwery MySQL/MariaDB.
Skonfiguruj opóźnione urządzenie podrzędne
Opóźniony slave to tylko typowy slave, jednak serwer slave celowo wykonuje transakcje później niż master o co najmniej określony czas, dostępny z MySQL 5.6. Zasadniczo zdarzenie odebrane od urządzenia głównego nie jest wykonywane, dopóki nie zostanie wykonane co najmniej N sekundy później niż jego wykonanie na kapitanie. W rezultacie niewolnik będzie odzwierciedlał stan mistrza jakiś czas temu.
Opóźnione urządzenie podrzędne może być użyte do odzyskania danych, co byłoby pomocne, gdy problem zostanie wykryty natychmiast, w okresie opóźnienia. Załóżmy, że skonfigurowaliśmy urządzenie podrzędne z 6-godzinnym opóźnieniem względem urządzenia nadrzędnego. Jeśli nasza baza danych została zmodyfikowana lub usunięta (przypadkowo przez programistę lub celowo przez hakera) w tym przedziale czasowym, istnieje możliwość cofnięcia się do momentu tuż przed tym, poprzez zatrzymanie aktualnego mastera, a następnie uruchomienie serwera slave do pewnego momentu za pomocą następującego polecenia:
# on delayed slave
mysql> STOP SLAVE;
mysql> START SLAVE UNTIL MASTER_LOG_FILE='xxxxx', MASTER_LOG_POS=yyyyyy;
Gdzie „xxxxx” to binarny plik dziennika, a „yyyyy” to pozycja tuż przed wystąpieniem awarii (użyj narzędzia mysqlbinlog, aby sprawdzić te zdarzenia). Na koniec, promuj urządzenie podrzędne, aby stało się nowym masterem, a twoja usługa MySQL będzie teraz działać jak zwykle. Ta metoda jest prawdopodobnie najszybszym sposobem na odzyskanie bazy danych MySQL w środowisku produkcyjnym bez konieczności ponownego ładowania kopii zapasowej. Posiadanie wielu opóźnionych urządzeń podrzędnych o różnych długościach, jak pokazano w tym blogu, Multiple Delayed Replication Slaves for Disaster Recovery z niskim RTO, jak skonfigurować opłacalne serwery opóźnionej replikacji na kontenerach Dockera.
Włącz rejestrowanie binarne
Logowanie binarne jest ogólnie zalecane, aby było włączone, nawet jeśli pracujesz na samodzielnym serwerze MySQL/MariaDB. Dziennik binarny zawiera informacje o instrukcjach SQL, które modyfikują zawartość bazy danych. Informacje są przechowywane w postaci „zdarzeń”, które opisują modyfikacje. Pomimo wpływu na wydajność, posiadanie dziennika binarnego umożliwia odtworzenie serwera bazy danych do dokładnego punktu, w którym chcesz go przywrócić, co jest znane również jako odzyskiwanie do punktu w czasie (PITR). Logowanie binarne jest również obowiązkowe w przypadku replikacji.
Gdy włączone jest logowanie binarne, podczas wykonywania pełnej kopii zapasowej należy dołączyć plik dziennika binarnego i informacje o pozycji. W przypadku mysqldump użycie flagi --master-data z wartością 1 lub 2 spowoduje wydrukowanie niezbędnych informacji, których możemy użyć jako punktu wyjścia do przewijania bazy danych podczas późniejszego odtwarzania dzienników binarnych.
Po włączeniu rejestrowania binarnego możesz użyć innej fajnej funkcji odzyskiwania zwanej flashbackiem, która jest opisana w następnej sekcji.
Włącz Flashback
Funkcja flashback jest dostępna w MariaDB, gdzie można przywrócić dane do poprzedniej migawki w bazie danych MySQL lub w tabeli. Flashback używa mysqlbinlog do tworzenia instrukcji wycofania i potrzebuje do tego pełnego obrazu wiersza dziennika binarnego. Dlatego, aby korzystać z tej funkcji, serwer MySQL/MariaDB musi być skonfigurowany w następujący sposób:
[mysqld]
...
binlog_format = ROW
binlog_row_image = FULL
Poniższy diagram architektury ilustruje konfigurację flashbacku na jednym z urządzeń podrzędnych:
Aby wykonać operację retrospekcji, najpierw musisz określić datę i godzinę kiedy chcesz "zobaczyć" dane lub plik dziennika binarnego i pozycję. Następnie użyj flagi --flashback z narzędziem mysqlbinlog, aby wygenerować instrukcje SQL, aby przywrócić dane do tego punktu. W wygenerowanym pliku SQL zauważysz, że zdarzenia DELETE są konwertowane na INSERT i odwrotnie, a także zamienia części WHERE i SET zdarzeń UPDATE.
Poniższa linia poleceń powinna zostać wykonana na urządzeniu slave2 (skonfigurowanym za pomocą binlog_row_image=FULL):
$ mysqlbinlog --flashback --start-datetime="2020-02-17 01:30:00" /var/lib/mysql/mysql-bin.000028 -v --database=shop --table=products > flashback_to_2020-02-17_013000.sql
Następnie odłącz slave2 od łańcucha replikacji, ponieważ zamierzamy go przerwać i użyć serwera do wycofania naszych danych:
mysql> STOP SLAVE;
mysql> RESET MASTER;
mysql> RESET SLAVE ALL;
Na koniec zaimportuj wygenerowany plik SQL do serwera MariaDB dla sklepu z bazą danych na urządzeniu slave2:
$ mysql -u root -p shop < flashback_to_2020-02-17_013000.sql
W przypadku zastosowania powyższego tabela „produkty” będzie według stanu z dnia 2020-02-17 01:30:00. Z technicznego punktu widzenia wygenerowany plik SQL można zastosować zarówno do serwerów MariaDB, jak i MySQL. Możesz również przesłać plik binarny mysqlbinlog z serwera MariaDB, aby móc korzystać z funkcji flashback na serwerze MySQL. Jednak implementacja MySQL GTID różni się od MariaDB, dlatego przywrócenie pliku SQL wymaga wyłączenia MySQL GTID.
Kilka zalet korzystania z flashbacku polega na tym, że nie trzeba zatrzymywać serwera MySQL/MariaDB, aby wykonać tę operację. Gdy ilość danych do przywrócenia jest niewielka, proces flashbacku jest znacznie szybszy niż odzyskiwanie danych z pełnej kopii zapasowej.
Zapisuj wszystkie zapytania do bazy danych
Dziennik ogólny zasadniczo przechwytuje każdą instrukcję SQL wykonaną przez klienta na serwerze MySQL. Jednak może to nie być popularna decyzja na obciążonym serwerze produkcyjnym ze względu na wpływ na wydajność i zużycie miejsca. Jeśli wydajność ma znaczenie, logowanie binarne ma wyższy priorytet do włączenia. Dziennik ogólny można włączyć w czasie wykonywania, uruchamiając następujące polecenia:
mysql> SET global general_log_file='/tmp/mysql.log';
mysql> SET global log_output = 'file';
mysql> SET global general_log = ON;
Możesz także ustawić ogólny wynik logu na tabelę:
mysql> SET global log_output = 'table';
Możesz następnie użyć standardowej instrukcji SELECT względem tabeli mysql.general_log, aby pobrać zapytania. Oczekuj nieco większego wpływu na wydajność podczas pracy z tą konfiguracją, jak pokazano w tym poście na blogu.
W przeciwnym razie można użyć zewnętrznych narzędzi do monitorowania, które mogą wykonywać próbkowanie i monitorowanie zapytań, dzięki czemu można filtrować i kontrolować zapytania przychodzące na serwer. ClusterControl może służyć do zbierania i podsumowywania wszystkich zapytań, jak pokazano na poniższych zrzutach ekranu, na których filtrujemy wszystkie zapytania zawierające ciąg DELETE:
Podobne informacje są również dostępne na stronie z najczęściej zadawanymi zapytaniami w ProxySQL (jeśli aplikacja jest połączenie przez ProxySQL):
Może być używany do śledzenia ostatnich zmian, które zaszły na serwerze bazy danych i mogą być również wykorzystywane do celów audytu.
Wnioski
Twoje serwery MySQL i MariaDB muszą być przez cały czas dobrze chronione, ponieważ zwykle zawierają poufne dane, którymi opiekują się napastnicy. Możesz także użyć ClusterControl do zarządzania aspektami bezpieczeństwa swoich serwerów baz danych, jak pokazano w tym poście na blogu Jak zabezpieczyć bazy danych Open Source za pomocą ClusterControl.