ลองทดสอบดู
เชื่อมต่อเป็น superuser จากนั้น:
SHOW VARIABLES LIKE "%version%";
+
| Variable_name | Value |
+
| version | 10.0.23-MariaDB-0+deb8u1-log |
แล้ว
USE mysql;
ติดตั้ง
สร้างผู้ใช้foo
ด้วยรหัสผ่านbar
สำหรับการทดสอบ:
CREATE USER foo@'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES;
เชื่อมต่อ
ในการเชื่อมต่อกับ Unix Domain Socket (เช่นไปป์ I / O ที่ตั้งชื่อโดยรายการระบบไฟล์/var/run/mysqld/mysqld.sock
หรือบางส่วน) ให้รันสิ่งนี้ในบรรทัดคำสั่ง (ใช้--protocol
ตัวเลือกเพื่อให้แน่ใจเป็นสองเท่า)
mysql -pbar -ufoo
mysql -pbar -ufoo
เราคาดหวังว่าการจับคู่ข้างต้น "ผู้ใช้มาจาก localhost" แต่ไม่ใช่ "ผู้ใช้มาจาก 127.0.0.1"
หากต้องการเชื่อมต่อกับเซิร์ฟเวอร์จาก "127.0.0.1" แทนให้เรียกใช้สิ่งนี้ในบรรทัดคำสั่ง
mysql -pbar -ufoo
หากคุณไม่--protocol=TCP
ใช้mysql
คำสั่งจะยังคงพยายามใช้ซ็อกเก็ตโดเมน Unix คุณยังสามารถพูดว่า:
mysql -pbar -ufoo
การเชื่อมต่อสองครั้งพยายามในหนึ่งบรรทัด:
export MYSQL_PWD=bar; \
mysql -ufoo
mysql -ufoo
(รหัสผ่านถูกตั้งค่าในสภาพแวดล้อมเพื่อให้ผ่านไปยังmysql
กระบวนการ)
การตรวจสอบในกรณีที่มีข้อสงสัย
เพื่อตรวจสอบว่าการเชื่อมต่อผ่านซ็อกเก็ต TCP / IP หรือซ็อกเก็ต Unix Domain
- รับ PID ของกระบวนการไคลเอนต์ mysql โดยตรวจสอบผลลัพธ์ของ
ps faux
- วิ่ง
lsof -n -p<yourpid>
.
คุณจะเห็นสิ่งต่างๆเช่น:
mysql [PID] quux 3u IPv4 [code] 0t0 TCP 127.0.0.1:[port]->127.0.0.1:mysql (ESTABLISHED)
หรือ
mysql [PID] quux 3u unix [code] 0t0 [code] socket
ดังนั้น:
กรณี 0: โฮสต์ = '10 .10.10.10 '(การทดสอบค่าว่าง)
update user set host='10.10.10.10' where user='foo'; flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: FAILURE
- เชื่อมต่อจาก 127.0.0.1: FAILURE
กรณีที่ 1: โฮสต์ = '%'
update user set host='%' where user='foo'; flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: ตกลง
- เชื่อมต่อจาก 127.0.0.1: ตกลง
กรณีที่ 2: โฮสต์ = 'localhost'
update user set host='localhost' where user='foo';flush privileges;
พฤติกรรมแตกต่างกันไปskip-name-resolve
และเห็นได้ชัดว่าขึ้นอยู่กับ หากตั้งค่าไว้จะทำให้บรรทัดlocalhost
ที่ถูกละเว้นตามบันทึก ข้อมูลต่อไปนี้สามารถเห็นได้ในบันทึกข้อผิดพลาด: "'user' entry 'root @ localhost' ถูกละเว้นในโหมด --skip-name-resolution" . ซึ่งหมายความว่าไม่มีการเชื่อมต่อผ่าน Unix Domain Socket แต่ในเชิงประจักษ์ไม่เป็นเช่นนั้น localhost
ตอนนี้หมายถึงซ็อกเก็ตโดเมน Unix เท่านั้นและไม่ตรงกับ 127.0.0.1 อีกต่อไป
skip-name-resolve
ปิด:
- เชื่อมต่อโดยใช้ซ็อกเก็ต: ตกลง
- เชื่อมต่อจาก 127.0.0.1: ตกลง
skip-name-resolve
เปิดอยู่:
- เชื่อมต่อโดยใช้ซ็อกเก็ต: ตกลง
- เชื่อมต่อจาก 127.0.0.1: FAILURE
กรณีที่ 3: โฮสต์ = '127.0.0.1'
update user set host='127.0.0.1' where user='foo';flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: FAILURE
- เชื่อมต่อจาก 127.0.0.1: ตกลง
กรณีที่ 4: โฮสต์ = ''
update user set host='' where user='foo';flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: ตกลง
- เชื่อมต่อจาก 127.0.0.1: ตกลง
(ตามที่MySQL 5.7: 6.2.4 การควบคุมการเข้าถึงขั้นตอนที่ 1: การเชื่อมต่อการตรวจสอบ , ว่างสตริง '' ยังหมายถึง“เจ้าภาพใด ๆ” แต่หลังจากที่ทุกประเภท '%'. )
กรณีที่ 5: โฮสต์ = '192.168.0.1' (การทดสอบเพิ่มเติม)
('192.168.0.1' เป็นหนึ่งในที่อยู่ IP ของเครื่องของฉันเปลี่ยนแปลงอย่างเหมาะสมในกรณีของคุณ)
update user set host='192.168.0.1' where user='foo';flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: FAILURE
- เชื่อมต่อจาก 127.0.0.1: FAILURE
แต่
- เชื่อมต่อโดยใช้
mysql -pbar -ufoo -h192.168.0.1
: ตกลง (!)
ประการหลังเพราะนี่คือการเชื่อมต่อ TCP ที่มาจาก192.168.0.1
ที่เปิดเผยโดยlsof
:
TCP 192.168.0.1:37059->192.168.0.1:mysql (ESTABLISHED)
Edge Case A: โฮสต์ = '0.0.0.0'
update user set host='0.0.0.0' where user='foo';flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: FAILURE
- เชื่อมต่อจาก 127.0.0.1: FAILURE
Edge Case B: โฮสต์ = '255.255.255.255'
update user set host='255.255.255.255' where user='foo';flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: FAILURE
- เชื่อมต่อจาก 127.0.0.1: FAILURE
ขอบเคส C: โฮสต์ = '127.0.0.2'
(127.0.0.2 เป็นที่อยู่ลูปแบ็คที่ถูกต้องสมบูรณ์เทียบเท่ากับ 127.0.0.1 ตามที่กำหนดในRFC6890 )
update user set host='127.0.0.2' where user='foo';flush privileges;
- เชื่อมต่อโดยใช้ซ็อกเก็ต: FAILURE
- เชื่อมต่อจาก 127.0.0.1: FAILURE
ที่น่าสนใจ:
mysql -pbar -ufoo -h127.0.0.2
เชื่อมต่อจาก127.0.0.1
และล้มเหลว
mysql -pbar -ufoo -h127.0.0.2 --bind-address=127.0.0.2
ก็โอเค
ทำความสะอาด
delete from user where user='foo';flush privileges;
ภาคผนวก
หากต้องการดูสิ่งที่อยู่ในmysql.user
ตารางซึ่งเป็นหนึ่งในตารางสิทธิ์ให้ใช้:
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;
สิ่งนี้ให้:
+
| password | user | host | su | gr | selock | modif | ria | views | funcs | replic | admin |
+
| *E8D46 | foo | | N | N | NN | NNNNN | NNN | NNN | NNNNN | NN | NNNNNN |
ในทำนองเดียวกันสำหรับตาราง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;