อ่าน: 3094
ความเห็น: 3
ความเห็น: 3
etherwake ethersleep
ethersleep
On Thu, Dec 13, 2007 at 04:52:27PM +0700, วิศิษฐ โชติอุทยางกูร wrote:>
> เรียนอ.ฉัตรชัย
>
> อ.ครับ ผมทดสอบ program etherwake สามารถ สั่งให้เครื่องเปิดได้ โดยอาศัย
> wake on lan
>
> ถามว่า มี program ที่สามารถ สั่งให้ shutdown ได้มั้ยครับ
> ผมเดาว่า ethersleep หาแล้วไม่มี
ไม่มี ethersleep ครับ
เพราะถ้าเครื่องเปิดอยู่ แล้วใครๆก็สามารถ shutdown เครื่อง
จาก remote ได้โดยการส่ง ethernet packet แบบเดียวกับ
การ wakeup โดยใช้ etherwake แล้วล่ะก้อ คงเป็นเรื่องยุ่ง
พอสมควรทีเดียว เพราะใช้งานอยู่ดีๆ แล้วจู่ๆมีใครก็ไม่รู้ ส่ง
คำสั่งมา shutdown เครื่องเฉยเลย ไฟล์ก็ยังไม่ได้ save
อะไรประมาณนั้น
ถ้าต้องการ shutdown เครื่องที่เป็น linux จะเป็น ubuntu หรือ
ตัวอื่นก็แล้วแต่ วิธีการที่ง่ายที่สุดก็คือ run คำสั่ง shutdown
ถ้าต้องการ shutdown จาก remote host สมมติว่าเป็น
linux ก่อนแล้วกัน เราก็สามารถใช้คำสั่งจาก shell prompt
ได้ โดยการใช้คำสั่ง
$ ssh root@machine1 shutdown -h now
ซึ่งจะ shutdown เครื่องที่ชื่อ machine1 (หรืออาจจะเปลี่ยน
จาก ชื่อเครื่องเป็น ip address ตามความเหมาะสม)
แล้วก็ทำเช่นเดียวกันนี้ กับ machine2, machine3, machine4
ไปเรื่อยๆจนถึง เครื่องสุดท้าย
วิธีการนี้ไม่ดีเท่าไร ด้วยเหตุผล 2-3 อย่าง
1. ใช้ user root สำหรับ remote login (ถึงแม้จะเป็น
secure shell ก็เถอะ)
ปัญหานี้สามารถแก้ได้โดย ไป ติดตั้ง sudo บนเครื่อง
machine1 ถึง machineXX และกำหนดให้ user1
สามารถ run คำสั่ง /sbin/shutdown ได้โดยไม่ต้อง
ใส่ password
แล้วเปลี่ยนคำสั่ง ข้างต้นเป็น
$ ssh user1@machine1 sudo /sbin/shutdown -h now
2. เครื่องคอมพิวเตอร์ที่ต้อง shutdown มีหลายเครื่อง ต้องมานั่ง
พิมพ์คำสั่งสำหรับ shutdown ทีละเครื่อง จนนิ้วหงิก แล้ว
มีโอกาสที่จะพิมพ์ผิดสูง
ปัญหานี้แก้ได้โดยใช้ shell script
ซึ่งเขียนได้ประมาณนี้
#!/bin/sh
LIST="machine1 machine2 machine3 ... machineXX"
for m in $LIST; do
ssh user1@${m} sudo /sbin/shutdown -h now
done
3. ทุกครั้งที่ใช้คำสั่ง ssh ไปเพื่อ shutdown แต่ละเครื่อง
ssh จะถาม password ของ user1 ทุกครั้ง
นั่นคือ ถ้ามี 50 เครื่องที่ต้องการ shutdown ก็จะต้องพิมพ์
password เดิม 50 ครั้ง
ปัญหานี้มีวิธีการแก้หลายวิธี วิธีที่ผมชอบมีอยู่ 2 วิธี
วิธีแรก เปลี่ยนจาก shell script เป็น expect script
แต่วิธีการนี้ จะต้องไปเรียนรู้การเขียน script โดยใช้
ภาษา tcl (ซึ่ง expect เป็นส่วนขยายของ tcl)
ซึ่งคงจะไม่สะดวกสำหรับกรณีนี้
วิธีที่ 2 จะต้องการกระบวนการเพิ่มเติม สำหรับการ setup
ขั้นต้นบนเครื่องแต่ละเครื่องก่อน (ซึ่งถ้าจะว่าไปแล้ว การ
เพิ่ม user ที่ชื่อ user1 และเพิ่ม sudo และ config ของ
sudo ในข้อ 1 ก็จะต้องทำบนเครื่องทุกเครื่องเช่นเดียวกัน)
แต่ถ้า เครื่องทั้งหมด setup โดยวิธีการ clone จาก
source เดียวกัน ก็ไม่น่าจะมีปัญหาซักเท่าไร
นั่นคือ เราจะต้องสร้าง secure shell key หรือ
identity file สำหรับ user1 และจะต้อง copy
ไปเก็บไว้ใน /home/user1/.ssh/ ของเครื่อง
client ที่เราต้องการ remote shutdown
โดยจาก host ที่ admin ใช้งาน (ไม่ใช่ที่เครื่อง
machine1 - machineXX) ใช้คำสั่ง
$ ssh-keygen -t dsa
คำสั่ง ssh-keygen จะถามตำแหน่ง ที่จะให้ save key
และ passphrase (หรือ password นั่นแหละ) สำหรับ
key อันนี้ และให้ยืนยันอีกครั้ง
ถ้าไม่เปลี่ยนตำแหน่งที่จะเก็บ key เราก็จะได้ไฟล์ private
key และ public key ใน ~/.ssh โดยมีชื่อว่า
id_dsa และ id_dsa.pub ตามลำดับ
ให้ copy ไฟล์ id_dsa.pub ไปไว้ใน /home/user1/.ssh
ที่เครื่องปลายทาง (machine1 .. XX) โดยให้มีชื่อว่า
authorized_keys
$ ssh user1@machine1@machine1 mkdir -p .ssh
$ scp ~/.ssh/id_dsa.pub user1@machine1:.ssh/authorized_keys
ในขั้นตอนที่สร้าง secure shell key แล้วถาม passphrase
แล้วเรา เคาะ enter ผ่านทั้งสองครั้ง (ตอนถาม และตอนยืนยัน)
นั่นระบุว่า สำหรับ key นี้ไม่ต้องใช้ passphrase
เราก็จะสามารถใช้ script ในข้อที่แล้วได้เลย โดยไม่จำเป็นต้อง
ใส่ password ใดๆในการเรียกใช้ script ในข้อ 2
แต่อย่างไรก็ตาม วิธีการนี้ไม่ค่อยเหมาะสักเท่าไร
เพราะถ้าวันใดวันหนึ่ง มีคนแอบมาเอาไฟล์ .ssh/id_dsa
ซึ่งเป็น private key ของเราไปได้ เขาก็จะสามารถสั่ง
shutdown เครื่องของเราได้ทั้งหมด โดยไม่จำเป็นต้องมี
รหัสผ่านใดๆ เพราะฉะนั้น key ของเรา จะต้องมี password
หรือ passphrase ป้องกันเอาไว้
แต่ถ้ามี passphrase ทุกครั้งที่เรียกใช้คำสั่ง ssh
ไปยังเครื่องปลายทาง เครื่องปลายทางก็จะถาม passphrase
ทุกครั้ง ซึ่งสำหรับกรณีนี้จะต่างกับกรณีแรก ที่ user1 ไม่มี
.ssh/authorized_key ใน home directory ของเครื่อง
ปลายทาง
กรณีแรก เมื่อ ssh เพื่อส่งคำสั่งไป เครื่องปลายทางจะถาม
system password ของ user1 (ข้อมูลจาก /etc/shadow)
กรณีที่สอง เมื่อ ssh ไป เครื่องปลายทางจะถาม passphrase
ซึ่งจะนำไปใช้กับ ~user1/.ssh/authorized_keys
ดูเหมือนว่าการใส่ passphrase ให้กับ secure shell key
จะทำให้เราไม่ก้าวหน้าไปเท่าไร แต่ไม่ใช่ เพราะ secure shell
มี agent ซึ่งจะทำให้เราสามารถ ใส่ passphrase เพียงครั้งเดียว
แล้วหลังจากนั้น เมื่อให้คำสั่ง อย่างเช่น ssh หรือ scp
ไปยังเครื่องปลายทางที่มี .ssh/authorized_keys ของ user
ที่เรา secure connect ไป ตัว agent ก็จะส่ง passphrase
ให้แทนเรา
เครื่องมือสำหรับ ช่วยจัดการ key และ setup agent ผมใช้
package ที่ชื่อว่า keychain โดยการติดตั้ง keychain
และเพิ่ม
if [ -x /usr/bin/keychain ]; then
keychain -q id_dsa
. ~/.keychain/`uname -n`-sh
fi
เข้าไปใน .bashrc -- ผมใช้ bash เป็น default shell
keychain ก็จะถาม passphrase เพียงครั้งเดียวคือตอน
login เข้าครั้งแรก หลังจากนั้น การติดต่อไปยังเครื่อง
ปลายทางที่มี .ssh/authorized_keys ก็จะจัดการโดย
ssh-agent โดยอัตโนมัติ ไม่จำเป็นต้องใส่ passphrase
อีกต่อไป
ถ้าตรงใหนผมเขียนไปแล้ว อ่านแล้วงง ไม่เข้าใจ ช่วยถามมาใหม่
อีกครั้งครับ
ฉัตรชัย
> ขอคำปรึกษาด้วยครับ
>
> คือว่า ผมเขียน script แล้ว สั่ง etherwake ตามด้วย mac ของ ห้อง lab
> เพื่อเปิดเครื่อง
> (etherwake สั่งจาก ubuntu => client xp)
>
> แต่เวลา ปิดเครื่อง ทำไม่เป็นครับ
>
> ต้องการ shutdown จาก ubuntu => client xp
>
> ขอบคุณครับ
>
> pomdent (วิศิษฐ)
sudo ในข้อ 1 ก็จะต้องทำบนเครื่องทุกเครื่องเช่นเดียวกัน)
แต่ถ้า เครื่องทั้งหมด setup โดยวิธีการ clone จาก
source เดียวกัน ก็ไม่น่าจะมีปัญหาซักเท่าไร
นั่นคือ เราจะต้องสร้าง secure shell key หรือ
identity file สำหรับ user1 และจะต้อง copy
ไปเก็บไว้ใน /home/user1/.ssh/ ของเครื่อง
client ที่เราต้องการ remote shutdown
โดยจาก host ที่ admin ใช้งาน (ไม่ใช่ที่เครื่อง
machine1 - machineXX) ใช้คำสั่ง
$ ssh-keygen -t dsa
คำสั่ง ssh-keygen จะถามตำแหน่ง ที่จะให้ save key
และ passphrase (หรือ password นั่นแหละ) สำหรับ
key อันนี้ และให้ยืนยันอีกครั้ง
ถ้าไม่เปลี่ยนตำแหน่งที่จะเก็บ key เราก็จะได้ไฟล์ private
key และ public key ใน ~/.ssh โดยมีชื่อว่า
id_dsa และ id_dsa.pub ตามลำดับ
ให้ copy ไฟล์ id_dsa.pub ไปไว้ใน /home/user1/.ssh
ที่เครื่องปลายทาง (machine1 .. XX) โดยให้มีชื่อว่า
authorized_keys
$ ssh user1@machine1@machine1 mkdir -p .ssh
$ scp ~/.ssh/id_dsa.pub user1@machine1:.ssh/authorized_keys
ในขั้นตอนที่สร้าง secure shell key แล้วถาม passphrase
แล้วเรา เคาะ enter ผ่านทั้งสองครั้ง (ตอนถาม และตอนยืนยัน)
นั่นระบุว่า สำหรับ key นี้ไม่ต้องใช้ passphrase
เราก็จะสามารถใช้ script ในข้อที่แล้วได้เลย โดยไม่จำเป็นต้อง
ใส่ password ใดๆในการเรียกใช้ script ในข้อ 2
แต่อย่างไรก็ตาม วิธีการนี้ไม่ค่อยเหมาะสักเท่าไร
เพราะถ้าวันใดวันหนึ่ง มีคนแอบมาเอาไฟล์ .ssh/id_dsa
ซึ่งเป็น private key ของเราไปได้ เขาก็จะสามารถสั่ง
shutdown เครื่องของเราได้ทั้งหมด โดยไม่จำเป็นต้องมี
รหัสผ่านใดๆ เพราะฉะนั้น key ของเรา จะต้องมี password
หรือ passphrase ป้องกันเอาไว้
แต่ถ้ามี passphrase ทุกครั้งที่เรียกใช้คำสั่ง ssh
ไปยังเครื่องปลายทาง เครื่องปลายทางก็จะถาม passphrase
ทุกครั้ง ซึ่งสำหรับกรณีนี้จะต่างกับกรณีแรก ที่ user1 ไม่มี
.ssh/authorized_key ใน home directory ของเครื่อง
ปลายทาง
กรณีแรก เมื่อ ssh เพื่อส่งคำสั่งไป เครื่องปลายทางจะถาม
system password ของ user1 (ข้อมูลจาก /etc/shadow)
กรณีที่สอง เมื่อ ssh ไป เครื่องปลายทางจะถาม passphrase
ซึ่งจะนำไปใช้กับ ~user1/.ssh/authorized_keys
ดูเหมือนว่าการใส่ passphrase ให้กับ secure shell key
จะทำให้เราไม่ก้าวหน้าไปเท่าไร แต่ไม่ใช่ เพราะ secure shell
มี agent ซึ่งจะทำให้เราสามารถ ใส่ passphrase เพียงครั้งเดียว
แล้วหลังจากนั้น เมื่อให้คำสั่ง อย่างเช่น ssh หรือ scp
ไปยังเครื่องปลายทางที่มี .ssh/authorized_keys ของ user
ที่เรา secure connect ไป ตัว agent ก็จะส่ง passphrase
ให้แทนเรา
เครื่องมือสำหรับ ช่วยจัดการ key และ setup agent ผมใช้
package ที่ชื่อว่า keychain โดยการติดตั้ง keychain
และเพิ่ม
if [ -x /usr/bin/keychain ]; then
keychain -q id_dsa
. ~/.keychain/`uname -n`-sh
fi
เข้าไปใน .bashrc -- ผมใช้ bash เป็น default shell
keychain ก็จะถาม passphrase เพียงครั้งเดียวคือตอน
login เข้าครั้งแรก หลังจากนั้น การติดต่อไปยังเครื่อง
ปลายทางที่มี .ssh/authorized_keys ก็จะจัดการโดย
ssh-agent โดยอัตโนมัติ ไม่จำเป็นต้องใส่ passphrase
อีกต่อไป
ถ้าตรงใหนผมเขียนไปแล้ว อ่านแล้วงง ไม่เข้าใจ ช่วยถามมาใหม่
อีกครั้งครับ
ฉัตรชัย
> ขอคำปรึกษาด้วยครับ
>
> คือว่า ผมเขียน script แล้ว สั่ง etherwake ตามด้วย mac ของ ห้อง lab
> เพื่อเปิดเครื่อง
> (etherwake สั่งจาก ubuntu => client xp)
>
> แต่เวลา ปิดเครื่อง ทำไม่เป็นครับ
>
> ต้องการ shutdown จาก ubuntu => client xp
>
> ขอบคุณครับ
>
> pomdent (วิศิษฐ)
สร้าง: 13 ธันวาคม 2550 23:22
แก้ไข: 21 มิถุนายน 2552 14:39
[ แจ้งไม่เหมาะสม ]
บันทึกอื่นๆ
- ใหม่กว่า » remote shutdown เครื่อง โดยไม่ต้...
ความเห็น
![]() |
ขอสอบถามอาจารย์บ้างครับพอดีผมมีเคสใกล้เคียงแบบนี้ แต่ว่าผมอยากให้คนอื่นสามารถ Shutdown ได้กรณีที่ไฟดับ เพราะ UPS มันจะสามารถสำรองไฟได้ไม่นานมาก บางครั้งไฟชอบดับช่วงดึกๆ นาน ทำให้บางทีเครื่องดับไปเลย ถ้ากรณีอย่างนี้มีการเขียนสคริป์อะไรให้สามารถสั่ง shutdown ด้วยคีย์ลัดแบบไม่ต้อง login เข้า root ก่อนหรือเปล่าครับเพราะเซิร์ฟเวอร์ผมแต่ละเครื่องไม่ได้ต่อจอไว้เลย แถมตั้งอยู่คนละที่อีกต่างหาก
คำตอบค่อนข้างยาว ผมเลยไปเขียนไว้ในบันทึกใหม่ครับ อยู่ที่
remote shutdown เครื่อง โดยไม่ต้องใช้ root account
หวังว่าคงตอบตรงคำถาม (รึเปล่า?)
13 ธันวาคม 2550 23:57
#4517