วิธีการใส่รหัสผ่านเพียงครั้งเดียวในสคริปต์ทุบตีต้องใช้ sudo


21

ข้อมูล

  • ฉันต้องการให้ผู้ใช้โอเปอเรเตอร์บนเครื่องนี้ติดตั้ง cifs ของตัวเอง
  • sudoersไฟล์แล้วมี/bin/mount -t cifs //*/* /media/* -o username=*คำสั่งสำหรับผู้ประกอบการทั้งหมด
  • ฉันต้องการให้ผู้ใช้เมาcifsนต์แชร์ผ่านสคริปต์ที่พิมพ์รหัสผ่านเพียงครั้งเดียวไม่ใช่สองครั้ง
  • รหัสผ่าน sudo และรหัสผ่าน cifs เหมือนกัน

สิ่งที่ฉันมีอยู่แล้ว

สคริปต์นี้ใช้งานได้:

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... แต่ผู้ใช้ต้องพิมพ์รหัสผ่านเดียวกันสองครั้ง!

  • ครั้งเดียวสำหรับ sudo
  • ครั้งหนึ่งสำหรับเขานั้นเอง

สิ่งนี้จะได้ผล:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... แต่สิ่งนี้จะทำให้ฉันต้องอนุญาตให้ผู้ใช้โอเปอเรเตอร์ทุกคนสามารถsudo sh (ปัญหาด้านความปลอดภัยที่สำคัญ)

คำถาม

วิธีการติดตั้งส่วนแบ่ง CIFS ในทุบตี ¹โดยไม่ต้องใส่shในsudoersไฟล์หรือสร้างไฟล์ถาวร / ชั่วคราว ???

หมายเหตุ 1:ไม่มีไพ ธ อน, Perl, C, Go, ... ได้โปรด?
หมายเหตุ 2:ฉันรู้ว่าฉันสามารถลบรหัสผ่านผ่านsudoersไฟล์ได้ แต่ฉันพยายามกระชับความปลอดภัยไม่คลายมันโดยไม่ยอมแพ้ ...


2
แล้วไงprintf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...ล่ะ
muru

ลองตอนนี้! @Muru
Fabby

คำตอบ:


24

คุณควรทำให้ผู้ใช้ทำการเรียกใช้ sudo sudo scriptแทน เพียงตรวจสอบว่าสคริปต์นั้นถูกเรียกใช้เป็นรูทหรือไม่ถ้าไม่ขอ

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

อย่าพยายามเก็บรหัสผ่านของผู้ใช้ของคุณ


1
บางทีฉันหายไปบางอย่าง แต่คุณสามารถอธิบายได้ว่าวิธีนี้ช่วยลดจำนวนรหัสผ่านที่แจ้งจากสองเป็นหนึ่งได้อย่างไร มิฉะนั้นฉันไม่เห็นว่าสิ่งนี้ตอบคำถามได้อย่างไร
Oliphaunt - คืนสถานะโมนิก้า

@Oliphaunt ฉันไม่เห็นข้อความแจ้งรหัสผ่านสองตัวคุณอธิบายได้ไหม นอกจากนี้คำตอบนี้ไม่ใช่สิ่งที่ OP ต้องการ แต่สิ่งที่ต้องการ สะอาดและทางออกที่เหมาะสมเมื่อคุณจำเป็นต้องเรียกใช้คำสั่งเป็นรากและวิธีการสาธารณูปโภคอื่น ๆ (ตรวจสอบว่ารากมิฉะนั้นประกันตัวออก)
Braiam

1
ปัญหาของ OP (ที่ผมเข้าใจมัน) คือผู้ใช้จะได้รับแจ้งให้ใส่รหัสผ่านของพวกเขาโดยsudoแล้ว (เมื่อประสบความสำเร็จในการตรวจสอบ) mountอีกครั้งโดย ในกรณีที่ใช้รหัสผ่านเหล่านี้เหมือนกันดังนั้นฉันจึงเห็นได้ว่าเหตุใด OP ต้องการให้ผู้ใช้ป้อนรหัสผ่านนี้เพียงครั้งเดียว ฉันไม่เชื่อว่าทางออกของคุณจะช่วยได้ ฉันยอมรับว่าไม่ควรเก็บรหัสผ่าน
Oliphaunt - คืนสถานะโมนิก้า

ขอบคุณ แต่ฉันอาจใช้คำถามแบบธรรมดาไปหน่อย: มันเป็นสคริปต์อยู่แล้วมีการทดสอบนั้น (ยกเว้น1>&2) อยู่ใน autostart และมันเคยเป็นแค่หนึ่ง cifs แบ่งปัน แต่ตอนนี้มันเป็นสามดังนั้นจริงๆรหัสผ่านเดียวมันจำเป็น. (มันมีการทดสอบนั้นอยู่แล้วในกรณีที่คนอื่นไม่ใช่สมาชิกของกลุ่มโอเปอเรเตอร์พยายามเรียกใช้)
Fabby

@ Fabby ฉันยังคิดว่าคุณกำลังเข้าใกล้ปัญหาอย่างไม่ถูกต้อง สำหรับกรณีเหล่านี้มีตัวช่วยในการ "จดจำ" รหัสผ่านของการแบ่งปัน CIFS / SMB อย่างปลอดภัย (แก้ไข~/.smbcredentialsตัวอย่าง) และแม้ไม่จำเป็นต้องใช้ sudo (ถ้าคุณใช้ gvfs, umount หรือ polkit)
Braiam

7

ฉันเป็นใบ้!

สคริปต์ต่อไปนี้:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

เพิ่งใช้งานได้และ:

  1. ไม่สร้างไฟล์ใด ๆ ที่มีรหัสผ่าน
  2. อนุญาตให้ผู้ใช้พิมพ์รหัสผ่านเดียวสำหรับการแชร์หลาย ๆ ครั้ง (รวมถึงรหัส Windows)
  3. ไม่จำเป็นต้องมีสิทธิ์พิเศษที่จะได้รับ :-)

1
1 คำถาม: นั่นสะท้อนคำสั่งในรายการกระบวนการหรือไม่?
Rinzwind

3
@ Rinzwind ในตัวมันไม่ควรจะเป็น bash หรือ zsh แม้ว่าคำสั่ง mount สามารถทำได้
muru

<<<สามารถใช้แทนได้printf แต่วิธีที่ดีกว่าคือการทิ้งreadทั้งหมดและใช้sudo --stdinด้วยตัวเองทั้งหมด บางอย่างเช่น$ printf "Type out your password\n" && sudo --stdin apt-get update ผู้ใช้ยังสามารถพิมพ์รหัสผ่าน sudo และนั่นจะไม่นำไปไว้ในรายการกระบวนการ แต่แน่นอนว่ายังมีปัญหาด้านความปลอดภัยอื่น ๆ อีกมากมายเช่น keyloggers ช่องโหว่ที่อาจเกิดขึ้นsudoและ blah และ blah และ blah สู่ infinity
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy: รู้สึกอิสระที่จะแก้ไขผู้ชาย!
Fabby

3

ไม่ต้องใช้sudoรหัสผ่านสำหรับการดำเนินการคำสั่งนี้ พรอมต์รหัสผ่านสำหรับmountยังคงอยู่

ในsudoersรวมสิ่งที่ชอบ

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

หลังจากรวมสิ่งนี้แล้วsudoจะไม่ถามรหัสผ่านสำหรับคำสั่งเฉพาะนี้อีกต่อไป ผู้ใช้ยังคงต้องให้รหัสผ่านกับmountคำสั่ง

หมายเหตุ : ฉันใช้คำต่อคำจากสิ่งที่คุณรวมไว้ในคำถาม; ฉันไม่ได้ตรวจสอบว่าอักขระตัวแทนจะอนุญาตให้ผู้ใช้ทำสิ่งที่น่ารังเกียจหรือไม่ อ่านsudoersmanpage เพื่อดูตัวอย่างความน่ารังเกียจ โดยเฉพาะอย่างยิ่งทราบว่าสายนี้ในการsudoersช่วยให้ผู้ใช้ในการเพิ่มจำนวนของ-oสวิทช์หรือข้อโต้แย้งอื่น ๆ mountที่จะ คุณอาจต้องการคิดทบทวนแนวทางของคุณใหม่เช่นโดยการเพิ่มสคริปต์เช่น @Braiam เสนอและอนุญาตให้ใช้งานได้sudoโดยไม่ต้องมีการตรวจสอบสิทธิ์เพิ่มเติม จากนั้นสคริปต์จะตรวจสอบให้แน่ใจว่าผู้ใช้สามารถเรียกใช้เฉพาะรูปแบบmountที่คุณต้องการให้เรียกใช้

นอกจากนี้แทนที่จะอนุญาตให้ใช้สำหรับผู้ใช้ทั้งหมดคุณสามารถ จำกัด สิ่งนี้ให้กับสมาชิกของกลุ่มใดกลุ่มหนึ่งเช่นคุณสามารถสร้างกลุ่มcifsmountแล้วมี

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

@ Fabby ขออภัย แต่สิ่งที่อันตรายเกี่ยวกับเรื่องนี้? นอกจากนี้ฉันอาจจะตรวจพบคำใบ้ของการเสียดสีไม่แน่ใจ
Oliphaunt - คืนสถานะโมนิก้า

ดีแม้ว่า sudo ไม่ต้องการรหัสผ่านการเมาท์อาจยังต้องใช้รหัสผ่าน ไฟล์ / etc / sudoers สามารถใช้เพื่อทำให้ sudo ไม่ต้องใช้รหัสผ่าน นั่นจะไม่ส่งผลกระทบต่อการเมานต์ถามรหัสผ่าน หากบุคคลไม่สามารถเมานต์ได้ sudo จะจบลงด้วยการเรียกใช้คำสั่งที่ล้มเหลวซึ่งน่าจะไม่ใช่ปัญหา
TOOGAM

@TOOGAM นั่นคือความตั้งใจของฉัน รหัสผ่านเดียวแทนที่จะเป็นสอง
Oliphaunt - คืนสถานะโมนิก้า

ความตั้งใจของฉันคือการเก็บกลุ่ม "โอเปอเรเตอร์" หนึ่งกลุ่มไว้ในไฟล์ sudoers ดังนั้นหากโอเปอเรเตอร์พยายามที่จะเมานต์ข้อมูลของตัวเองพวกเขายังคงต้องพิมพ์รหัสผ่าน แต่หากต้องการเมานต์โอเปอเรเตอร์ ครั้งเดียวแทน 5 ครั้ง ... แต่การทำงานอาจจะแก้ปัญหาของคุณสำหรับคนอื่น ๆ upvoted ดังนั้น ... (และความคิดเห็นของเดิมออก)
Fabby

1

วิธีแก้ไขปัญหาทั่วไปสำหรับปัญหาเหล่านี้คือการนำคำนำหน้าต่อไปนี้มาไว้บนสุดของ sudo ที่ต้องการสคริปต์:

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

เห็นได้ชัดว่านี่เป็นข้อเสียที่ถ้าคำสั่งบางอย่างในสคริปต์ไม่จำเป็นต้องsudoเรียกใช้จะมีสิทธิ์ระดับสูงที่ไม่จำเป็นที่นี่

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

คุณอาจต้องการตรวจสอบtimestamp_timeoutตัวแปรman 5 sudoersที่บอกsudoให้จำข้อมูลรับรองผู้ใช้เป็นเวลา จำกัด จำนวนนาที (และอาจเป็นเศษส่วน)


ฉันใช้สคริปต์มากเกินไปเพื่อให้ได้คำตอบที่ง่าย: สคริปต์มีอยู่แล้ว: #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi ประเด็นก็คือมันยังมีการเมานต์หลายตัวทั้งหมดด้วยรหัสผ่านเดียวกัน (อีกครั้ง: ถูกลบ) แต่ขอบคุณด้วย ...
Fabby

1
ประเด็นก็คือการแก้ปัญหาข้างต้นจะต้องพิมพ์รหัสผ่านเพียงครั้งเดียว (สำหรับ sudo) ไม่ควรต้องการสิ่งอื่นใด นอกจากนี้ยังเป็นเรื่องทั่วไป (และสวยงามกว่าการให้ข้อผิดพลาดและต้องพิมพ์คำสั่งด้วย sudo อีกครั้ง) สำหรับปัญหาที่คล้ายกันทั้งหมดแม้ว่าพวกเขาต้องการคำสั่งที่มีสิทธิพิเศษหลายรายการ (มากกว่าสอง)
arielf

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