Wpisy otagowane ‘C API’

Bezpieczne połączenia z MySQL (C API)

niedziela, 10 Sierpień 2008

Ostatnio coraz więcej kodu w C piszę z użyciem MySQL API, a że dane przy jednym z projektów są poufne i serwer nie jest lokalny, przyjrzałem się połączeniom SSL. W zasadzie po stronie kodu to nic wielkiego – wystarczy wywołać mysql_ssl_set() przed mysql_real_connect() (mysql_connect() jest deprecated). Oczywiście pod warunkiem, że klient jest skompilowany ze wsparciem OpenSSL (lub yaSSL, ale nigdy nie testowałem).

Uruchomienie samego serwera (również przy założeniu, że skompilowany ze wsparciem SSL) sprowadza się do podania dodatkowych parametrów w linii komend. Przykładowo może to wyglądać tak:

mysqld --defaults-file=/etc/mysql/my.cnf --ssl --ssl-ca=</path/to/CA.crt> --ssl-cert=</path/to/file.crt> --ssl-key=</path/to/file.key>

Ewentualnie odpowiednie parametry podać w pliku konfiguracyjnym (my.cnf):

ssl-ca = </path/to/CA.crt>
ssl-cert =</path/to/file.crt>
ssl-key =</path/to/file.key>

Pamiętać należy, że w przypadku, gdy certyfikat jest zabezpieczony hasłem, MySQL może być jedynie uruchomiony ręcznie. Korzystając ze skryptów startowych (na pewno w Gentoo Linux) czy nawet wrzucając proces w tło (&) serwer nie skorzysta z certyfikatu i nie nawiążemy szyfrowanej transmisji. Próba takiego uruchomienia zakończy się podobnym wpisem w logach:

[Warning] Failed to setup SSL

Testowe połączenie do serwera z konsoli mysql możemy wykonać podając jedynie ścieżkę do certyfikatu CA (format PEM), np.

mysql -h <host> -u <user> -p --ssl-ca=</path/to/CA.crt> <database>

Wywołując STATUS możemy sprawdzić czy bieżące połączenie ma wsparcie SSL:

SSL:            Cipher in use is DHE-RSA-AES256-SHA

czy też nie:

SSL:            Not in use

Wymuszanie szyfrowanych połączeń możliwe tylko poprzez REQUIRE SSL przy nadawaniu praw użytkownikowi (GRANT). W takim przypadku połączenie bez SSL zakończy się komunikatem podobnym jak w przypadku np. podania błędnego hasła:

ERROR 1045 (28000): Access denied for user 'exg'@'192.168.1.101' (using p assword: YES)

Więcej o używaniu SSL w MySQL można poczytać tutaj:

Wracając do samej funkcji mysql_ssl_set(), to jako parametry przyjmuje: uchwyt połączenia zwrócony przez mysql_init(), ścieżkę do pliku klucza, certyfikatu i certyfikatu CA oraz ścieżkę do katalogu z certyfikatami CA w formacie PEM, a także listę wspieranych algorytmów.
Nieużywane parametry powinny przyjmować wartość NULL.
Funkcja zawsze zwraca 0, o błędach SSL informuje mysql_real_connect().

ERROR 2026 (HY000): SSL connection error

Na koniec łyżka dziegciu – libmysql (i klient mysql) dla Windows (ten z binarnej paczki) nie jest skompilowany z obsługą SSL. Aby korzystać z bezpiecznych połączeń należy pobrać źródła i samodzielnie dokonać kompilacji. Mi się nie udało… Może przez zbyt stare Visual C++.