Serwer odpowiada pustym pakietem podczas negocjacji sesji, co powoduje, że klient podaje nieprawidłowy błąd pakietu

14

Próbuję połączyć się ze zdalnym serwerem mysql. Dzieje się tak w 100% przypadków.

klient: mysql Ver 14.14 Distrib 5.7.12, dla Win32 (AMD64)
serwera : 5.0.95

To jest błąd, który otrzymuję:

C:\>mysql -h example.com -P 3306 -D prod_rcadb -u username -p
Enter password: **********
ERROR 2027 (HY000): Malformed packet

ten sam błąd z mysqladmin:

C:\>mysqladmin -h example.com -P 3306 -u username -p version
Enter password: **********
mysqladmin: connect to server at '10.106.24.79' failed
error: 'Malformed packet'

Więc wziąłem pcap, żeby dowiedzieć się, jak wyglądała ta rozmowa.

Uzgadnianie TCP:

1              2016-04-14 11:18:48.910690         0.000000              137.69.150.80                     10.106.24.79       TCP        66                511573306 [SYN] Seq=0 Win=8192 Len=0 MSS=1428 WS=256 SACK_PERM=1   8192
2              2016-04-14 11:18:49.019893         0.109203              10.106.24.79                       137.69.150.80     TCP        66                330651157 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460 SACK_PERM=1 WS=256           5840
3              2016-04-14 11:18:49.019893         0.000000              137.69.150.80                     10.106.24.79       TCP        54                511573306 [ACK] Seq=1 Ack=1 Win=65536 Len=0          256

Negocjacja połączenia MySQL:

4              2016-04-14 11:18:49.144696         0.124803              10.106.24.79                       137.69.150.80     MySQL  110        Server Greeting proto=10 version=5.0.95            23
5              2016-04-14 11:18:49.144696         0.000000              137.69.150.80                     10.106.24.79       MySQL  119         Login Request user=bigdata   256<br>
6              2016-04-14 11:18:49.144696         0.000000              10.106.24.79                       137.69.150.80     TCP        60                330651157 [ACK] Seq=57 Ack=66 Win=5888 Len=0        23
7              2016-04-14 11:18:49.316301         0.171605              10.106.24.79                       137.69.150.80     MySQL  60           Response                23

Tak więc klient łączy się na poziomie TCP, serwer wita nas obsługiwanymi opcjami i statusem:

Server Capabilities: 0xa22c
.... .... .... ...0 = Long Password: Not set
.... .... .... ..0. = Found Rows: Not set
.... .... .... .1.. = Long Column Flags: Set
.... .... .... 1... = Connect With Database: Set
.... .... ...0 .... = Don't Allow database.table.column: Not set
.... .... ..1. .... = Can use compression protocol: Set
.... .... .0.. .... = ODBC Client: Not set
.... .... 0... .... = Can Use LOAD DATA LOCAL: Not set
.... ...0 .... .... = Ignore Spaces before '(': Not set
.... ..1. .... .... = Speaks 4.1 protocol (new flag): Set
.... .0.. .... .... = Interactive Client: Not set
.... 0... .... .... = Switch to SSL after handshake: Not set
...0 .... .... .... = Ignore sigpipes: Not set
..1. .... .... .... = Knows about transactions: Set
.0.. .... .... .... = Speaks 4.1 protocol (old flag): Not set
1... .... .... .... = Can do 4.1 authentication: Set
Server Language: latin1 COLLATE latin1_swedish_ci (8)

Klient prosi o login:

.... .... .... ...1 = Long Password: Set
.... .... .... ..0. = Found Rows: Not set
.... .... .... .1.. = Long Column Flags: Set
.... .... .... 0... = Connect With Database: Not set
.... .... ...0 .... = Don't Allow database.table.column: Not set
.... .... ..0. .... = Can use compression protocol: Not set
.... .... .0.. .... = ODBC Client: Not set
.... .... 1... .... = Can Use LOAD DATA LOCAL: Set
.... ...0 .... .... = Ignore Spaces before '(': Not set
.... ..1. .... .... = Speaks 4.1 protocol (new flag): Set
.... .0.. .... .... = Interactive Client: Not set
.... 0... .... .... = Switch to SSL after handshake: Not set
...0 .... .... .... = Ignore sigpipes: Not set
..1. .... .... .... = Knows about transactions: Set
.0.. .... .... .... = Speaks 4.1 protocol (old flag): Not set
1... .... .... .... = Can do 4.1 authentication: Set
Extended Client Capabilities: 0x81be
.... .... .... ...0 = Multiple statements: Not set
.... .... .... ..1. = Multiple results: Set
.... .... .... .1.. = PS Multiple results: Set
.... .... .... 1... = Plugin Auth: Set
.... .... ...1 .... = Connect attrs: Set
.... .... ..1. .... = Plugin Auth LENENC Client Data: Set
.... .... 1... .... = Session variable tracking: Set
1000 0001 .0.. .... = Unused: 0x0204

Serwer potwierdza, a następnie wysyła odpowiedź, która jest zasadniczo pusta…

Packet Length: 1
Packet Number: 2
EOF marker: 254

A to natychmiast powoduje, że klient FIN i zamknąć gniazdo:

8              2016-04-14 11:18:49.316301         0.000000              137.69.150.80                     10.106.24.79       TCP        54                511573306 [FIN, ACK] Seq=66 Ack=62 Win=65536 Len=0            256
9              2016-04-14 11:18:49.332901         0.016600              10.106.24.79                       137.69.150.80     TCP        60                330651157 [ACK] Seq=62 Ack=67 Win=5888 Len=0        23
10           2016-04-14 11:18:49.391904         0.059003              10.106.24.79                       137.69.150.80     TCP        60                330651157 [FIN, ACK] Seq=62 Ack=67 Win=5888 Len=0              23
11           2016-04-14 11:18:49.391904         0.000000              137.69.150.80                     10.106.24.79       TCP        54                511573306 [ACK] Seq=67 Ack=63 Win=65536 Len=0     256

Tak więc łączący się klient nie spodobał się ten pusty pakiet wysłany przez serwer.

Nie otrzymuję tego przeciwko innemu serwerowi mysql w tej samej wersji od tego samego klienta. Oto pakiet odpowiedzi na żądanie logowania z serwera 2:

Packet Length: 7
Packet Number: 2
Affected Rows: 0
Server Status: 0x0002
.... .... .... ...0 = In transaction: Not set
.... .... .... ..1. = AUTO_COMMIT: Set
.... .... .... .0.. = More results: Not set
.... .... .... 0... = Multi query - more resultsets: Not set
.... .... ...0 .... = Bad index used: Not set
.... .... ..0. .... = No index used: Not set
.... .... .0.. .... = Cursor exists: Not set
.... .... 0... .... = Last row sent: Not set
.... ...0 .... .... = database dropped: Not set
.... ..0. .... .... = No backslash escapes: Not set
.... .0.. .... .... = Session state changed: Not set
.... 0... .... .... = Query was slow: Not set
...0 .... .... .... = PS Out Params: Not set

Nie administruję tym plikiem db, ale jeśli masz sugestie dotyczące rzeczy, które należy szukać w dziennikach, mogę poprosić o te informacje.

Masz jakieś przemyślenia na temat tego, dlaczego otrzymuję pusty pakiet z serwera?

MaQleod
źródło

Odpowiedzi:

13

Pakiet, o którym myślałem, że jest pusty, tak naprawdę nie był, był to wniosek o zmianę starego uwierzytelniania :

Payload
1     [fe]
Fields
status (1) -- 0xfe
Returns
Protocol::AuthSwitchResponse with old password hash
Example
01 00 00 02 fe

1, 2, 254 przeanalizowane przez wireshark to tak naprawdę 01 00 00 02 fe, jeśli spojrzysz na rzeczywiste ciągi bajtów.

Więc nie chodzi o nieporozumienie, serwer rozumie całkowicie i poprawnie reaguje, a klient poprawnie kończy, ponieważ nie może negocjować w dół. Protokół nie jest zbyt stary, ponieważ został zmieniony w 4.1, więc zarówno 5.0, jak i 5.7 doskonale się rozumieją. Powinien to być wyraźniejszy komunikat o błędzie.

Klient jest zbyt nowy, aby używać --skip-secure-auth ( odniesienie ). Celowo usunęli możliwość negocjacji w dół przed 5.7.

Moje opcje to zezwolenie na nowe hasła na serwerze (która jest konfiguracją specyficzną dla użytkownika, a nie globalna opcja serwera) lub użycie starszego pliku binarnego.

Konkretny problem z konfiguracją opiera się na podanej przeze mnie nazwie użytkownika. W pewnym momencie w przeszłości ktoś używający tej nazwy użytkownika korzystał ze starszego klienta i zmienił metodę hasła :

B.5.2.4 Client does not support authentication protocol

The current implementation of the authentication protocol uses a password hashing algorithm that is incompatible with that used by older (pre-4.1) clients. Attempts to connect to a 4.1 or newer server with an older client may fail with the following message:

shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

To deal with this problem, the preferred solution is to upgrade all client programs to use a 4.1.1 or newer client library. If that is not possible, use one of the following approaches:

    To connect to the server with a pre-4.1 client program, use an account that still has a pre-4.1-style password.

    Reset the password to pre-4.1 style for each user that needs to use a pre-4.1 client program. This can be done using the SET PASSWORD statement and the OLD_PASSWORD() function. As of MySQL 5.6.6, it is also necessary to first ensure that the authentication plugin for the account is mysql_old_password:

    mysql> UPDATE mysql.user SET plugin = 'mysql_old_password'
    mysql> WHERE User = 'some_user' AND Host = 'some_host';
    mysql> FLUSH PRIVILEGES;
    mysql> SET PASSWORD FOR
        -> 'some_user'@'some_host' = OLD_PASSWORD('new_password');
MaQleod
źródło
2

Wystąpił ten błąd podczas próby połączenia ze starszym serwerem MySQL @@old_passwords włączoną funkcją. Korzystam z mysql-client v5.7.19 i wersji Server: 5.1.73.

Rozwiązałem problem, ręcznie tworząc skrót hash MySQL SHA1 (używając programu, który napisałem w tym celu), a następnie uruchomiłem polecenie na serwerze:

SET PASSWORD FOR 'nagios'@'10.10.10.201' = 'xxxx';

(Gdzie xxxxwłaściwie był skrót).

Alastair Irvine
źródło
to zadziałało dla mnie! Możesz wygenerować te skróty haseł na serwerze MySQL 5.5 / 5.6 / 5.7 za pomocą: SELECT PASSWORD('abc');Lub użyj generatora online, takiego jak: browserling.com/tools/mysql-password
Jeroen