วิธีการบังคับใช้รหัสผ่าน sudo สำหรับคำสั่งเฉพาะเสมอ


12

เมื่อวันก่อนฉันทำงานบำรุงรักษาบางอย่างบนเว็บเซิร์ฟเวอร์ของฉัน ฉันรีบและง่วงนอนดังนั้นฉันจึงทำทุกอย่างโดยใช้sudoคำสั่ง

จากนั้นฉันกดCtrl+ โดยไม่ตั้งใจVส่งคำสั่งนี้ไปยังเว็บเซิร์ฟเวอร์ของฉัน:

sudo rm -rf /*

สำหรับผู้ที่สงสัยว่าคำสั่งดังกล่าวทำอะไร: สิ่งนี้ลบเว็บเซิร์ฟเวอร์ทั้งหมดของฉัน

โชคดีที่ฉันมีข้อมูลสำรองและเศร้าฉันต้องใช้เวลาอีกสองชั่วโมงในการตื่นเพื่อแก้ไขข้อผิดพลาดที่น่ากลัวนี้ แต่ตั้งแต่นั้นมาฉันก็สงสัยว่า:

มีวิธีในการบังคับใช้รหัสผ่าน sudo สำหรับคำสั่งเฉพาะหรือไม่

หากเซิร์ฟเวอร์ขอรหัสผ่านฉันจะช่วยตัวเองให้พ้นจากปัญหามากมาย มันไม่ได้เพราะฉันวิ่งไปประมาณ 5 sudoคำสั่งก่อนที่ข้อผิดพลาดอันยิ่งใหญ่นี้

ดังนั้นมีวิธีที่จะทำมันได้หรือไม่ ฉันแค่ต้องการรหัสผ่านพร้อมrmคำสั่งเพื่อบังคับใช้เสมอ คำสั่งอื่น ๆ ที่ฉันใช้มักจะเป็นnanoหรือcpที่ทั้งคู่เป็น (กลับกันได้บ้าง)



2
@solsTiCe /*ถูกขยายก่อนที่จะถูกส่งไปยังคำสั่ง rm ดังนั้นคำสั่งจะไม่เห็นอาร์กิวเมนต์เดี่ยว แต่รายการอาร์กิวเมนต์ ( /bin /boot /cdrom /dev /etc /home... )
Dan

3
บทเรียนสำคัญอย่างหนึ่งที่ควรหลีกเลี่ยงคือคุณไม่ควรทำสิ่งต่าง ๆ ด้วย sudo เว้นแต่คุณต้องการจริงๆ ฉันรู้ว่าไม่ตอบสิ่งที่คุณถามที่นี่ แต่คำถามที่ครอบคลุมคือวิธีการ (หวังว่า) ป้องกันตัวเองจากการลบเซิร์ฟเวอร์ของคุณอีกครั้งและการหลีกเลี่ยง sudo ควรเป็นแนวป้องกันแรกของคุณ
David Z


2
@ WinEunuuchs2Unix นั่นไม่ใช่คำถามที่ซ้ำกันเลย op ที่นี่ไม่ต้องการให้rmคำสั่งมีรหัสผ่าน พวกเขาต้องการที่sudoจะถามหนึ่งครั้งทุกครั้งที่ใช้คำสั่ง rm sudo rmวิธีการแก้ปัญหาให้กับคำถามที่คุณเชื่อมโยงก็จะกลายเป็นน่ารำคาญเล็กน้อยเมื่อคำสั่งแรกคุณคือ ในขณะที่มันจะขอรหัสผ่านสองหนึ่งสำหรับหนึ่งสำหรับsudo rm
ด่าน

คำตอบ:


17

คุณสามารถตั้งค่าtimestamp_timeoutการสำหรับคำสั่งโดยเฉพาะอย่างยิ่ง0 /etc/sudoersสร้างไฟล์ที่visudo -f /etc/sudoers.d/pduckมีเนื้อหาดังต่อไปนี้:

Cmnd_Alias DANGEROUS = /bin/rm

Defaults!DANGEROUS timestamp_timeout=0

pduck ALL = (ALL:ALL) DANGEROUS

ตอนนี้ผู้ใช้pduckจะถามรหัสผ่านเสมอเมื่อเรียกใช้sudo rm(ไม่ว่าจะมีพารามิเตอร์เพิ่มเติมใด) แม้ว่าผู้ใช้จะเป็นสมาชิกของsudoกลุ่มและsudoจดจำรหัสผ่านของเขาสำหรับคำสั่งอื่น ๆ

ข้อเสียคือคุณไม่สามารถเพิ่มพารามิเตอร์ลงใน/bin/rmบรรทัดในไฟล์เพื่อ จำกัด สิ่งนี้ได้อีก ก็…คุณทำได้เช่น:

Cmnd_Alias DANGEROUS = /bin/rm -f

แต่จากนั้นคุณจะได้รับพร้อมต์สำหรับตัวอย่างเช่นsudo rm -fและไม่ใช่ (อีกครั้ง) sudo rm -rfอย่างแน่นอน


9

วิธีการหนึ่งที่จะใช้ปลอดภัย RM นี่จะเป็นการใช้งาน "rm" เท่านั้นและป้องกันไม่ให้เรียกใช้ "rm" รุ่นที่เฉพาะเจาะจง ซึ่งรวมถึงการลบระบบรูทของคุณ แต่ยังสามารถใช้เพื่อป้องกันการลบไดเรกทอรีที่เกี่ยวข้องกับระบบเช่น "/ usr /" หรือ "/ var /" จากลิงค์:

การคืนค่าการลบไฟล์สำคัญโดยไม่ตั้งใจ

Safe-rm เป็นเครื่องมือด้านความปลอดภัยที่มีวัตถุประสงค์เพื่อป้องกันการลบไฟล์สำคัญโดยไม่ตั้งใจโดยแทนที่/bin/rmด้วย wrapper ซึ่งตรวจสอบข้อโต้แย้งที่กำหนดกับบัญชีดำของไฟล์และไดเรกทอรีที่กำหนดค่าได้ซึ่งไม่ควรลบออก

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

$ rm -rf /usr   
Skipping /usr

(เส้นทางที่ได้รับการป้องกันสามารถตั้งค่าได้ทั้งในระดับไซต์และผู้ใช้)

การกู้คืนไฟล์สำคัญที่คุณลบโดยไม่ได้ตั้งใจอาจเป็นเรื่องยาก ป้องกันตัวเองวันนี้ด้วยการติดตั้ง safe-rm และลดโอกาสที่คุณจะต้องติดต่อบริการกู้คืนข้อมูล!

ป้อนคำอธิบายรูปภาพที่นี่


ได้รับการโหวตให้ขึ้นสู่ความปลอดภัย
Michael Fulton

3

sudoมีตัวเลือก-k, --reset-timestampให้ดูman sudo:

เมื่อใช้ร่วมกับคำสั่งหรือตัวเลือกที่อาจต้องใช้รหัสผ่านตัวเลือกนี้จะทำให้ sudo ไม่สนใจข้อมูลประจำตัวที่แคชของผู้ใช้ ดังนั้น sudo จะขอรหัสผ่าน (หากจำเป็นต้องใช้นโยบายความปลอดภัย) และจะไม่อัปเดตข้อมูลประจำตัวที่แคชของผู้ใช้

คุณสามารถเขียน wrapper ง่าย ๆ สำหรับsudoทดสอบrm -rf /*และใช้งานได้

sudo -k rm -rf /*

แทนเช่นนี้:

sudo ()                                                                                                                                                 
{ 
    [[ "$*" == "rm -rf /*" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

ตัวอย่างการใช้งาน

ทดสอบกับecho aที่นี่

$ sudo echo
[sudo] password for dessert: 

$ sudo echo

$ sudo echo a
[sudo] password for dessert: 
a
$ sudo echo a
[sudo] password for dessert: 
a

หากคุณต้องการให้มีการถามทุกครั้งที่คุณเรียกใช้rmโดยทั่วไปคุณสามารถปรับฟังก์ชั่นด้านบนดังนี้:

sudo () 
{ 
    [[ "$1" == "rm" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

หากคุณต้องการรวมทั้งการเรียกคำสั่งทั่วไปและบรรทัดคำสั่งเฉพาะที่ฉันแนะนำให้ใช้caseเช่น:

sudo () 
{ 
    case "$*" in 
        rm*)            opt="-k" ;;
        "mv /home"*)    opt="-k" ;;
        "ln -s /usr/bin/fish /bin/sh") opt="-k" && echo "Don't you dare!" ;;
        *)              opt="" ;;
    esac;
    /usr/bin/sudo $opt "$@"
}

โปรดทราบว่าวิธีการเหล่านี้จะไม่ทำงานถ้าคุณทำงานsudoกับตัวเลือก - การแก้ปัญหาที่เป็นไปได้[[ "$*" =~ " rm " ]]เพื่อตรวจสอบสตริง“RM” ล้อมรอบด้วยช่องว่างหรือ*" rm "*)มีcaseการจับบรรทัดคำสั่งใด ๆ ที่มี“RM”


[[ "$1" == "rm" ]] && opt="-k";แล้วจะเป็น/bin/rmอย่างไร
Rinzwind

@ Rinzwind ฉันคิดว่าฟังก์ชั่นสามารถปรับเปลี่ยนได้อย่างง่ายดายตามความต้องการเฉพาะโดยเฉพาะอย่างยิ่งcaseวิธีการ
ของหวาน

1

คำตอบนี้ไม่ได้อยู่ที่sudoเป็นส่วนหนึ่งของคำถามของคุณ แต่ในทางกลับกันมันอยู่ที่วิธีการลดอันตรายจากอุบัติเหตุที่rmสวดสำหรับใด ๆของผู้ใช้

คุณสามารถนามแฝงrmไปrm -Iที่

  • ขอให้ยืนยันทันทีที่มันจะลบไดเรกทอรีหรือมากกว่า 3 ไฟล์
  • ตราบใดที่คุณยังไม่ได้ใช้-f-Iตัวเลือกก่อนหน้านี้

--one-file-systemเป็นอีกการป้องกันที่เป็นไปได้ต่อการลบโดยไม่ตั้งใจที่ฉันใช้ในrmนามแฝง

ติดตั้ง

ในการสร้างนามแฝงดังกล่าวให้ใช้คำสั่ง:

alias rm='rm -I --one-file-system'

คุณสามารถใส่ไว้ในของคุณหรือแม้กระทั่ง~/.bashrc/etc/bash.bashrc

การใช้

$ sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?

ประเภทการยืนยันหรือการแปลของมันเข้าไปในสถานที่ของคุณหรือตัวอักษรตัวแรกของคำทั้งสองและกดyes Enterอินพุตอื่นใดรวมถึงไม่มีการยกเลิกการดำเนินการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.