Nie można połączyć się z mysql przy użyciu samopodpisanego certyfikatu SSL

15

Po utworzeniu samopodpisanego certyfikatu SSL skonfigurowałem mój zdalny serwer MySQL, aby z nich korzystał (a protokół SSL jest włączony)

Przesyłam ssh do mojego zdalnego serwera i próbuję połączyć się z własnym mysqld za pomocą SSL (serwer MySQL to 5.5.25).

mysql -u <user> -p --ssl=1 --ssl-cert=client.cert --ssl-key=client.key --ssl-ca=ca.cert
Enter password: 
ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)

Ok, pamiętam, że przeczytałem problem z połączeniem się z tym samym serwerem przez SSL. Więc pobieram klucze klienta do mojej skrzynki lokalnej i testuję stamtąd ...

mysql -h <server> -u <user> -p --ssl=1 --ssl-cert=client.cert --ssl-key=client.key --ssl-ca=ca.cert 
Enter password: 
ERROR 2026 (HY000): SSL connection error

Nie jest jasne, do czego odnosi się ten błąd „Błąd połączenia SSL”, ale jeśli go pominę -ssl-ca, będę mógł połączyć się za pomocą SSL.

mysql -h <server> -u <user> -p --ssl=1 --ssl-cert=client.cert --ssl-key=client.key 
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 5.5.25 MySQL Community Server (GPL)

Uważam jednak, że jest to tylko szyfrowanie połączenia, a nie weryfikacja ważności certyfikatu (co oznacza, że ​​byłbym potencjalnie narażony na atak man-in-middle)

Certyfikaty SSL są ważne (choć podpisane przez siebie) i nie zawierają hasła. Więc moje pytanie brzmi: co robię źle? Jak mogę połączyć się przez SSL, używając certyfikatu z podpisem własnym?

Wersja MySQL Server to 5.5.25, a serwer i klienci to CentOS 5.

Dziękuję za wszelkie porady

Edycja : Zauważ, że we wszystkich przypadkach polecenie jest wydawane z tego samego katalogu, w którym znajdują się klucze ssl (stąd brak ścieżki bezwzględnej)

Edycja (w odpowiedzi na mgorven): ca.certto certyfikat ośrodka certyfikacji, który powinien informować mysql, że mój ośrodek certyfikacji jest zaufany.

Konfiguracja z my.cnfjest

[mysqld]
ssl-ca=/etc/ssl/mysql/ca.cert
ssl-cert=/etc/ssl/mysql/server.cert
ssl-key=/etc/ssl/mysql/server.key

Próbowałem również dodać, ssl-cipher=DHE-RSA-AES256-SHAale od tego czasu go usunąłem, ponieważ nie pomogło.

carpii
źródło
2
Co to jest ca.cert? Czy jest to samopodpisany certyfikat serwera? Czy używasz certyfikatów klienta do uwierzytelniania? Podaj konfigurację związaną z SSL na serwerze.
mgorven
Dzięki, zaktualizowałem moje pytanie o odpowiedź i konfigurację ssl z serwera. Certyfikaty przekazywane w wierszu poleceń podczas próby połączenia są rzeczywiście certyfikatami klientów.
carpii
W rzeczywistości to dobre pytanie. Z perspektywy czasu nie jestem pewien, czy klient powinien określać serwery ssl-ca. Ale potem bez Im pod impresją zaszyfrowane połączenie nie jest ściśle uwierzytelnione
carpii

Odpowiedzi:

12

Tak, masz rację, że jeśli nie określisz, --ssl-caklient w ogóle nie sprawdzi certyfikatu serwera. Ponieważ działa bez tej opcji, najbardziej prawdopodobną przyczyną niepowodzenia jest to, że klient nie ufa certyfikatowi serwera.

Jeśli używasz samopodpisanych certyfikatów klienta i serwera, ca.certplik powinien zawierać oba te pliki. W ten sposób klient będzie ufał certyfikatowi serwera, a serwer będzie ufał certyfikatowi klienta.

Na przykład:
Wygeneruj klucz serwera i certyfikat:

$ openssl req -x509 -newkey rsa:1024 \
         -keyout server-key-enc.pem -out server-cert.pem \
         -subj '/DC=com/DC=example/CN=server' -passout pass:qwerty

$ openssl rsa -in server-key-enc.pem -out server-key.pem \
         -passin pass:qwerty -passout pass:

Wygeneruj klucz klienta i certyfikat:

$ openssl req -x509 -newkey rsa:1024 \
         -keyout client-key-enc.pem -out client-cert.pem \
         -subj '/DC=com/DC=example/CN=client' -passout pass:qwerty

$ openssl rsa -in client-key-enc.pem -out client-key.pem \
         -passin pass:qwerty -passout pass:

Połącz certyfikaty klienta i serwera w plik certyfikatów urzędu certyfikacji:

$ cat server-cert.pem client-cert.pem > ca.pem
Keith Burdis
źródło
Dziękuję bardzo! Brakującym krokiem jest to, że nie łączyłem certyfikatów serwera i klienta w ca.pem. Zamiast tego przekazałem ca.cert, który został wygenerowany początkowo (a następnie przekazałem jako - klucz CA podczas generowania certyfikatów klienta i serwera)
carpii
Dziwne, ale zawsze działało dla mnie z jednym certyfikatem CA - takim samym na kliencie i serwerze.
Dmitry Leskov
Tak, o ile nie ma specjalnych wymagań dla nazwy wyróżniającej - na przykład CN mającej określoną wartość - można używać tego samego klucza i samopodpisanego certyfikatu na kliencie i serwerze.
Keith Burdis,
3

Aby użyć jednokierunkowego ssl, powinieneś spróbować z:

mysql -u <user> -p --ssl=1 --ssl-ca=ca.cert --ssl-verify-server-cert

--ssl-certI --ssl-keyna kliencie mysql służą do 2 way SSL. Oznacza to uwierzytelnianie oparte na certyfikatach. Przedmiotem certyfikatu klienta powinna być nazwa użytkownika.

Mircea Vutcovici
źródło
2
Należy również pamiętać, że podczas nawiązywania połączenia przez gniazdo i używania --ssl-verify-server-certCN certyfikatu serwera musi być taki sam, jak host podany dla opcji wiersza polecenia -h.
Keith Burdis,
0

Czy przypadkiem nie wprowadziłeś tej samej nazwy zwyczajowej dla certyfikatów serwera i klienta? Jeśli tak, wymień jedną z nich, aby nazwy wspólne były różne.

Dmitrij Leskow
źródło
Dla mnie rozwiązanie Dmitrija Leskowa działało. Zgodnie z dokumentacją SSL MySQL: ( dev.mysql.com/doc/refman/5.0/en/creating-ssl-certs.html )> Niezależnie od metody użytej do wygenerowania certyfikatu i plików kluczy, wartość Common Name używana dla serwera i certyfikaty / klucze klienta muszą różnić się od wartości Common Name użytej dla certyfikatu CA. W przeciwnym razie pliki certyfikatów i kluczy nie będą działać dla serwerów skompilowanych przy użyciu OpenSSL. Typowy błąd w tym przypadku to: BŁĄD 2026 (HY000): Błąd połączenia SSL: błąd: 00000001: lib (0): func (0): powód (1)
gmas