Server merespons dengan paket kosong selama negosiasi sesi sehingga klien memberikan kesalahan paket yang salah

14

Saya mencoba untuk terhubung ke server mysql jarak jauh. Ini terjadi 100% dari waktu.

client: mysql Ver 14.14 Distrib 5.7.12, untuk
server Win32 (AMD64) : 5.0.95

Ini adalah kesalahan yang saya dapatkan:

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

kesalahan yang sama dengan 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'

Jadi saya mengambil pcap, hanya untuk mengetahui seperti apa percakapan itu.

Jabat tangan 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

Negosiasi koneksi 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

Jadi klien terhubung di tingkat TCP, server menyambut kami dengan opsi dan status yang didukung:

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)

Klien meminta 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

Server mengakui, lalu mengirim respons, yang pada dasarnya kosong ...

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

Dan itu segera menyebabkan klien FIN dan menutup soket:

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

Jadi klien yang terhubung tidak suka paket kosong yang dikirim server.

Saya tidak mendapatkan ini terhadap server mysql lain dari versi yang sama dari klien yang sama. Berikut adalah paket respons terhadap permintaan masuk dari 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

Saya sendiri tidak mengelola db ini, tetapi jika Anda memiliki saran untuk hal-hal yang harus dicari dalam log, saya dapat meminta informasi itu.

Adakah pemikiran mengapa saya mendapatkan paket kosong kembali dari server?

MaQleod
sumber

Jawaban:

13

Paket yang saya pikir kosong sebenarnya tidak, itu adalah Permintaan Auth Switch Lama :

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

The 1, 2, 254 yang diuraikan wireshark sebenarnya 01 00 00 02 fe jika Anda melihat string byte yang sebenarnya.

Jadi bukan karena ada kesalahpahaman, server memahami sepenuhnya dan benar merespons dan klien dengan benar berakhir karena tidak dapat dinegosiasikan ke bawah. Protokolnya tidak terlalu tua seperti yang diubah pada 4.1, sehingga baik 5.0 dan 5.7 saling memahami dengan sempurna. Ini harus menjadi pesan kesalahan yang lebih jelas.

Klien terlalu baru untuk menggunakan --skip-secure-auth ( referensi ). Mereka dengan sengaja menghilangkan kemampuan untuk bernegosiasi sebelum 5.7.

Jadi pilihan saya adalah memperbolehkan kata sandi baru di server (yang merupakan konfigurasi khusus pengguna, bukan opsi server global) atau menggunakan biner yang lebih lama.

Masalah konfigurasi khusus didasarkan pada nama pengguna yang saya berikan. Di masa lalu, seseorang yang menggunakan nama pengguna ini menggunakan klien yang lebih lama dan mereka mengubah metode kata sandi :

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

Saya mendapatkan kesalahan ini ketika mencoba terhubung ke server MySQL yang lebih lama dengan @@old_passwordsdiaktifkan. Saya menggunakan mysql-client v5.7.19 dan versi Server: 5.1.73.

Saya memperbaiki masalah dengan secara manual membuat hash kata sandi MySQL SHA1 (menggunakan program yang saya tulis untuk tujuan itu) dan kemudian saya menjalankan perintah ini di server:

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

(Di mana xxxxsebenarnya hash.)

Alastair Irvine
sumber