Der Server antwortet während der Sitzungsaushandlung mit einem leeren Paket, was dazu führt, dass der Client einen fehlerhaften Paketfehler ausgibt

14

Ich versuche, eine Verbindung zu einem Remote-MySQL-Server herzustellen. Dies geschieht zu 100%.

client: mysql Ver 14.14 Distrib 5.7.12, für Win32 (AMD64)
server: 5.0.95

Dies ist der Fehler, den ich erhalte:

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

Gleicher Fehler bei 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'

Also nahm ich mir einen Moment Zeit, um eine Vorstellung davon zu bekommen, wie diese Unterhaltung aussah.

TCP-Handshake:

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

MySQL-Verbindungsverhandlung:

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

Der Client verbindet sich also auf TCP-Ebene, der Server begrüßt uns mit den unterstützten Optionen und dem Status:

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)

Client fordert ein Login an:

.... .... .... ...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

Der Server bestätigt und sendet dann eine Antwort, die im Wesentlichen leer ist.

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

Und das führt sofort dazu, dass der Client FIN ausführt und den Socket schließt:

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

Der verbindende Client mochte das leere Paket, das der Server gesendet hatte, nicht.

Ich bekomme dies nicht gegen einen anderen MySQL-Server der gleichen Version vom gleichen Client. Hier ist das Antwortpaket auf die Anmeldeanforderung von Server 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

Ich verwalte diese Datenbank nicht selbst, aber wenn Sie Vorschläge für Dinge haben, nach denen Sie in Protokollen suchen sollten, kann ich diese Informationen anfordern.

Irgendwelche Gedanken darüber, warum ich ein leeres Paket vom Server zurückbekomme?

MaQleod
quelle

Antworten:

13

Das Paket, von dem ich dachte, dass es leer ist, war eigentlich kein altes Auth-Switch-Request :

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

Die 1, 2, 254, die wireshark analysiert hat, ist tatsächlich 01 00 00 02, wenn Sie sich die tatsächlichen Byte-Strings ansehen.

Es ist also nicht so, dass es ein Missverständnis gibt, der Server versteht es vollständig und reagiert richtig und der Client wird korrekt beendet, da er nicht aushandeln kann. Das Protokoll ist nicht zu alt, da es in 4.1 geändert wurde, sodass beide Versionen 5.0 und 5.7 sich perfekt verstehen. Dies sollte eine deutlichere Fehlermeldung sein.

Der Client ist zu neu, um --skip-secure-auth ( Referenz ) zu verwenden. Sie haben absichtlich die Fähigkeit entfernt, vor 5.7 zu verhandeln.

Daher habe ich die Möglichkeit, neue Kennwörter auf dem Server zuzulassen (dies ist eine benutzerspezifische Konfiguration, keine globale Serveroption) oder eine ältere Binärdatei zu verwenden.

Das spezifische Konfigurationsproblem basiert auf dem Benutzernamen, den ich erhalten habe. Irgendwann in der Vergangenheit hat jemand, der diesen Benutzernamen verwendet, einen älteren Client verwendet und die Kennwortmethode geändert :

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
quelle
2

Ich habe diese Fehlermeldung erhalten, als ich versucht habe, eine Verbindung zu einem älteren MySQL-Server mit @@old_passwordsaktivierter Funktion herzustellen. Ich benutze MySQL-Client v5.7.19 und Server-Version: 5.1.73.

Ich habe das Problem behoben, indem ich manuell einen MySQL SHA1-Passwort-Hash erstellt habe (mit einem Programm, das ich zu diesem Zweck geschrieben habe) und dann diesen Befehl auf dem Server ausgeführt habe:

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

(Wo xxxxwar eigentlich der Hash.)

Alastair Irvine
quelle