Script สำหรับการ reset mysql root’s password

สำหรับ admin ของ Linux Server โดยทั่วไปแล้ว มักจะหลีกไม่พ้นที่จะต้อง ติดตั้ง database server สักครั้งนึง เพราะว่า สำหรับ application โดยส่วนใหญ่แล้ว โดยเฉพาะ web application ในปัจจุบัน มักจะต้องการใช้ database server เป็น backend สำหรับการเก็บข้อมูล

และบน Linux ส่วนใหญ่ก็จะหนีไม่พ้นการใช้งาน MySQL เป็น Server … เพราะเป็นตัวที่มีคนใช้กันมากที่สุด และรองรับโดยหลายๆ framework ของ Web App ทั้งหลาย

แน่นอน ตอนที่ติดตั้งครั้งแรก ตัวซอฟต์แวร์ที่ใช้ในการติดตั้ง ก็ถาม root password ของ MySQL สำหรับการ กำหนดสิทธิในการใช้งาน

สำหรับคนที่ใช้งาน database server มานานระดับหนึ่ง ก็จะรู้ว่า password ที่จะใช้สำหรับ root ของ MySQL นั้น ไม่จำเป็นจะต้องเป็นตัวเดียวกับ root password ของระบบ … และ ไม่ควรที่จะเป็นตัวเดียวกัน … สำหรับคนที่ไม่รู้ในเรื่องนี้ ก็มักจะต้อง “เรียนรู้” ด้วยความยากลำบากในทีหลัง … ผมรู้สิน่า ผม “จ่าย” ค่าเล่าเรียนเรื่องนี้ด้วยราคาที่ “แพง” พอสมควรเชียวล่ะ

หลังจากที่รู้แล้วว่า มัน “จะต้อง” ไม่ใช่ password เดียวกันกับ password ที่สำคัญของระบบ ปัญหาที่จะตามมาก็คือว่า เราก็อาจจะตั้ง password ของ root ของ MySQL แบบง่ายๆ เช่น “1234”, “abcd” อะไรทำนองนี้ เพราะว่า ในแง่ของการให้บริการ MySQL server ก็มักจะให้บริการกับ “client” ท่อยู่บนเครื่องเดียวกัน ไม่ได้ให้บริการผ่าน network ไปให้เครื่องอื่นๆ หรือ ถ้าจำเป้นจะต้องให้บริการ ก้ให้บริการกับ server  ที่อยู่ใน cluster เดียวกัน จะมีเฉพาะ admin ด้วยกันที่จะรู้ว่ามี mysql ให้บริการอยู่บนเครื่องนี้

แน่นอน ความคิดเช่นนี้ ก็มักจะนำบทเรียน “ราคาแพง” บทที่สอง เกี่ยวกับ root password ของ mysql มาให้ อีกเหมือนกัน และมันมักจะพ่วงมากับ “phpmyadmin” ที่จะทำให้ ตัว mysql server ซึ่งเคยเข้าใจว่า “ไม่สามารถเข้าถึงจาก server อื่นๆได้” กลับเข้าถึงได้ง่ายๆ ผ่าน “web” และเมื่อเจอกับ bot ที่โจมตีแบบอัตโนมัติ หายนะ … ก็มาเยือนได้ง่ายๆ เหมือนกัน

นั่นก็จะเป็นบทเรียนราคาแพงอีกบทนึงเช่นกัน

ข้อสรุปของผม หลังจากได้บทเรียนอย่างนั้นมาก็คือ password ของ root ไม่ว่าจะเป็นของระบบเอง หรือ จะเป็นของ database “จะต้อง” เป็นคนละตัวกัน  _และ_ จะต้องมีระดับของความปลอดภัยสูงใกล้ๆกัน

ได้ password ที่ secure มา … ก็ดี … แต่ปัญหาของ password ที่ secure ก็คือ จำยาก … สำหรับ root’s password ของระบบ ที่ยังมีการใช้งานค่อนข้างบ่อย ก็จะมีโอกาสที่จะลืมได้น้อยกว่า … วิธีการที่จะทำให้ ไม่ลืม และยังมี password ที่ secure ก็มีแน่ๆ แต่นั่นไม่ใช่สิ่งที่ผมอยากจะพูดถึงในบันทึกนี้ (อันที่จริงก็เขียนเอาไว้ที่อื่นแล้วด้วย)

ที่จะมาแก้ปัญหาในบันทึกนี้ ก็คือ password ของ root ของ MySQL … โอเค … ก็รู้แล้วล่ะว่าจะต้อง set ให้มัน secure … ก็ set ไปแล้ว แต่ก็ลืมไปแล้วด้วย (ฮา) … งั้นทำไงดีล่ะ?

ครับ ถ้าลืม root password ไม่ว่าจะเป็นของระบบเอง หรือ จะเป็นของ MySQL server ถ้าจะให้สามารถ “ยึดอำนาจ” ของ root กลับมาได้ ก็คงต้องใช้วิธีการ reset password กัน

วิธีการ reset password ของ root ระบบที่ใช้ Linux ที่ไม่ได้การ encrypt ระบบไฟล์เอาไว้ และ ไม่ได้ lock password ที่ระดับของ bios ก็ไม่ได้ยุ่งยากอะไรมาก … แต่ก็ไม่ได้เป็นเรื่องที่ตั้งใจจะเขียนในบันทึกฉบับนี้อีกเหมือนกัน และคิดว่า admin แทบทุกท่านก็น่าจะรู้วิธีการกันอยู่ดีพอสมควรแล้ว

ที่ตั้งใจจะพูดถึงก็คือ การ reset password ของ root ของ MySQL Server

ซึ่งอันที่จริง ก็ไม่ได้เป็นความลับอะไร ถ้าลอง search หาด้วย google ก็จะเจอในระยะไม่เกิน 2-3 click ของ mouse

แต่โดยตัวผมเอง ที่จำเป็นจะต้อง เกี่ยวข้องกับ MySQL Server บนหลายเครื่อง และเกิดเหตุการณ์จำเป็นให้ต้อง reset password ของ MySQL อยู่ 2-3 รอบ ในช่วงไม่กี่เดือนที่ผ่านมา ก็ชักจะรู้สึกหงุดหงิอยู่นิดหน่อย ตรงที่ว่า วิธีการที่มี มันจะต้องทำแบบ manual และ จะต้องเปิด terminal ขึ้นมามากกว่า 2 terminal หรือ 2 tab เพื่อที่จะจัดการให้เสร็จเรียบร้อย เพราะจะต้อง run โปรแกรม server บน terminal นึง และ run โปรแกรม client อีก terminal นึง ขนานกันไป

ทำอยู่ หลายรอบ … รอบสุดท้ายที่ทำ ก็ชักเบื่อ แล้วก็ถามตัวเองว่า จะเขียนมันเป็น script แล้ว run ครั้งเดียวเสร็จ ไม่ได้เชียวหรือ?

ลองกลับไป ล้วง,แคะ,แกะ,เกา shell script และตัว mysqld กับ mysql client ใหม่อีกรอบ ก็ทำให้ได้ script ตัวนี้มาครับ

#!/bin/sh

PASSWD="$1"
[ -z "$PASSWD" ] && echo "Usage: $0 newpassword" && exit

[ `id -u` != "0" ] && echo "Must be root!" && exit

# Is mysql installed?
[ ! -x /usr/bin/mysql ]    && \
    echo "[?] Is mysql-server & mysql client installed?" && \
    exit

RUNNING=0
# is mysql server running?
if [ "`ps auxw | grep [/]usr/sbin/mysqld`" ]; then
    echo "[*] mysqld is running, try to stop it..."
    RUNNING=1
    # yes, then shutdown it
    service mysql stop
    for i in `seq 1 10`; do
        [ "$i" = "10" ] && {
            echo "[?] Hmm? can't stop mysqld server";
            exit;
        }
        [ -z "`ps auxw | grep [/]usr/sbin/mysqld`" ] && {
            echo "[*] mysqld stopped!";
            break;
        }
        echo -n "."
        sleep 1
    done
    echo ""
fi

# Start mysqld not using grant tables
echo "[*] Start mysqld without using grant tables"
/usr/sbin/mysqld --skip-grant-tables 2>/dev/null &
MPID=$!

echo "[*] Wait for mysqld to be ready ..."
sleep 5

echo "[*] Now, set new password..."
cat <<EOT | /usr/bin/mysql
UPDATE mysql.user SET Password=PASSWORD("$PASSWD") WHERE User='root';
FLUSH PRIVILEGES;
EOT

echo "[*] Done! now stop the mysqld again ..."
kill -QUIT $MPID
sleep 3

[ "$RUNNING" = "1" ] && {
    echo "[*] Restart mysqld using normal running method..";
    service mysql start;
}

วิธีการ ใช้งาน  ก็ save โปรแกรมลงในไฟล์ สมมติว่าชื่อ reset-mysql-root-password

$ chmod +x bin/reset-mysql-root-password
$ bin/reset-mysql-root-password NewSecretPasswd2013

ครับ เรียกใช้โปรแกรมตามด้วย password ที่ต้องการจะให้ set ใหม่แค่นั้นเองครับ

ตัว script เขียนขึ้นมาเพื่อให้ใช้งานได้กับ Debian และ Ubuntu

ผมใช้ delay เพื่อรอให้การ start/stop ของ mysqld เสร็จเรียบร้อยก่อนที่จะทำงานต่อไป ซึ่งก็ขึ้นอยู่กับว่า load ของเครื่อง และความเร็วของเครื่องที่ใช้อยู่เป้นอย่างไร ถ้ามีปัญหา ก็อาจจะต้องปรับเพิ่มค่า delay ที่มีอยู่ใน script ให้มากขึ้นกว่าเดิมอีกหน่อยครับ

จริงๆแล้วผมควรที่จะอธิบายเพิ่มว่า เทคนิคที่ใช้ใน script มีอะไรบ้าง แต่ก็คาดว่า หลายๆคนที่เตยเจอปัญหาแบบเดียวกัน ก็น่าจะเคยอ่านจาก document ของ MySQL เองแล้ว ก็น่าจะไม่จำเป็นมาก ที่ผมต้องการจะเสนอในที่นี ก็คือ tool เป้น shell script ที่จะช่วยให้ทำงานให้ง่ายขึ้น แทนที่จะต้องใช้วิธีการแบบ manual น่ะครับ

แต่ยังไงถ้ามีข้อสงสัย ก็ comment / ถามมาก็แล้วกันนะครับ ผมจะกลับมาตอบ ถ้ามีคำถามครับ 🙂

1 comment for “Script สำหรับการ reset mysql root’s password

  1. วิบูลย์ วราสิทธิชัย
    March 30, 2013 at 1:11 pm

    ขอบคุณครับ บทความนี้ช่วยให้ได้ไอเดียในการเขียน shell script เพิ่มเติม ทั้งที่จริงแล้ว command ในการแก้ไขลืม Password ของ mysqld root ก็ไม่กี่บรรทัด ฮิๆ คิดว่าผู้เขียนคงจะขอถ่ายทอดวิธีการเขียน shell script จากที่เคยสอนในห้องเรียน มาเพิ่มความรู้ต่อให้นั่นเอง

Leave a Reply