วิธีที่เหมาะสมในการให้ผู้ใช้ป้อนรหัสผ่านสำหรับสคริปต์ทุบตีโดยใช้เฉพาะ GUI (ที่ซ่อนเทอร์มินัล)


8

ฉันได้สร้างสคริปต์ทุบตีที่ใช้ kdialog เฉพาะสำหรับการโต้ตอบกับผู้ใช้ มันถูกเปิดตัวจากไฟล์ ".desktop" เพื่อให้ผู้ใช้ไม่เคยเห็นเทอร์มินัล ดูเหมือน 100% เหมือนแอป GUI (แม้ว่าจะเป็นเพียงสคริปต์ทุบตี) มันทำงานใน KDE เท่านั้น (Kubuntu 12.04)

ปัญหาเดียวของฉันคือจัดการรหัสผ่านให้ปลอดภัยและสะดวก ฉันไม่สามารถหาทางออกที่น่าพอใจ

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

ปัญหาหลักคือการใช้kdesudoเพื่อเปิดสคริปต์ของฉันซึ่งเป็นวิธี GUI มาตรฐานหมายความว่าสคริปต์ทั้งหมดจะถูกดำเนินการโดยผู้ใช้รูท ดังนั้นความเป็นเจ้าของไฟล์จึงถูกกำหนดให้กับผู้ใช้รูทฉันไม่สามารถพึ่งพา~/ในพา ธ ได้และสิ่งอื่น ๆ อีกมากมายนั้นน้อยกว่าอุดมคติ การรันสคริปต์ทั้งหมดในฐานะผู้ใช้รูทเป็นเพียงโซลูชันที่ไม่น่าพอใจและฉันคิดว่านี่เป็นวิธีปฏิบัติที่ไม่ดี

ฉันขอขอบคุณแนวคิดใด ๆ ที่ให้ผู้ใช้ป้อนรหัสผ่าน sudo เพียงครั้งเดียวผ่านทาง GUI ในขณะที่ไม่ได้ใช้สคริปต์ทั้งหมดในฐานะที่เป็นรูท ขอบคุณ

คำตอบ:


14

-Aตัวเลือก sudo ช่วยให้คุณระบุโปรแกรมผู้ช่วย (ในตัวแปร SUDO_ASKPASS) ที่จะขอรหัสผ่าน

สร้างสคริปต์เพื่อถามรหัสผ่าน (myaskpass.sh):

#!/bin/bash
zenity --password --title=Authentication

จากนั้นแทรกบรรทัดนี้ที่จุดเริ่มต้นของสคริปต์ของคุณ:

export SUDO_ASKPASS="/path/to/myaskpass.sh"

และแทนที่สิ่งที่เกิดขึ้นทั้งหมดsudo <command>ด้วย:

sudo -A <command>

zenityคุณสามารถใช้สิ่งที่รหัสผ่านขอโปรแกรมที่คุณต้องการแทน ผมต้องแค็ปซูลได้ภายในสคริปต์เพราะ SUDO_ASKPASS ต้องชี้ไปยังแฟ้มดังนั้นมันจะไม่ทำงานร่วมกับตัวเลือกที่จำเป็นโดย--passwordzenity

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


หากคุณไม่ต้องการที่หน้าต่าง terminal sudo -Sที่ทุกท่านสามารถจัดเก็บรหัสผ่านในตัวแปรและท่อไปยัง อาจมีข้อกังวลด้านความปลอดภัย แต่ฉันคิดว่ามันค่อนข้างปลอดภัย (อ่านความคิดเห็นในคำตอบนี้ )

แทรกบรรทัดนี้ที่จุดเริ่มต้นของสคริปต์ของคุณ:

PASSWD="$(zenity --password --title=Authentication)\n"

และแทนที่สิ่งที่เกิดขึ้นทั้งหมดsudo <command>ด้วย:

echo -e $PASSWD | sudo -S <command>

ขอบคุณ. นั่นเป็นเรื่องที่น่าสนใจมาก อย่างไรก็ตามเมื่อใช้สิ่งนี้การหมดเวลาปกติของ sudo (เช่น 15 นาที) จะหายไป สคริปต์ของฉันที่มีคำสั่ง sudo มากกว่า 50 คำสั่งจะให้ใส่รหัสผ่านของผู้ใช้ 50+ ครั้ง! ฉันไปรอบ ๆ และฉันไม่เห็นวิธีแก้ปัญหา คุณรู้จักหรือไม่
MountainX

ขอบคุณสำหรับการอัพเดท. ทางเลือกที่คุณแนะนำคือสิ่งที่ฉันได้ตัดออกไปเนื่องจากความกังวลด้านความปลอดภัย แต่จากการอ่านความคิดเห็นที่ลิงก์ที่คุณให้ฉันคิดว่ามันน่าจะปลอดภัยพอ และเป็นวิธีที่ง่ายในการแก้ไขปัญหา ขอบคุณ.
MountainX

การทดสอบในระบบของฉันจะต้องเป็นsudo -s(ตัวพิมพ์เล็กs) และไม่sudo -S(ตัวพิมพ์ใหญ่s)
WinEunuuchs2Unix

0

นี่คือคำตอบที่ยอดเยี่ยมของ Eric Carvalho ฉันโพสต์มันเพื่ออธิบายรายละเอียดเกี่ยวกับปัญหาที่ฉันพบ โดยเฉพาะเมื่อใช้สิ่งนี้การหมดเวลา sudo ปกติ (เช่น 15 นาที) จะหายไป สคริปต์ของฉันที่มีคำสั่ง sudo มากกว่า 50 คำสั่งจะให้ใส่รหัสผ่านของผู้ใช้ 50+ ครั้ง!

นี่คือตัวอย่างการทำงานที่สมบูรณ์ของทุกส่วนของโซลูชัน ประกอบด้วยสคริปต์ทุบตีสคริปต์ "myaskpass" ตามที่ Eric แนะนำและไฟล์ ".desktop" สิ่งทั้งหมดควรเป็น 100% GUI (ไม่มีการโต้ตอบกับเทอร์มินัลเลย) ดังนั้นไฟล์ .desktop จึงเป็นสิ่งจำเป็น (afaik)

$ cat myaskpass.sh 
#!/bin/bash
kdialog --password "Please enter your password: "
exit 0


$ cat askpasstest1.desktop 
#!/usr/bin/env xdg-open
[Desktop Entry]
Comment=SUDO_ASKPASS tester1
Exec=bash /home/user/test/askpasstest1.sh
GenericName=SUDO_ASKPASS tester1
Name=SUDO_ASKPASS tester1
NoDisplay=false
Path[$e]=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
Categories=Application;Utility;
X-KDE-SubstituteUID=false
X-KDE-Username=

และบททดสอบด้วยตัวเอง อันนี้จะขอรหัสผ่านของคุณสองครั้งเมื่อใช้โซลูชันนี้ (โดยปกติจะถามเพียงครั้งเดียวเนื่องจากการหมดเวลา sudo เริ่มต้น)

#!/bin/bash

sudo -k
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass1
touch filemadeas_regularuser1
SUDO_ASKPASS="/home/user/test/myaskpass.sh" sudo -A touch filemadeas_askpass2
touch filemadeas_regularuser2
ls -la filemadeas* > /home/user/test/fma.log
kdialog --title "Files Created" --textbox /home/user/test/fma.log 640 480
sudo rm filemadeas_*
rm fma.log

exit 0

เรียกใช้สคริปต์นี้จากบรรทัดคำสั่งรหัสผ่านจะถูกถามเพียงครั้งเดียว เรียกใช้จาก GUI (คลิก .desktop หรือ. sh ในตัวจัดการไฟล์) ทุกครั้งจะsudo -Aใช้รหัสผ่านใหม่ ฉันจะพยายามคิดออก
Eric Carvalho

ฉันเพิ่งปรับปรุงคำตอบของฉัน
Eric Carvalho

เอริค ... คุณคิดวิธีแก้ปัญหาหรือไม่?
anthony

0

สคริปต์ต่อไปนี้ทำงานผ่านบรรทัดคำสั่งไฟล์เดสก์ท็อปหรือดับเบิลคลิกถามรหัสผ่านเพียงครั้งเดียวและsudo -Sp '' <your command here> <<<${sudo_password}สามารถใช้รูปแบบคำสั่งได้หลายครั้งทุกที่ในไฟล์:

    # get sudo password
    sudo_password=$( gksudo --print-pass --message="Provide permission to make system changes: Type your password or press Cancel." -- : 2>/dev/null )
    # check for null entry or cancellation
    if [[ ${?} != 0 || -z ${sudo_password} ]]
    then
        exit 4
    fi
    if ! sudo -kSp '' [ 1 ] <<<${sudo_password} 2>/dev/null
    then
        exit 4
    fi
    # command
    sudo -Sp '' gedit "/etc/hosts" <<<${sudo_password}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.