PostgreSQL jest ceniony za swoje bogate funkcje, elastyczność oraz wysoką wydajność. Jest szeroko stosowany zarówno w małych, jak i dużych organizacjach. W dobie rosnących zagrożeń cybernetycznych, hardening (utwardzanie) serwerów i baz danych PostgreSQL staje się jednym z najważniejszych elementów strategii bezpieczeństwa IT. Hardening oznacza proces zabezpieczania systemów komputerowych, czy w naszym przypadku baz danych przed nieautoryzowanym dostępem i innymi zagrożeniami poprzez zastosowanie różnorodnych technik i praktyk bezpieczeństwa. 

Dlaczego hardening jest ważny?

Zabezpieczenie to nie tylko ochrona przed utratą danych, ale również zapobieganie naruszeniom ich integralności i poufności. Utrata danych może prowadzić do poważnych konsekwencji finansowych, prawnych oraz utraty reputacji. Dlatego organizacje muszą podejmować świadome kroki w celu ochrony swoich systemów. W tym artykule omówimy najpopularniejsze techniki hardeningu dla bazy danych PostgreSQL.

Podstawy hardeningu serwerów PostgreSQL


Na początek warto przypomnieć podstawowe zasady bezpieczeństwa systemów operacyjnych:  

  1. Aktualizacje i łatki – pierwszym krokiem w hardeningu serwera jest zapewnienie, że system operacyjny i wszystkie zainstalowane oprogramowanie są na bieżąco aktualizowane. Regularne instalowanie poprawek zabezpieczeń zmniejsza ryzyko wykorzystania znanych luk w systemie. 
  2. Minimalizacja powierzchni ataku – usunięcie lub wyłączenie niepotrzebnych usług i oprogramowania jest kluczowe. Im mniej usług jest uruchomionych, tym mniejsza powierzchnia ataku dostępna dla potencjalnych napastników. Należy również zamknąć wszystkie nieużywane porty sieciowe.
  3. Uwierzytelnianie i autoryzacja – korzystanie z silnych haseł oraz mechanizmów uwierzytelniania dwuskładnikowego (2FA) znacząco zwiększa bezpieczeństwo. Konta użytkowników powinny mieć przypisane minimalne niezbędne uprawnienia zgodnie z zasadą najmniejszych uprawnień (PoLP – Principle of Least Privilege). 

Konfiguracja sieci:

  1. Firewalle – firewalle są pierwszą linią obrony w zabezpieczeniach sieciowych. Powinny być skonfigurowane tak, aby blokować wszelki ruch sieciowy, który nie jest niezbędny dla działania serwera PostgreSQL. 
  2. Segregacja sieciowa – dzieląc sieć na segmenty (np. za pomocą VLANów), można lepiej chronić serwery bazy danych przed dostępem z innych części sieci. Serwery baz danych powinny znajdować się w odizolowanej strefie z ograniczonym dostępem. 

Konfiguracja plików samej usługi PostgreSQL

Poniżej opisujemy kilkanaście prostych zasad, których należy przestrzegać podczas konfigurowania usługi postgres. Należy tu odróżnić dwa typy plików konfiguracyjnych w kontekście postgresa. 

Konfiguracja w pliku postgresql.conf:

Jest to główny plik konfiguracyjny. Dostosowanie `postgresql.conf`wraz z zastosowaniem dobrych praktyk umożliwia dostosowanie serwera do specyficznych potrzeb organizacji, zapewniając optymalne wykorzystanie zasobów systemowych, co przekłada się na lepszą wydajność i stabilność serwera. Ustawienia dotyczące logowania i monitorowania pozwalają na szybkie wykrywanie i reagowanie na nietypowe aktywności, co jest kluczowe w kontekście zapobiegania incydentom bezpieczeństwa. Szyfrowanie połączeń przy użyciu SSL oraz stosowanie silnych metod uwierzytelniania zabezpiecza dane przed podsłuchiwaniem i manipulacją podczas transmisji, co jest szczególnie ważne w środowiskach, gdzie bazy danych są dostępne zdalnie. 

listen_addresses: 
Ogranicza adresy IP, na których PostgreSQL będzie nasłuchiwać połączeń. 
Rekomendacja: Ustaw na konkretne adresy IP zamiast domyślnego '*’.  
listen_addresses = '127.0.0.1′ (tylko lokalne połączenia) lub  
listen_addresses = '192.168.1.100′ (konkretny adres IP serwera). 

port: 
Domyślny port dla PostgreSQL to 5432. 
Rekomendacja: Rozważ zmianę domyślnego portu na niestandardowy, aby utrudnić potencjalnym atakującym jego odnalezienie.  
port = 5433. 

ssl: 
Włącza obsługę SSL dla szyfrowanych połączeń. 
Rekomendacja: Włącz SSL.  
ssl = on. 

ssl_cert_file i ssl_key_file: 
Ścieżki do plików certyfikatu i klucza SSL. Upewnij się, że certyfikaty są aktualne i odpowiednio chronione.  

password_encryption: 
Określa, czy hasła użytkowników są szyfrowane. 
Możesz włączyć szyfrowanie hasłem  
password_encryption = scram-sha-256. 

log_connections: 
Loguje każde nowe połączenie do serwera. Warto włączyć logowanie połączeń, aby wiedzieć kto próbuje i skąd łączy się do naszej bazy.  
log_connections = on. 

log_disconnections: 
Loguje każde rozłączenie z serwerem. Warto włączyć logowanie rozłączeń podobnie jak ich nawiązywanie może nam to dać wiele cennych informacji czy nie są utrzymywanie niepotrzebnie gdzieś ciągłe sesje. 
log_disconnections = on. 

log_statement: 
Określa, które zapytania SQL są logowane. Loguj przynajmniej ddl (zapytania tworzące, zmieniające lub usuwające struktury bazy danych).  
log_statement = 'ddl’. 

log_duration: 
Loguje czas wykonania każdego zapytania. Włącz logowanie czasu trwania zapytań. log_duration = on. 

log_min_duration_statement: 
Loguje tylko te zapytania, które trwają dłużej niż określony czas (w ms). Ustaw na rozsądną wartość, aby identyfikować długotrwałe zapytania. log_min_duration_statement = 1000. 

client_min_messages: 
Określa minimalny poziom komunikatów wysyłanych do klienta. Ustaw na notice lub warning, aby zminimalizować ilość informacji wyciekających do użytkowników.  
client_min_messages = warning. 

log_min_messages: 
Określa minimalny poziom komunikatów logowanych przez serwer. Ustaw na error lub warning dla produkcyjnych systemów.  
log_min_messages = warning. 

shared_buffers: 
Ilość pamięci przydzielonej do buforów współdzielonych. Optymalizacja tego parametru może poprawić wydajność i odporność na ataki DDoS.  
shared_buffers = 25% ogólnej pamięci systemu. 

max_connections: 
Maksymalna liczba równoczesnych połączeń do serwera. Ustaw na rozsądną wartość, aby zapobiec wyczerpaniu zasobów systemowych.  
max_connections = 100. 

authentication_timeout: 
Czas oczekiwania na ukończenie procesu uwierzytelniania. Ustaw krótki czas, aby ograniczyć czas prób logowania.  
authentication_timeout = 1min. 

ssl_renegotiation_limit: 
Limit danych przesyłanych przed renegocjacją SSL. Ustaw na wysoką wartość, aby zmniejszyć częstotliwość renegocjacji. 
ssl_renegotiation_limit = 0 (wyłączenie). 

log_hostname: 
Logowanie nazw hostów zamiast adresów IP. Włącz, jeśli jest potrzeba logowania nazw hostów dla analizy.  
log_hostname = on. 

datestyle: 
Ustawienie formatu daty i czasu. Ustaw na bezpieczny format unikania dwuznaczności. datestyle = 'iso, mdy’. 

timezone: 
Ustawienie strefy czasowej serwera. Upewnij się, że strefa czasowa jest poprawna dla lokalizacji serwera.  

timezone = 'UTC’. 

Konfiguracja dla pliku pg_hba.conf:

Jest to plik konfiguracyjny PostgreSQL, który kontroluje, kto i w jaki sposób może łączyć się z serwerem bazy danych. Skrót HBA oznacza „Host-Based Authentication”. Plik `pg_hba.conf`, kontrolując kto i w jaki sposób może się połączyć z serwerem, stanowi pierwszą linię obrony przed nieautoryzowanym dostępem. Precyzyjne określenie adresów IP, z których można nawiązywać połączenia oraz stosowanie silnych metod uwierzytelniania takich jak `scram-sha-256` czy integracja z zewnętrznymi systemami uwierzytelniania, znacząco podnosi poziom bezpieczeństwa. Segmentacja sieci oraz ograniczenie dostępu tylko do zaufanych źródeł minimalizuje ryzyko dostępu przez osoby niepowołane. Ponadto, regularne przeglądy i aktualizacje tych konfiguracji zapewniają, że system jest odporny na nowe zagrożenia i spełnia aktualne wymagania bezpieczeństwa. 

Specyficzne adresy IP zamiast szerokich zakresów 
Używaj dokładnych adresów IP lub precyzyjnych zakresów zamiast ogólnych. 
Zamiast `0.0.0.0/0`, używaj precyzyjnych adresów IP.  

host all all 192.168.1.0/24 md5 

Lokalne połączenia 
Ogranicz dostęp do lokalnych połączeń tylko do niezbędnych użytkowników. Używaj `peer` dla lokalnych połączeń, aby wymagać systemowego uwierzytelnienia użytkowników.  

     local all postgres peer
local all all peer 

Szyfrowane połączenia (SSL) 
Wymuszaj szyfrowane połączenia dla zdalnych użytkowników.Dodaj np. `hostssl` zamiast `host`, aby wymusić SSL.  

hostssl all all 192.168.1.0/24 md5 

Minimalne uprawnienia  
Ustaw minimalne uprawnienia dla użytkowników i ról. Stosuj zasadę najmniejszych uprawnień 

     host nazwa_db user 192.168.1.0/24 md5 

Uwierzytelnianie zewnętrzne 
Używaj zewnętrznych mechanizmów uwierzytelniania, takich jak LDAP czy Kerberos, gdy jest to możliwe. Konfiguruj odpowiednie metody uwierzytelniania dla różnych środowisk.  

     host all all 0.0.0.0/0 ldap ldapserver=ldap.wladcysieci.pl
ldapbasedn=”dc=wladcysieci,dc=pl” 

Ograniczanie dostępu dla specyficznych baz danych 
Kontroluj, kto może uzyskać dostęp do konkretnych baz danych. Dodaj reguły dla specyficznych baz danych. Przykład: 

     host baza użytkownik 192.168.1.100/32 md5 

Ograniczenie metod uwierzytelniania 
Unikaj używania słabych metod uwierzytelniania, takich jak `trust`. Używaj mocniejszych metod, takich jak `md5` lub `scram-sha-256`. Przykład: 

     host all all 0.0.0.0/0 scram-sha-256 

Specyfikacja sieci IPv6 
Zabezpiecz również sieci IPv6, jeśli są używane. Dodaj reguły także dla IPv6 o których z reguły się zapomina 

     host all all ::1/128 scram-sha-256 
host all all fe80::/10 scram-sha-256 

Połączenia tylko z zaufanych sieci 
Ogranicz dostęp do serwera PostgreSQL tylko z zaufanych sieci. Używaj specyficznych reguł dla zaufanych sieci. 

     host all all 192.168.1.0/24 md5 

Testowanie konfiguracji 
– **Opis**: Po każdej zmianie testuj konfigurację, aby upewnić się, że działa zgodnie z oczekiwaniami. Używaj `pg_hba_check` lub narzędzi do testowania konfiguracji. 

pg_hba_check 

Podsumowanie

Zastosowanie się do powyższych reguł dotyczących konfiguracji plików `postgresql.conf` oraz `pg_hba.conf` ma istotne znaczenie dla zapewnienia bezpieczeństwa, stabilności i wydajności serwera PostgreSQL. Jak widać nie wystarczy jedynie zainstalować serwera, usługi i odciąć ruchu od sieci. W dzisiejszym środowisku IT, w którym zagrożenia cybernetyczne są coraz bardziej wyrafinowane, ochrona danych staje się priorytetem dla każdej organizacji. Prawidłowa konfiguracja tych plików pozwala na kontrolowanie dostępu do bazy danych, co zapobiega nieautoryzowanemu dostępowi i potencjalnym atakom. Zdaję jednak sobie sprawę, że powyższe nie wyczerpuje w całości tematu zabezpieczenia i hardeningu PostgreSQL’a. Jest na pewno dobrym punktem wyjścia.