วิธีใช้รหัสผ่านที่เข้ารหัสใน Bash Scripts
เผยแพร่แล้ว: 2022-01-29หากคุณถูกบังคับให้ใช้สคริปต์ Linux เพื่อเชื่อมต่อกับทรัพยากรที่มีการป้องกันด้วยรหัสผ่าน คุณอาจรู้สึกไม่สบายใจที่จะใส่รหัสผ่านนั้นในสคริปต์ OpenSSL แก้ปัญหานั้นให้คุณได้
รหัสผ่านและสคริปต์
ไม่ควรใส่รหัสผ่านในเชลล์สคริปต์ อันที่จริงมันเป็นความคิดที่แย่มาก หากสคริปต์ตกไปอยู่ในมือของผู้อื่น ทุกคนที่อ่านสคริปต์จะเห็นว่ารหัสผ่านคืออะไร แต่ถ้าคุณถูกบังคับให้ใช้สคริปต์ คุณทำอะไรได้อีก?
คุณสามารถป้อนรหัสผ่านด้วยตนเองเมื่อกระบวนการไปถึงจุดนั้น แต่ถ้าสคริปต์ทำงานโดยไม่มีใครดูแล สคริปต์นั้นจะไม่ทำงาน โชคดีที่มีทางเลือกอื่นนอกเหนือจากการฮาร์ดโค้ดรหัสผ่านลงในสคริปต์ มันใช้รหัสผ่านอื่นเพื่อให้บรรลุเป้าหมายนี้ ควบคู่ไปกับการเข้ารหัสที่รัดกุม
ในสถานการณ์ตัวอย่างของเรา เราจำเป็นต้องทำการเชื่อมต่อระยะไกลกับคอมพิวเตอร์ Fedora Linux จากคอมพิวเตอร์ Ubuntu ของเรา เราจะใช้สคริปต์เปลือก Bash เพื่อทำการเชื่อมต่อ SSH กับคอมพิวเตอร์ Fedora สคริปต์ต้องทำงานแบบอัตโนมัติ และเราไม่ต้องการใส่รหัสผ่านสำหรับบัญชีระยะไกลในสคริปต์ เราไม่สามารถใช้คีย์ SSH ได้ในกรณีนี้ เนื่องจากเราแสร้งทำเป็นว่าเราไม่มีสิทธิ์ควบคุมหรือสิทธิ์ของผู้ดูแลระบบในคอมพิวเตอร์ Fedora
เราจะใช้ชุดเครื่องมือ OpenSSL ที่รู้จักกันดีในการจัดการการเข้ารหัสและยูทิลิตี้ที่เรียกว่า sshpass
เพื่อป้อนรหัสผ่านลงในคำสั่ง SSH
ที่เกี่ยวข้อง: วิธีสร้างและติดตั้งคีย์ SSH จาก Linux Shell
การติดตั้ง OpenSSL และ sshpass
เนื่องจากเครื่องมือเข้ารหัสและความปลอดภัยอื่นๆ จำนวนมากใช้ OpenSSL จึงอาจติดตั้งไว้ในคอมพิวเตอร์ของคุณแล้ว อย่างไรก็ตาม หากไม่ใช่ จะใช้เวลาสักครู่ในการติดตั้ง
บน Ubuntu พิมพ์คำสั่งนี้:
sudo apt รับ openssl
ในการติดตั้ง sshpass
ให้ใช้คำสั่งนี้:
sudo apt ติดตั้ง sshpass
ใน Fedora คุณต้องพิมพ์:
sudo dnf ติดตั้ง openssl
คำสั่งในการติดตั้ง sshpass
คือ:
sudo dnf ติดตั้ง sshpass
บน Manjaro Linux เราสามารถติดตั้ง OpenSSL ด้วย:
sudo pacman -Sy openssl
สุดท้ายในการติดตั้ง sshpass
ให้ใช้คำสั่งนี้:
sudo pacman -Sy sshpass
การเข้ารหัสบน Command Line
ก่อนที่เราจะเริ่มต้นใช้งานคำสั่ง openssl
กับสคริปต์ เรามาทำความคุ้นเคยกับมันโดยใช้คำสั่งในบรรทัดรับคำสั่งเสียก่อน สมมติว่ารหัสผ่านสำหรับบัญชีบนคอมพิวเตอร์ระยะไกลเป็น rusty!herring.pitshaft
เราจะเข้ารหัสรหัสผ่านนั้นโดยใช้ openssl
เราจำเป็นต้องให้รหัสผ่านการเข้ารหัสเมื่อเราทำ รหัสผ่านการเข้ารหัสจะใช้ในกระบวนการเข้ารหัสและถอดรหัส มีพารามิเตอร์และตัวเลือกมากมายในคำสั่ง openssl
เราจะดูที่แต่ละรายการในอีกสักครู่
echo 'rusty!herring.pitshaft' | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'pick.your.password'
เรากำลังใช้ echo
เพื่อส่งรหัสผ่านบัญชีระยะไกลผ่านไพพ์และไปยังคำสั่ง openssl
พารามิเตอร์ openssl
คือ:
- enc -aes-256-cbc : ประเภทการเข้ารหัส เรากำลังใช้การเข้ารหัสคีย์มาตรฐาน 256 บิตขั้นสูงที่มีการเข้ารหัสแบบบล็อกเชน
- -md sha512 : ประเภทข้อความย่อย (แฮช) เรากำลังใช้อัลกอริธึมการเข้ารหัส SHA512
- -a : สิ่งนี้บอกให้
openssl
ใช้การเข้ารหัส base-64 หลังจากขั้นตอนการเข้ารหัสและก่อนขั้นตอนการถอดรหัส - -pbkdf2 : การใช้ Password-Based Key Derivation Function 2 (PBKDF2) ทำให้ยากขึ้นมากสำหรับการโจมตีด้วยกำลังเดรัจฉานในการเดารหัสผ่านของคุณสำเร็จ PBKDF2 ต้องการการคำนวณจำนวนมากเพื่อดำเนินการเข้ารหัส ผู้โจมตีจะต้องทำซ้ำการคำนวณเหล่านั้นทั้งหมด
- -iter 100000 : ตั้งค่าจำนวนการคำนวณที่ PBKDF2 จะใช้
- -salt : การใช้ค่าเกลือแบบสุ่มทำให้เอาต์พุตที่เข้ารหัสแตกต่างกันทุกครั้ง แม้ว่าข้อความธรรมดาจะเหมือนกันก็ตาม
- -pass pass:'pick.your.password' : รหัสผ่านที่เราจะต้องใช้เพื่อถอดรหัสรหัสผ่านระยะไกลที่เข้ารหัส แทนที่
pick.your.password
ด้วยรหัสผ่านที่คุณเลือกได้
เวอร์ชันเข้ารหัสของรหัสผ่าน rusty!herring.pitshaft
ของเราถูกเขียนลงในหน้าต่างเทอร์มินัล
ในการถอดรหัสสิ่งนี้ เราต้องส่งสตริงที่เข้ารหัสนั้นไปยัง openssl
ด้วยพารามิเตอร์เดียวกันกับที่เราเคยเข้ารหัส แต่เพิ่มในตัวเลือก -d
(ถอดรหัส)
เสียงก้อง U2FsdGVkX19iiiRNhEsG+wm/uKjtZJwnYOpjzPhyrDKYZH5lVZrpIgo1S0goZU46 | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:'pick.your.password'
สตริงถูกถอดรหัส และข้อความต้นฉบับของเรา—รหัสผ่านสำหรับบัญชีผู้ใช้ระยะไกล—ถูกเขียนลงในหน้าต่างเทอร์มินัล
นั่นพิสูจน์ให้เห็นว่าเราสามารถเข้ารหัสรหัสผ่านบัญชีผู้ใช้ระยะไกลของเราได้อย่างปลอดภัย เรายังสามารถถอดรหัสได้เมื่อเราต้องการโดยใช้รหัสผ่านที่เราให้ไว้ในขั้นตอนการเข้ารหัส
แต่สิ่งนี้ช่วยปรับปรุงสถานการณ์ของเราได้จริงหรือ หากเราต้องการรหัสผ่านการเข้ารหัสเพื่อถอดรหัสรหัสผ่านบัญชีระยะไกล รหัสผ่านถอดรหัสจะต้องอยู่ในสคริปต์หรือไม่ ใช่มันไม่ แต่รหัสผ่านบัญชีผู้ใช้ระยะไกลที่เข้ารหัสจะถูกเก็บไว้ในไฟล์อื่นที่ซ่อนอยู่ สิทธิ์ในไฟล์จะป้องกันไม่ให้ใครก็ตาม - และผู้ใช้รูทของระบบ - เห็นได้ชัดว่าไม่สามารถเข้าถึงได้
ในการส่งเอาต์พุตจากคำสั่งเข้ารหัสไปยังไฟล์ เราสามารถใช้การเปลี่ยนเส้นทางได้ ไฟล์นี้มีชื่อว่า “.secret_vault.txt” เราได้เปลี่ยนรหัสผ่านการเข้ารหัสเป็นสิ่งที่มีประสิทธิภาพมากขึ้น
echo 'rusty!herring.pitshaft' | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'secret#vault!password' > .secret_vault.txt
ไม่มีอะไรปรากฏให้เห็น แต่รหัสผ่านถูกเข้ารหัสและส่งไปยังไฟล์ “.secret_vault.txt”
เราสามารถทดสอบว่ามันใช้งานได้โดยถอดรหัสรหัสผ่านในไฟล์ที่ซ่อนอยู่ โปรดทราบว่าเรากำลังใช้ cat
ที่นี่ ไม่ใช่ echo
cat .secret_vault.txt | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass: 'secret # vault! รหัสผ่าน'
รหัสผ่านถูกถอดรหัสสำเร็จจากข้อมูลในไฟล์ เราจะใช้ chmod
เพื่อเปลี่ยนการอนุญาตในไฟล์นี้เพื่อไม่ให้คนอื่นสามารถเข้าถึงได้
chmod 600 .secret_vault.txt
ls -l .secret_vault.txt
การใช้มาสก์การอนุญาต 600 จะลบการเข้าถึงทั้งหมดสำหรับใครก็ตามที่ไม่ใช่เจ้าของไฟล์ ตอนนี้เราสามารถไปเขียนบทของเราได้แล้ว
ที่เกี่ยวข้อง: วิธีใช้คำสั่ง chmod บน Linux
การใช้ OpenSSL ในสคริปต์
สคริปต์ของเราค่อนข้างตรงไปตรงมา:
#!/bin/bash #ชื่อบัญชีระยะไกล REMOTE_USER=เกินบรรยาย # รหัสผ่านสำหรับบัญชีระยะไกล REMOTE_PASSWD=$(cat .secret_vault.txt | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:'secret#vault!password') #คอมพิวเตอร์ระยะไกล REMOTE_LINUX=fedora-34.local # เชื่อมต่อกับคอมพิวเตอร์ระยะไกลและใส่การประทับเวลาในไฟล์ชื่อ script.log sshpass -p $REMOTE_PASSWD ssh -T $REMOTE_USER@$REMOTE_LINUX << _remote_commands echo $USER "-" $(date) >> /home/$REMOTE_USER/script.log _remote_commands
- เราตั้งค่าตัวแปรที่เรียกว่า
REMOTE_USER
เป็น "geek" - จากนั้นเราตั้งค่าตัวแปรที่เรียกว่า
REMOTE_PASSWD
เป็นค่าของรหัสผ่านที่ถอดรหัสแล้วซึ่งดึงมาจากไฟล์ “.secret_vault.txt” โดยใช้คำสั่งเดียวกับที่เราใช้เมื่อสักครู่นี้ - ตำแหน่งของคอมพิวเตอร์ระยะไกลถูกเก็บไว้ในตัวแปรที่เรียกว่า
REMOTE_LINUX
ด้วยข้อมูลดังกล่าว เราสามารถใช้คำสั่ง ssh
เพื่อเชื่อมต่อกับคอมพิวเตอร์ระยะไกลได้
- คำสั่ง
sshpass
เป็นคำสั่งแรกบนบรรทัดการเชื่อมต่อ เราใช้กับตัวเลือก-p
(รหัสผ่าน) ซึ่งช่วยให้เราระบุรหัสผ่านที่ควรส่งไปยังคำสั่งssh
- เราใช้ตัวเลือก
-T
(ปิดใช้งานการจัดสรรเทอร์มินัลหลอก) กับssh
เนื่องจากเราไม่จำเป็นต้องจัดสรร pseudo-TTY ให้เราบนคอมพิวเตอร์ระยะไกล
เรากำลังใช้ เอกสารสั้น ๆ ที่นี่ เพื่อส่งคำสั่งไปยังคอมพิวเตอร์ระยะไกล ทุกอย่างระหว่างสตริง _remote_commands
ทั้งสองจะถูกส่งเป็นคำสั่งไปยังเซสชันผู้ใช้บนคอมพิวเตอร์ระยะไกล ในกรณีนี้ จะเป็นสคริปต์ Bash บรรทัดเดียว
คำสั่งที่ส่งไปยังคอมพิวเตอร์ระยะไกลจะบันทึกชื่อบัญชีผู้ใช้และการประทับเวลาไปยังไฟล์ชื่อ “script.log”
คัดลอกและวางสคริปต์ลงในโปรแกรมแก้ไขแล้วบันทึกลงในไฟล์ชื่อ "go-remote.sh" อย่าลืมเปลี่ยนรายละเอียดเพื่อให้สอดคล้องกับที่อยู่ของคอมพิวเตอร์ระยะไกล บัญชีผู้ใช้ระยะไกล และรหัสผ่านบัญชีระยะไกลของคุณ
ใช้ chmod
เพื่อทำให้สคริปต์ทำงานได้
chmod +x go-remote.sh
ที่เหลือก็แค่ลองดู มาจุดไฟให้สคริปต์ของเรากันเถอะ
./go-remote.sh
เนื่องจากสคริปต์ของเราเป็นแบบเรียบง่ายสำหรับสคริปต์แบบไม่ต้องใส่ข้อมูล จึงไม่มีเอาต์พุตไปยังเทอร์มินัล แต่ถ้าเราตรวจสอบไฟล์ "script.log" บนคอมพิวเตอร์ Fedora เราจะเห็นว่าการเชื่อมต่อระยะไกลทำได้สำเร็จและไฟล์ "script.log" ได้รับการอัปเดตด้วยการประทับเวลา
cat script.log
รหัสผ่านของคุณเป็นแบบส่วนตัว
รหัสผ่านบัญชีระยะไกลของคุณจะไม่ถูกบันทึกในสคริปต์
และแม้ว่ารหัสผ่านในการถอดรหัส จะอยู่ ในสคริปต์ แต่ไม่มีใครสามารถเข้าถึงไฟล์ “.secret_vault.txt” ของคุณเพื่อถอดรหัสและดึงรหัสผ่านบัญชีระยะไกลได้