นโยบายการจัดการความรู้ มหาวิทยาลัยสงขลานครินทร์ 1.ให้ใช้เครื่องมือการจัดการความรู้ผลักดัน คุณภาพคน และกระบวนทำงาน 2.ส่งเสริมการแลกเปลี่ยนประสบการณ์การทำงาน จากหน้างาน 3.ส่งเสริมให้มีเวทีเรียนรู้ร่วมกัน

นาย ฉัตรชัย จันทร์พริ้ม
Ico64
เครือข่าย
สมาชิก · ติดตาม: 4 · ผู้ติดตาม: 5

อ่าน: 4197
ความเห็น: 5

remote shutdown เครื่อง โดยไม่ต้องใช้ root account

ssh webserver sudo shutdown -h now

คุณ adzz ถามว่า

... แต่ว่าผมอยากให้คนอื่นสามารถ Shutdown ได้กรณีที่ไฟดับ เพราะ UPS มันจะสามารถสำรองไฟได้ไม่นานมาก บางครั้งไฟชอบดับช่วงดึกๆ นาน ทำให้บางทีเครื่องดับไปเลย ถ้ากรณีอย่างนี้มีการเขียนสคริป์อะไรให้สามารถสั่ง shutdown ด้วยคีย์ลัดแบบไม่ต้อง login เข้า root ก่อนหรือเปล่าครับเพราะเซิร์ฟเวอร์ผมแต่ละเครื่องไม่ได้ต่อจอไว้เลย แถมตั้งอยู่คนละที่อีกต่างหาก ...

การ shutdown เครื่องต้องใช้สิทธิของ root ถ้าต้องการให้ user อื่นๆที่ไม่ใช่ root  สามารถ shutdown เครื่องได้ วิธีการที่นิยมกันโดยทั่วไปก็คือใช้ sudo

ซึ่ง sudo package น่าจะมีติดตั้งสำหรับเครื่องที่เป็น server อยู่แล้ว ถ้ายังไม่มี ก็แล้วแต่ว่าจะใช้ linux distribution ใหน ซึ่งส่วนใหญ่แล้วคำสั่งที่ใช้ในการติดตั้ง มักจะหนีไม่พ้น

    # apt-get install sudo

สำหรับตระกูลของ debian 

    # yum install sudo

สำหรับตระกูลของ redhat 

ทีนี้ พอมี sudo ติดตั้งไว้แล้ว ก็จะต้อง config ตัว package sudo ว่าจะให้ใครใช้คำสั่ง อะไรได้บ้าง วิธีการ config สามารถทำได้ซับซ้อนและหลากหลายพอสมควร รายละเอียดสามารถหาอ่านได้หลายที่จาก internet หรือใน manpage ของ sudo เอง

สำหรับ blog นี้ต้องการตอบคำถามคุณ adzz โดยเสนอแค่ทางเลือกหนึ่ง เพราะฉะนั้น ผมจะสมมติว่า ต้องการให้ user ที่มีชื่อว่า adzz ซึ่งมี account อยู่บนเครื่อง webserver สามารถสั่ง shutdown เครื่องได้เมื่อจำเป็น

ก็เริ่มจากการติดตั้ง sudo บน webserver และแก้ไขไฟล์ /etc/sudoers โดยการใช้คำสั่ง

    # visudo

หรืออาจจะใช้การ edit file /etc/sudoers โดยใช้ text editor ใดๆก็ได้ เพราะไฟล์นี้เป็น text file ธรรมดา แต่ถ้าใช้คำสั่ง visudo ก็จะได้ประโยชน์ตรงที่ คำสั่งนี้จะตรวจสอบ format ของไฟล์ที่เพิ่ง edit ไป ก่อนที่จะ save ลงไป ว่ามี format ถูกต้องหรือเปล่า ถ้ามีที่ผิดก็จะไม่ยอม save ถ้าเกิด edit เองโดยใช้ text editor แล้วมีที่ผิดพลาด ก็จะมีปัญหาในขั้นตอนของการเรียกใช้คำสั่ง sudo

ถึงแม้ว่าชื่อคำสั่งจะเป็น visudo แต่ editor ที่เรียกใช้ขึ้นมาจริงๆขึ้นอยู่กับ default editor ที่ได้ set เอาไว้ บนเครื่อง debian ส่วนใหญ่ ในระยะหลังจะใช้ nano แทนที่จะเป็น vi ถ้าอยากจะใช้ editor ตัวอื่นก็สามารถกำหนดได้ โดยการกำหนดค่า environment ที่ชื่อว่า EDITOR ... ตัวอย่าง

    # EDITOR=vi visudo

หรือ ถ้าจะใช้ gedit

   # EDITOR=gedit visudo

กลับมาส่วนที่ต้องใส่เข้าไปในไฟล์ /etc/sudoers สำหรับกรณีนี้เราต้องการให้ user ที่ชื่อว่า adzz สามารถเรียกใช้คำสั่ง shutdown เพื่อปิดเครื่องได้โดยไม่ต้องมี root password ก็สามารถกำหนด config ใน sudo ได้เป็น

    adzz       ALL=(root)   NOPASSWD:   /sbin/shutdown

อธิบายความหมายของ sudo config พอคร่าวๆ นะครับ

adzz     ชื่อ account ของ user ที่ต้องการให้ใช้คำสั่งนั้นๆ

ALL     เป็นชื่อ host ในกรณีนี้หมายถึง host ใดๆก็ได้ สาเหตุที่ต้องมีส่วนของ host อยู่ด้วย ก็เพื่อที่จะให้ file config ตัวเดียวกันเอาไปใช้งานบนหลายเครื่องได้ โดยแต่ละเครื่อง user ที่มีชื่อ account เดียวกันอาจจะมีสิทธิทำอะไรได้ไม่เท่ากัน

(root)     คือคำสั่งนั้นๆ run โดยใช้สิทธิของใคร สำหรับกรณีนี้ shutdown ต้องใช้สิทธิของ root จึงจะทำงานได้

NOPASSWD:    บอกว่าเมื่อ user adzz เรียกใช้คำสั่งนี้ ก็ไม่จำเป็นจะต้องป้อน password ซึ่งถ้าไม่มี NOPASSWD: user adzz จะต้องป้อน password ของตัวเอง (ไม่ต้องใช้ root password) เพื่อจะใช้คำสั่ง shutdown

/sbin/shutdown เป็นคำสั่งที่ต้องการอนุญาตให้ user adzz ใช้ ซึ่งถ้ามีหลายคำสั่งที่ต้องการให้สิทธิในลักษณะเดียวกัน ก็ list คำสั่งอื่นๆตามไปได้เลย โดยใช้เครื่องหมาย จุลภาคคั่นระหว่างคำสั่ง

พอจัดการตรงส่วนของการ config sudo เรียบร้อยแล้ว เราก็สามารถทดสอบได้โดย ทดลอง login เข้าสู่เครื่อง webserver แล้วเรียกใช้คำสั่ง

     $ sudo shutdown -k now "Test shutdown by adzz" 

ซึ่ง option "-k" จะหมายถึงไม่ให้ shutdown จริงเพียงแต่ส่ง message ไปเตือน user เท่านั้น ถ้าการ config sudo ยังไม่ถูกต้อง หรือ ถ้าเรียกใช้คำสั่ง shutdown โดยใช้  user adzz โดยไม่ใช้คำสั่ง sudo ก็ควรที่จะได้รับคำเตือนว่า

     shutdown: you must be root to do that!

แต่ถ้าใช้ user root หรือใช้คำสั่ง sudo ก็ควรที่จะได้ message บอกว่า

     Broadcast message from root@ ...

     ...
     The system is going down to maintenance mode NOW!

     Shutdown cancelled.

เมื่อถึงขั้นนี้ ก็พร้อมที่จะให้ สั่ง shutdown จากเครื่อง remote ได้แล้วโดยสามารถใช้ user ธรรมดา (ไม่ต้องใช้ root) และไม่ต้องพิมพ์ password ใดๆ (ถ้าเรียกใช้ keychain ไว้แล้ว)

วิธีการ setup public key เพื่อให้ ใช้คำสั่ง ssh ไปยังอีกเครื่องนึงได้ ผมเขียนตอบคุณป้อมไว้แล้ว เมื่อปลายปีที่แล้ว (13 ธค. 2007) ดูได้จาก etherwake/ethersleep

ซึ่งถ้า user zzad บนเครื่อง notebook ได้ setup key และ copy key ไปเก็บไว้บนเครื่อง webserver ใน home directory ของ user adzz ~/.ssh/authorized_keys แล้ว  zzad ก็สามารถสั่ง shutdown เครื่อง webserver จาก notebook ได้โดยใช้คำสั่ง

    zzad@notebook:~$ ssh adzz@webserver sudo shutdown -h now

สำหรับการปิดเครื่องไปเลย (หรือจะแค่ทดสอบโดย "-k now")

โดยวิธีการนี้ ถ้าต้องการให้ user อื่น บนเครื่องอื่นสามารถ shutdown webserver ได้เช่นเดียวกัน ก็อาจจะใช้วิธีการเดียวกันในการ config sudo และ key ของ user นั้น หรือถ้าต้องการแค่ใครบางคนที่มี account บนเครื่องอื่นๆ แต่ไม่จำเป็นต้องมี account บน webserver แต่สามารถสั่ง shutdown webserver ได้ ก็สามารถทำได้ โดยการสร้าง account ขึ้นมาใหม่ แล้วกำหนดให้ใช้งานได้เฉพาะคำสั่ง shutdown แล้ว copy เอา public key ของ user แต่ละคนไปไว้ใน authorized_keys ของ user ที่ใช้สำหรับ shutdown เครื่อง นั้นๆ โดยเฉพาะ

สำหรับเรื่องนี้ มีรายละเอียดเพิ่มเติมอีกนิด แต่คิดว่าคำตอบที่มีคงตอบที่คุณ adzz ถามไว้แล้วได้ ก็เลยขอเขียนแค่นี้ก่อนครับ ถ้ามีคำถามเพิ่ม เดี๋ยวค่อยเติมคำตอบ ส่วนที่ยังขาด :)

เพิ่มเติมอีกนิด เพราะคำถามถามถึง script

จริงๆแล้ว กระบวนการหลักๆ จะเป็นการ setup ทั้งจากตัว host ที่ user/admin ใช้ และ server ที่ต้องการ run คำสั่งโดยอัตโนมัติ หลังจากนั้นเมื่อต้องการใช้งาน ก็จะเหลือคำสั่งแค่บรรทัดเดียว ซึ่งไม่นิยมเขียนเป็น script สักเท่าไร

แต่ถ้ามองว่ามีเครื่องที่ต้องการจะ shutdown อยู่หลายเครื่อง เช่น webserver, mailserver, proxyserver, radiusserver แล้วจะใช้วิธีการเขียน script เพื่อให้เรียกใช้งานได้ง่ายขึ้น ก็อาจจะทำได้ประมาณนี้

#!/bin/sh

SERVERLIST="webserver mailserver proxyserver radiusserver"

USER="adzz" 

if [ -z "$1" ]; then

    for SVR in ${SERVERLIST}; do

          echo "===== shutting down $SVR ====="

          ssh ${USER}@{SVR} sudo shutdown -h now

    done

else

   SVR="$1"

   echo "===== shutting down $SVR =====" 

   ssh ${USER}@{SVR} sudo shutdown -h now

fi 

โดย script ตัวนี้สามารถใช้งานได้ 2 แบบ สมมติว่าให้ script ชื่อ remoteshutdown แบบแรกเป็นการ shutdown เพียงเครื่องเดียว ก็สามารถระบุชื่อเครื่องที่จะ shutdown เป็น argument เช่น

    $ ./remoteshutdown webserver

หรือให้ shutdown ทุกเครื่องโดยเรียงลำดับไปทีละเครื่อง ก็สามารถเรียกใช้

    $ ./remoteshutdown

ได้เลย โดย script จะใช้ชื่อของ server ที่ list อยู่ในตัวแปร SERVERLIST มาเรียกใช้คำสั่งทีละตัว -- ใช้สำหรับกรณีที่ไฟดับแล้วต้องการ down ทีเดียวทั้งหมด

ถ้าต้องการให้มันสั่ง shutdown แบบ ขนานกันไปเลย โดยไม่ต้องรอให้ down ทีละเครื่องก่อนที่จะไปสั่งตัวถัดไป ก็อาจจะแก้ไข script นิดหน่อย โดยเปลี่ยน บรรทัด

    ssh ${USER}@{SVR} sudo shutdown -h now

เป็น 

    ssh ${USER}@{SVR} sudo shutdown -h now &

แต่ผมชอบแบบแรกมากกว่า

โดยทั่วไปการ shutdown เครื่องจะใช้เวลาไม่นานนัก น่าจะ down ได้ทันก่อนที่แบตเตอรี่ของ UPS จะหมด ถ้าเครื่องใหนใช้เวลานานเกินควร ก็อาจจะหมายความว่า เครื่องนั้นถ้าไม่ load หนักเกิน ก็ resource เช่น memory น้อยเกินไป ซึ่งเป็นปัญหาอย่างอื่นที่ต้องแก้

การเรียงลำดับ ชื่อ server ใน SERVERLIST โดยเอาตัวที่ load น้อยทำงานได้เร็วกว่า ขึ้นมาไว้ก่อนก็จะทำให้เวลาโดยรวมของการ shutdown ทั้งระบบใช้เวลาน้อยลง

การ parallel shutdown อาจจะเหมาะสำหรับการ shutdown เครื่องในห้อง lab ซึ่งมีหลายสิบเครื่อง ที่ทำให้การรอให้เครื่อง down ทีละเครื่องไม่เหมาะสม แต่สำหรับ ชุดของ server ผมคิดว่า รอให้แต่ละเครื่อง down แน่นอนแล้วจะดีกว่า เพราะถ้าสั่ง shutdown พร้อมกันแล้วบางเครื่องมีปัญหา เราอาจจะไม่ทันสังเกตุปัญหานั้นก็ได้ เพราะมี message มากเกินในช่วงเวลาสั้นๆ

 

 

  

 

 

 

Sections: Miscellaneous
License: สงวนสิทธิ์ทุกประการ Copyright
created: 21 May 2008 12:18 Modified: 21 June 2009 14:39 [ Report Abuse ]
ดอกไม้
People Who Like This
 
Facebook
Twitter
Google

Other Posts By This Blogger

ความเห็น

Ico48
Adzz [IP: 58.97.41.193]
21 May 2008 13:33
#29590
คือว่าคำถามนี้ผมจะเผื่อไว้กรณีไฟดับน่ะครับ แต่เครื่องเซิร์ฟเวอร์ยังมีไฟเลี้ยงจาก UPS อยู๋ นั่นก็คือเครื่องอื่นจะเข้ามายังตัวเซิร์ฟเวอร์ไม่ได้เพราะ Hub กับเครื่องก็จะดับไปด้วย เลยอยากหาวิธี shutdown เซิร์ฟเวอร์ที่ตัวเซิร์ฟเวอร์ได้เลยน่ะครับผม
ต้องขออภัยที่ถามไม่เคลียร์เท่าที่ควรครับ        
Ico48
Adzz [IP: 58.97.41.193]
21 พฤษภาคม 2551 13:41
#29591
ที่อยากได้จริงๆก็ืคือเหมือนกดปุ่ม Ctrl+Alt+Delete แล้วสั่งรีสตาร์ทได้เลยน่ะครับผม ขอรบกวนอีกรอบนะครับ

โอเคครับ

ในกรณีนี้นี่ ผมคิดว่าน่าจะดีกว่าถ้าแก้ปัญหา โดยไม่จำเป็นจะต้องใช้ ผู้ดูแลเลย

สำหรับ UPS รุ่นใหม่ มักจะมี feature ในการ shutdown เครื่องโดยอัตโนมัติ ในกรณีที่ไฟดับ แล้ว ไฟที่สำรองในแบตเตอรี่กำลังจะหมด

สำหรับ Linux อาจจะมีให้เลือกน้อยกว่า Windows เพราะปัญหาเรื่อง driver แต่ก็มีตัวที่สามารถใช้งานได้ เหมือนที่คุณ neutron เขียนไว้ใน blog ที่ debianclub ชือบันทึกว่า หายห่วงเมื่อไฟดับ! ... ซึ่งถ้าไฟเกิดดับขึ้นมา admin ก็ไม่ต้องมากดปุ่ม crtl+alt+del เลย มันจะ shutdown เองโดยอัตโนมัติ และเราสามารถใช้ในลักษณะ master/slave โดยมีตัว ups ที่ต่อกับ server หลักเพียงตัวเดียว เมื่อไฟดับและต้อง shutdown ตัว server หลักก็สามารถส่งคำสั่งไป shutdown เครื่อง server อื่นๆที่เป็น slave ได้เลย 

กลับมาอ่านดูใหม่อีกที ดูเหมือนว่าผมจะไม่ค่อย ฟังใครอื่นเขาพูดจริงๆนั่นแหละ มัวแต่เลือกฟังในเรื่องที่ตนเองสนใจ ทำให้เข้าใจความหมายผิด

เฮ้อ ...

ขอลองตอบใหม่อีกทีครับ ในบันทึกใหม่  ปิดเครือง server โดยใช้วิธีการ Ctrl+Alt+Del
คิดว่าคราวนี้ น่าจะตรงกว่าที่ผ่านๆมา

Ico48
สุริยพงษ์ พรมตอง [IP: 180.183.205.30]
09 September 2015 11:01
#103783

ผมอ่านแล้วโครตสนใจเลยครับ พอดีผมอยากทำ ups สั่งปิด server ตอนไฟดับ คือ ผมขออธิบายถึงภาพการทำงานของ server ผมก่อนนะครับ ผมมี server ประมาณ 10 เครื่อง ต่อกับ ups leonics รุ่น ultra sine 1050 แล้วทีนี้ผมจะซื้อเครื่องสำรองไฟเครื่องใหม่มา ต่อกับ pc แล้วทำการ ทำ script ให้มันสั่ง ปิด server เครื่องที่ต่อกับ ups เดิม server มี os อยู่ คือ linux centos ,windows xp , windown 2003 พอจะมีคำแนะนำไหมครับ

ร่วมแสดงความเห็นในหน้านี้

ชื่อ:
อีเมล:
IP แอดเดรส: 3.219.31.204
ข้อความ:  
เรียกเครื่องมือจัดการข้อความ
   
ยกเลิก หรือ