Basis data MySQL saya membutuhkan dua pengguna: pengguna aplikasi dan dukungan.
Salah satu pengembang aplikasi bersikeras bahwa saya membuat empat akun untuk pengguna ini:
appuser@'%'
appuser@'localhost'
support@'%'
support@'localhost'
Demi kehidupanku, aku tidak tahu mengapa menurutnya kita membutuhkan ini. Tidakkah menggunakan wildcard sebagai tuan rumah akan mengurus 'localhost'?
Ada ide?
(Menggunakan MySQL 5.5 di sini)
Seperti yang ditunjukkan @nos di komentar dari jawaban yang diterima saat ini untuk pertanyaan ini, jawaban yang diterima salah.
Ya, ada perbedaan antara menggunakan
%
danlocalhost
untuk host akun pengguna saat menyambungkan melalui sambungan soket, bukan sambungan TCP / IP standar.Nilai host
%
tidak termasuklocalhost
untuk soket dan karenanya harus ditentukan jika Anda ingin menyambung menggunakan metode itu.sumber
Mari kita uji.
Hubungkan sebagai superuser, lalu:
SHOW VARIABLES LIKE "%version%"; +-------------------------+------------------------------+ | Variable_name | Value | +-------------------------+------------------------------+ | version | 10.0.23-MariaDB-0+deb8u1-log |
lalu
USE mysql;
Mendirikan
Buat pengguna
foo
dengan kata sandibar
untuk pengujian:CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
Menghubung
Untuk menyambung ke Soket Domain Unix (yaitu pipa I / O yang diberi nama oleh entri sistem file
/var/run/mysqld/mysqld.sock
atau semacamnya), jalankan ini pada baris perintah (gunakan--protocol
opsi untuk memastikan ganda)mysql -pbar -ufoo mysql -pbar -ufoo --protocol=SOCKET
Orang mengharapkan bahwa kecocokan di atas "pengguna berasal dari localhost" tetapi tentu saja bukan "pengguna berasal dari 127.0.0.1".
Untuk menyambung ke server dari "127.0.0.1" sebagai gantinya, jalankan ini di baris perintah
mysql -pbar -ufoo --bind-address=127.0.0.1 --protocol=TCP
Jika Anda keluar
--protocol=TCP
,mysql
perintah akan tetap mencoba menggunakan soket domain Unix. Anda juga bisa mengatakan:mysql -pbar -ufoo --bind-address=127.0.0.1 --host=127.0.0.1
Dua upaya koneksi dalam satu baris:
export MYSQL_PWD=bar; \ mysql -ufoo --protocol=SOCKET --execute="SELECT 1"; \ mysql -ufoo --bind-address=127.0.0.1 --host=127.0.0.1 --execute="SELECT 1"
(kata sandi diatur di lingkungan sehingga diteruskan ke
mysql
proses)Verifikasi Jika Ada Keraguan
Untuk benar-benar memeriksa apakah koneksi berjalan melalui soket TCP / IP atau soket Domain Unix
ps faux
lsof -n -p<yourpid>
.Anda akan melihat sesuatu seperti:
atau
Begitu:
Kasus 0: Host = '10 .10.10.10 '(tes nol)
update user set host='10.10.10.10' where user='foo'; flush privileges;
Kasus 1: Host = '%'
update user set host='%' where user='foo'; flush privileges;
Kasus 2: Host = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
Perilaku bervariasi dan ini tampaknya tergantung
skip-name-resolve
. Jika disetel, menyebabkan baris denganlocalhost
diabaikan menurut log. Berikut ini dapat dilihat di log kesalahan: "'entri pengguna' root @ localhost 'diabaikan dalam mode - lewati-nama-penyelesaian." . Ini berarti tidak ada koneksi melalui Unix Domain Socket. Tetapi secara empiris tidak demikian.localhost
sekarang berarti HANYA Soket Domain Unix, dan tidak lagi cocok dengan 127.0.0.1.skip-name-resolve
tidak aktif:skip-name-resolve
pada:Kasus 3: Host = '127.0.0.1'
update user set host='127.0.0.1' where user='foo';flush privileges;
Kasus 4: Host = ''
update user set host='' where user='foo';flush privileges;
(Menurut MySQL 5.7: 6.2.4 Access Control, Tahap 1: Verifikasi Koneksi , String kosong '' juga berarti "sembarang host" tetapi diurutkan setelah '%'. )
Kasus 5: Host = '192.168.0.1' (tes ekstra)
('192.168.0.1' adalah salah satu alamat IP mesin saya, ubah dengan tepat dalam kasus Anda)
update user set host='192.168.0.1' where user='foo';flush privileges;
tapi
mysql -pbar -ufoo -h192.168.0.1
: OK (!)Yang terakhir karena ini sebenarnya berasal dari koneksi TCP
192.168.0.1
, seperti yang diungkapkan olehlsof
:Kasus Tepi A: Host = '0.0.0.0'
update user set host='0.0.0.0' where user='foo';flush privileges;
Kasus Tepi B: Host = '255.255.255.255'
update user set host='255.255.255.255' where user='foo';flush privileges;
Kasus Tepi C: Host = '127.0.0.2'
(127.0.0.2 adalah alamat loopback yang benar-benar valid, setara dengan 127.0.0.1 seperti yang didefinisikan dalam RFC6890 )
update user set host='127.0.0.2' where user='foo';flush privileges;
Menariknya:
mysql -pbar -ufoo -h127.0.0.2
terhubung dari127.0.0.1
dan KEGAGALANmysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
OKMembersihkan
delete from user where user='foo';flush privileges;
Tambahan
Untuk melihat apa yang sebenarnya ada di
mysql.user
tabel, yang merupakan salah satu tabel izin, gunakan:SELECT SUBSTR(password,1,6) as password, user, host, Super_priv AS su, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) AS funcs, CONCAT(Repl_slave_priv, Repl_client_priv) AS replic, CONCAT(Shutdown_priv, Process_priv, File_priv, Show_db_priv, Reload_priv, Create_user_priv) AS admin FROM user ORDER BY user, host;
ini memberi:
+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin | +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ | *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN |
Demikian pula untuk tabel
mysql.db
:SELECT host,db,user, Grant_priv as gr, CONCAT(Select_priv, Lock_tables_priv) AS selock, CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, CONCAT(References_priv, Index_priv, Alter_priv) AS ria, CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv) AS funcs FROM db ORDER BY user, db, host;
sumber
Jika Anda ingin terhubung
user@'%'
dari penggunaan localhostmysql -h192.168.0.1 -uuser -p
.sumber
Akan memberikan jawaban yang sedikit berbeda dengan yang diberikan sejauh ini.
Jika Anda memiliki baris untuk pengguna anonim dari localhost di tabel users Anda
''@'localhost'
maka ini akan diperlakukan sebagai lebih spesifik daripada pengguna Anda dengan host wildcard'user'@'%'
. Inilah mengapa perlu juga menyediakan'user'@'localhost'
.Anda dapat melihat penjelasan ini lebih detail di bagian bawah halaman ini .
sumber
Simbol persen berarti: semua host, termasuk koneksi jarak jauh dan lokal.
Localhost hanya mengizinkan koneksi lokal.
(jadi untuk memulai, jika Anda tidak memerlukan koneksi jarak jauh ke database Anda, Anda dapat langsung menyingkirkan pengguna appuser @ '%')
Jadi, ya, mereka tumpang tindih, tapi ...
... ada alasan untuk menyetel kedua jenis akun, ini dijelaskan di dokumen mysql: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html .
Jika Anda memiliki pengguna anonim di localhost Anda, yang dapat Anda temukan dengan:
select Host from mysql.user where User='' and Host='localhost';
dan jika Anda hanya membuat pengguna appuser @ '%' (dan Anda bukan appuser @ 'localhost'), maka ketika pengguna appuser mysql terhubung dari host lokal, akun pengguna anonim digunakan (ini lebih diutamakan daripada pengguna aplikasi Anda @ '%' pengguna).
Dan perbaikan untuk ini adalah (seperti yang bisa ditebak) dengan membuat appuser @ 'localhost' (yang lebih spesifik daripada pengguna anonim host lokal dan akan digunakan jika pengguna aplikasi Anda terhubung dari localhost).
sumber