เชื่อมต่อ MySQL, MariaDB สิทธิ์ วิธีไหนดี

Byphunsanit

เชื่อมต่อ MySQL, MariaDB สิทธิ์ วิธีไหนดี

ในการเชื่อมต่อ MySQL และ MariaDB ความแตกต่างหลักในการเชื่อมต่อ ( Connection Type ) อยู่ที่โปรแกรมโปรโตคอล ( Protocol ) การรับส่งข้อมูล, ขอบเขตการเข้าถึง ( Scope ) และความปลอดภัย ( Security Impact ) ครับ


การเชื่อมต่อ 3 รูปแบบหลัก

รูปแบบวิธีการ ( Connection Type )ลักษณะการทำงานความเร็ว
Unix Socketlocalhostใช้ไฟล์พิเศษ ( เช่น .sock ) ในระบบไฟล์ Linux เพื่อคุยกันโดยตรงเร็วที่สุด ( ไม่ต้องผ่าน Network Stack )
TCP/IP127.0.0.1 หรือ IPใช้ Network Protocol ในการรับส่งข้อมูลผ่าน Port ( ปกติคือ 3306 )ปานกลาง ( มี Overhead ของการจัดการ Packet )
% ( Wildcard )Remote Accessเป็นการตั้งค่า User Permission ให้รับการเชื่อมต่อจาก IP ใดก็ได้ผ่าน TCP / IPเท่ากับ TCP / IP

ความปลอดภัยและกรณีที่ควรใช้

Unix Socket ( Unix-like เช่น Linux, macOS, BSD ) ( Localhost )

เป็นการเชื่อมต่อภายในเครื่องเดียวกันโดยไม่ผ่านระบบ Network

  • ความปลอดภัย: สูงสุด เพราะไม่มีการเปิด Port ให้โลกภายนอกเห็น จำกัดสิทธิ์ผ่าน User Permissions ของตัว OS เอง
  • Case ที่ควรใช้
    • Production Server: เมื่อ Web Server ( Nginx / PHP-FPM ) และ Database อยู่บนเครื่อง Physical / VPS ตัวเดียวกัน
  • ข้อควรจำ: หากระบุ Host เป็น localhost ใน Client ส่วนใหญ่ (เช่น PHP, Python) ระบบจะพยายามวิ่งหา Socket ไฟล์โดยอัตโนมัติ

TCP/IP ( 127.0.0.1 หรือ Specific IP )

การรับส่งข้อมูลผ่าน Network Interface

  • ความปลอดภัย: สูง หากจำกัด Bind-address ไว้ที่ 127.0.0.1 ( เฉพาะในเครื่อง ) หรือระบุ IP เฉพาะของ App Server
  • Case ที่ควรใช้
    • Development ( Dev ): เชื่อมต่อจาก IDE ( DBeaver / VS Code ) เข้าหา Database ที่รันอยู่
    • Multi-Server: เมื่อแยกเครื่อง Web Server และ DB Server ออกจากกัน

% ( Wildcard User )

ไม่ใช่ “วิธี” เชื่อมต่อ แต่เป็น “สิทธิ์” ของ User ที่อนุญาตให้ Connect มาจากIP ที่ไหนก็ได้

  • ความปลอดภัย: ต่ำที่สุด หากเปิดคู่กับ Firewall ที่ไม่รัดกุม เสี่ยงต่อการโดน Brute-force จากภายนอก
  • Case ที่ควรใช้:
    • ไม่แนะนำให้ใช้บน Production นอกจากจะทำ VPN หรือ White-list IP เท่านั้น

รายละเอียด

  • % คืออะไรในโลกของ MySQL/MariaDB?
    • ในตาราง mysql.user ฟิลด์ Host จะระบุว่า User นั้นสามารถล็อคอินมาจากที่ไหนได้บ้าง
      • Specific IP: เช่น 192.168.1.10 ( เข้าได้จากเครื่องนี้เครื่องเดียว )
      • IP Range: เช่น 192.168.1.% ( เข้าได้จากทุกเครื่องในวง Network 192.168.1.xxx )
      • Wildcard ( % ): หมายถึง “Any Host” หรือทุก IP Address ในโลกที่วิ่งมาถึง Server คุณได้
  • ทำไมถึงบอกว่าเป็น Subset ( หรือ Super-set ) ของ IP ?
    • หากเราวาดวงกลมของสิทธิ์การเข้าถึง
      • วงกลมเล็กที่สุด: คือ Specific IP ( เช่น 127.0.0.1 ) — เข้าได้เฉพาะจุดเดียว
      • วงกลมที่ใหญ่ขึ้น: คือ IP Range ( เช่น 10.0.0.% ) — เข้าได้เฉพาะในวง LAN
      • วงกลมที่ใหญ่ที่สุด: คือ Wildcard (%) — ครอบคลุมทุก IP Address ที่มีอยู่จริง

ดังนั้น % จึงเป็นตัวแทน ( Placeholder ) ที่รวมเอาทุกๆ IP Address เข้าไว้ด้วยกันเพื่อให้จัดการสิทธิ์ได้ง่ายขึ้นครับ

ความเข้าใจผิดที่พบบ่อย ( จุดที่ต้องระวัง! )

แม้ว่า % จะแปลว่า “ทุก IP” แต่ใน MySQL/MariaDB มันมี “ข้อยกเว้น” ที่สำคัญมากครับ
% ไม่รวม localhost (ในบางกรณี)
โดยปกติ MySQL จะมองว่าการเชื่อมต่อผ่าน Unix Socket ( ใช้คำว่า localhost ) กับการเชื่อมต่อผ่าน TCP/IP ( ใช้ % หรือ IP ) เป็นคนละช่องทางกัน

  • ถ้าคุณสร้าง User 'pitt'@'%' บางครั้งคุณอาจจะล็อคอินด้วย -h localhost ไม่ได้ ( เพราะมันจะวิ่งหา Socket )
  • คุณต้องล็อคอินด้วย -h 127.0.0.1 แทน เพื่อให้ระบบมองว่าเป็น Network IP แล้วไปเช็คสิทธิ์ใน %

การใช้งานใน Environment ต่าง ๆ

Development ( Local Machine )

  • แนะนำ: ใช้ TCP/IP (127.0.0.1)
  • เหตุผล: ตั้งค่าง่าย และ Tools ส่วนใหญ่บน macOS / Windows ทำงานกับ TCP ได้เสถียรกว่าการงมหา Path ของ Socket ไฟล์

Docker Environment

  • แนะนำ: ใช้ TCP/IP ( ผ่าน Container Name )
  • เหตุผล: ในโลกของ Docker แต่ละ Container คือ “คนละเครื่อง” ดังนั้นมันจะคุยผ่าน Socket ไม่ได้ ( เว้นแต่จะทำ Shared Volume ซึ่งยุ่งยาก )
  • การตั้งค่า: ให้ App เชื่อมไปที่ Hostname ตามชื่อ Service ใน docker-compose.yml

Production Server ( Ubuntu / Linux )

  • แนะนำ: ใช้ Unix Socket
  • เหตุผล: ประสิทธิภาพดีที่สุดและปลอดภัยที่สุด เพราะไม่ต้องเปิด Port 3306 ทิ้งไว้ ( ระบุ host เป็น localhost หรือระบุ path ไปที่ /var/run/mysqld/mysqld.sock )

สรุปการเลือกใช้ ( Decision Matrix ) ตาม OS

OS / Environmentวิธีที่แนะนำทำไม?
Linux ( Server / Production )Unix Socketเร็วที่สุด ปลอดภัยที่สุด ไม่ต้องผ่าน Network Card
macOS ( Development )TCP/IP ( 127.0.0.1 )สะดวกที่สุด ลดปัญหาเรื่องหา Path ของ Socket ไม่เจอ
Windows ( Development )TCP/IP ( 127.0.0.1 )เป็นวิธีมาตรฐานเพียงวิธีเดียวที่ทำงานได้สถียร
Docker ( ทุก OS )TCP/IP ( Host/Service Name )เพราะ Container คุยข้ามกันผ่าน Socket ไม่ได้

ข้อควรระวังเรื่องความปลอดภัย ( Security Impact )

  1. ห้ามเปิด % สำหรับ User root โดยเด็ดขาด
  2. การใช้ % คือการเปิดประตูบ้านทิ้งไว้ทุกบาน ( ทุก ๆ ip )
    • เสี่ยงต่อการ Brute-force: ใครก็ตามที่รู้ IP Server ของคุณสามารถพยายามเดารหัสผ่านได้จากทั่วโลก
    • ควรใช้คู่กับ Firewall: หากจำเป็นต้องใช้ % จริง ๆ ( เช่น ใน Docker ที่ IP เปลี่ยนบ่อย ) คุณควรจำกัดที่ระดับ Firewall ( UFW หรือ Security Group ของ Cloud ) ให้เฉพาะ IP ที่ไว้ใจเท่านั้นที่ผ่าน Port 3306 เข้ามาได้
  3. หากต้องใช้ Remote Access ให้ใช้การ SSH Tunneling แทนการเปิด Port 3306 ตรง ๆ
  4. ตรวจสอบ bind-address ในไฟล์ config ( my.cnf หรือ 50-server.cnf ) เสมอว่าไม่ได้เผลอเปิดรับทุก IP (0.0.0.0) โดยไม่จำเป็น
  5. ถ้าคุณรันบน Docker, ปกติเราจะใช้ % เพราะ IP ของ Container ลูกจะเปลี่ยนไปเรื่อย ๆ ทุกครั้งที่ Restart แต่เราจะ “ซ่อน” Port 3306 ไว้ไม่ให้ Public ออกไปข้างนอก ( ไม่ทำ Port Mapping 3306:3306 ) เพื่อความปลอดภัยครับ

อ่านเพิ่มเติม

About the author

phunsanit administrator