วิธีที่ปลอดภัยที่สุดในการจำกัดการเข้าถึง SSH ของผู้ใช้ให้อยู่ในไดเร็กทอรีที่กำหนดบน Ubuntu 24.04 คือการใช้ OpenSSH ร่วมกับ `@SSH_directory_name` วิธีChrootDirectoryนี้ForceCommand internal-sftpเหมาะอย่างยิ่งเมื่อบัญชีผู้ใช้ต้องการเพียงแค่การถ่ายโอนไฟล์เท่านั้น โดยจะให้มุมมองแบบ SFTP แก่ผู้ใช้ ซึ่งมีไดเร็กทอรีรากของระบบไฟล์เป็นไดเร็กทอรีที่คุณเลือก ในขณะเดียวกันก็บล็อกการเข้าถึงเชลล์แบบโต้ตอบและการส่งต่อ SSH
หากผู้ใช้ต้องการใช้งานเชลล์แบบปกติจริงๆ การตัดสินใจก็จะแตกต่างออกไป เชลล์แบบโต้ตอบที่ใช้ chroot จำเป็นต้องมีไบนารีเชลล์ ไลบรารี โหนดอุปกรณ์ และไฟล์สนับสนุนของตัวเองอยู่ภายใน jail เอกสาร OpenSSH ได้อธิบายเรื่องนี้ไว้อย่างชัดเจน สำหรับบัญชีอัปโหลด สำรองข้อมูล หน่วยงาน ผู้ขาย และโฮสติ้งแบบแชร์ส่วนใหญ่ การใช้ chroot เฉพาะ SFTP นั้นง่ายกว่าและมีโอกาสเกิดข้อผิดพลาดน้อยกว่ามาก สำหรับผู้ใช้ที่ไม่น่าเชื่อถือที่ต้องการสภาพแวดล้อมคำสั่งแบบเต็มรูปแบบ คอนเทนเนอร์หรือ VM เฉพาะมักจะดูแลรักษาง่ายกว่าการสร้าง chroot เชลล์ด้วยตนเอง
คู่มือนี้ใช้ Ubuntu 24.04 LTS และผู้ใช้ตัวอย่างชื่อ ผู้aliceใช้รายนี้จะถูกจำกัด/srv/sftp/aliceสิทธิ์ในการเขียนข้อมูลเฉพาะภายใน เท่านั้น/filesโปรดเปลี่ยนชื่อและเส้นทางให้เหมาะสมกับเซิร์ฟเวอร์ของคุณ
ก่อนเริ่มต้น: โปรดทำความเข้าใจกฎการเป็นเจ้าของ
สาเหตุที่พบบ่อยที่สุดของการทำงาน chroot ล้มเหลวคือปัญหาเรื่องสิทธิ์การเข้าถึง OpenSSH กำหนดให้ทุกส่วนประกอบของChrootDirectoryพาธต้องเป็นของ root และไม่สามารถเขียนได้โดยกลุ่มหรือผู้ใช้อื่น ๆข้อกำหนดนี้จะถูกตรวจสอบโดยไม่มีเงื่อนไข นั่นหมายความว่าคุณไม่ควรอนุญาตให้ กลุ่มหรือผู้ใช้อื่น ๆ /srv/sftp/aliceเขียนaliceได้
แต่ให้เปลี่ยนไดเร็กทอรีหลักของคุกให้เป็นของ root และสร้างไดเร็กทอรีลูกที่สามารถเขียนได้:
/srv/sftp/alice root:root 755
└── files alice:alice 755
การออกแบบนี้เป็นไปตามพฤติกรรมที่ระบุไว้ในคู่มือUbuntu 24.04sshd_config(5)คู่มือเดียวกันนี้ระบุว่าinternal-sftpไม่จำเป็นต้องมีไฟล์รันไทม์เพิ่มเติมภายใน chroot ซึ่งเป็นเหตุผลว่าทำไมจึงเหมาะสมที่สุดสำหรับบัญชีที่มีข้อจำกัดในการถ่ายโอนไฟล์
ขั้นตอนที่ 1: ตรวจสอบว่าได้ติดตั้ง OpenSSH Server แล้ว
ตรวจสอบให้แน่ใจว่าได้ติดตั้ง OpenSSH Server แล้วและssh.serviceกำลังทำงานอยู่ ก่อนที่จะเปลี่ยนแปลงกฎการเข้าถึง
ติดตั้งแพ็คเกจเซิร์ฟเวอร์หากจำเป็น:
sudo apt update
sudo apt install openssh-server
sudo systemctl status ssh.service
เอกสารอย่างเป็นทางการของ Ubuntu เกี่ยวกับ OpenSSH ใช้openssh-serverแพ็กเกจ daemon และssh.serviceสำหรับการจัดการบริการ โปรดดูคู่มือ Ubuntu Server OpenSSH
หากนี่เป็นเครื่องระยะไกลและ SSH เป็นเส้นทางการดูแลระบบเพียงเส้นทางเดียวของคุณ โปรดเปิดเซสชันผู้ดูแลระบบที่มีอยู่ของคุณไว้ขณะทำการเปลี่ยนแปลง การกำหนดค่า SSH ที่ไม่ถูกต้องอาจทำให้คุณไม่สามารถเข้าถึงได้
ขั้นตอนที่ 2: สร้างกลุ่มและเพิ่มผู้ใช้ที่มีสิทธิ์จำกัดเข้าไป
สร้างกลุ่มเฉพาะเพื่อให้สามารถใช้ข้อจำกัดดังกล่าวได้อย่างสม่ำเสมอสำหรับบัญชี SFTP เท่านั้นหนึ่งบัญชีหรือหลายบัญชี
สร้างกลุ่มสำหรับผู้ใช้ที่มีสิทธิ์เข้าถึงจำกัด หากaliceมีอยู่แล้ว ให้เพิ่มเธอเข้าไปในกลุ่มเท่านั้น:
sudo groupadd sftpusers
sudo adduser alice
sudo usermod -aG sftpusers alice
id alice
หากคุณใช้คีย์สาธารณะ SSH อยู่แล้ว ก็ใช้ต่อไปได้เลย การตั้งค่า chroot จะควบคุมสิ่งที่เกิดขึ้นหลังจากยืนยันตัวตนแล้ว ไม่จำเป็นต้องเปลี่ยนจากการยืนยันตัวตนด้วยคีย์เป็นรหัสผ่าน
โดยทั่วไปแล้ว การกำหนดกฎเกณฑ์แบบกลุ่มจะดีกว่าMatch Userการกำหนดกฎเกณฑ์แยกต่างหากสำหรับแต่ละบัญชี เพราะจะช่วยให้การจัดการนโยบายเป็นไปอย่างเป็นระบบ อย่างไรก็ตาม การกำหนดกฎเกณฑ์ต่อผู้ใช้แต่ละคนก็ยังคงมีประโยชน์อยู่ เมื่อจำเป็นต้องจำกัดการใช้งานเลย์เอาต์ที่แตกต่างกันสำหรับผู้ใช้แต่ละคน
ขั้นตอนที่ 3: สร้าง jail ที่ root เป็นเจ้าของ และไดเร็กทอรีย่อยที่สามารถเขียนได้
ไดเร็กทอรีรากของ chroot ยังคงเป็นของ root; มีเพียงfilesไดเร็กทอรีลูกเท่านั้นที่ผู้ใช้ที่มีสิทธิ์จำกัดสามารถเขียนได้
สร้างโครงสร้างลำดับชั้นของไดเร็กทอรี:
sudo mkdir -p /srv/sftp/alice/files
sudo chown root:root /srv/sftp/alice
sudo chmod 755 /srv/sftp/alice
sudo chown alice:alice /srv/sftp/alice/files
sudo chmod 755 /srv/sftp/alice/files
ตรวจสอบความเป็นเจ้าของ:
ls -ld /srv /srv/sftp /srv/sftp/alice /srv/sftp/alice/files
namei -l /srv/sftp/alice
หาก ไฟล์ /srvนั้น/srv/sftpสามารถเขียนได้โดยกลุ่มหรือผู้ใช้ ก็ให้แก้ไขส่วนนั้นด้วย OpenSSH ตรวจสอบส่วนประกอบทั้งหมดของพาธ ไม่ใช่แค่ไดเร็กทอรีสุดท้ายเท่านั้น
ขั้นตอนที่ 4: เพิ่มกฎการจับคู่ในไฟล์ sshd_config.d
บล็อกMatch Groupดังกล่าวจะใช้ chroot และนโยบาย SFTP-only กับสมาชิกของบล็อกsftpusersเท่านั้น
เอกสารประกอบการใช้งานเซิร์ฟเวอร์ Ubuntu ในปัจจุบันแนะนำให้เก็บการตั้งค่า SSH แบบกำหนดเองไว้ภายในไฟล์การตั้งค่าหลัก/etc/ssh/sshd_config.d/แทนที่จะผสมการตั้งค่าเหล่านั้นเข้าไปในไฟล์การตั้งค่าหลักที่บรรจุไว้ สร้างตัวอย่างโค้ด:
sudo nano /etc/ssh/sshd_config.d/90-sftp-restricted.conf
เพิ่ม:
Match Group sftpusers
ChrootDirectory /srv/sftp/%u
ForceCommand internal-sftp -d /files
DisableForwarding yes
PermitTTY no
Match all
%uขยายเป็นชื่อผู้ใช้ที่ได้รับการตรวจสอบสิทธิ์ ดังนั้นaliceจึงถูกวางไว้ใน/srv/sftp/alice. -d /filesอาร์กิวเมนต์บอกให้เซิร์ฟเวอร์ SFTP ภายในเริ่มต้นภายในไดเร็กทอรีลูกที่เขียนได้DisableForwarding yesปิดใช้งานการส่งต่อ X11, เอเจนต์, TCP และ StreamLocal ในคำสั่งเดียว โดยมีเอกสารระบุไว้อย่างชัดเจนสำหรับการลดความซับซ้อนของการกำหนดค่าที่จำกัด
ส่วน "สุดท้าย" Match allมีความสำคัญในโค้ดตัวอย่าง เนื่องจากเป็นการสิ้นสุดบริบทเงื่อนไขก่อนที่จะมีการประมวลผลการกำหนดค่าในภายหลัง
ขั้นตอนที่ 5: ตัดสินใจเลือกระหว่างการจำกัดแบบกลุ่มและการจำกัดแบบรายบุคคล
ใช้บัญชีผู้ใช้เฉพาะเมื่อผู้ขาย งานสำรองข้อมูล หรือผู้ใช้ภายนอกไม่ควรมีสิทธิ์เข้าถึงเชลล์ตามปกติ
สำหรับผู้ใช้หลายคนที่มีรูปแบบการจัดวางเหมือนกัน ให้คงกฎการจัดกลุ่มที่แสดงไว้ด้านบน แต่สำหรับบัญชีพิเศษเพียงบัญชีเดียว ให้ใช้การบล็อกเฉพาะผู้ใช้แทน:
Match User vendor1
ChrootDirectory /srv/vendor/vendor1
ForceCommand internal-sftp -d /incoming
DisableForwarding yes
PermitTTY no
Match all
เลือกตามค่าใช้จ่ายในการบริหารจัดการ:
| สถานการณ์ | กฎที่ดีที่สุด | ทำไม |
| ผู้ใช้งานที่อัปโหลดอย่างเดียวจำนวนมากที่มีโครงสร้างเหมือนกัน | Match Group | นโยบายเดียวใช้บังคับกับสมาชิกทุกคน |
| ผู้ขายรายหนึ่งต้องการไดเร็กทอรีเฉพาะตัว | Match User | เส้นทางและข้อจำกัดต่างๆ สามารถแตกต่างกันได้โดยไม่ส่งผลกระทบต่อผู้อื่น |
| ผู้ใช้ต้องการเชลล์แบบโต้ตอบปกติ | อย่าใช้สูตรนี้ซึ่งใช้ได้เฉพาะกับ SFTP เท่านั้น | chroot แบบโต้ตอบต้องการสภาพแวดล้อมการทำงานที่สมบูรณ์ |
| ผู้ใช้ที่ไม่น่าเชื่อถือจำเป็นต้องมีคำสั่งและการแยกตัวอย่างเข้มงวด | ลองพิจารณาใช้คอนเทนเนอร์หรือเครื่องเสมือน (VM) | การกำหนดและอัปเดตสภาพแวดล้อมการทำงานโดยรวมทำได้ง่ายกว่า |
ขั้นตอนที่ 6: ตรวจสอบความถูกต้องของการตั้งค่า SSH ก่อนรีสตาร์ท
ก่อนที่จะใช้กฎ chroot โปรดตรวจสอบความถูกต้องของไวยากรณ์และการตั้งค่าที่ใช้งานได้จริงสำหรับผู้ใช้แต่ละราย
ห้ามรีสตาร์ท SSH ทันทีหลังจากแก้ไขไฟล์ ให้ทำการทดสอบไวยากรณ์ตามที่ Ubuntu แนะนำก่อน:
sudo sshd -t
ไม่มีข้อความแสดงผล หมายความว่าการตรวจสอบไวยากรณ์สำเร็จแล้ว คุณยังสามารถตรวจสอบการตั้งค่าที่มีผลบังคับใช้สำหรับผู้ใช้รายใดรายหนึ่งได้อีกด้วย:
sudo sshd -T -C user=alice,host=localhost,addr=127.0.0.1 | grep -E 'chrootdirectory|forcecommand|disableforwarding|permittty'
คุณควรจะเห็นพาธ chroot ที่คาดหวังและคำสั่ง SFTP ที่บังคับใช้ สิ่งนี้มีประโยชน์อย่างยิ่งบน Ubuntu เพราะการตั้งค่าสามารถมาจากทั้ง/etc/ssh/sshd_configไฟล์และโฟลเดอร์/etc/ssh/sshd_config.d/Ubuntu ระบุว่า OpenSSH โดยทั่วไปจะใช้ค่าแรกที่ได้รับสำหรับคำสั่งส่วนใหญ่ ดังนั้นการตรวจสอบการกำหนดค่าที่มีผลจึงปลอดภัยกว่าการสันนิษฐานว่าไฟล์ใดจะถูกนำไปใช้
ขั้นตอนที่ 7: รีสตาร์ท SSH และทดสอบด้วย SFTP
หลังจากทำการทดสอบการตั้งค่าอย่างสะอาดแล้ว ให้รีสตาร์ท SSH และตรวจสอบว่าบัญชีดังกล่าวเข้าถึงได้เฉพาะระบบไฟล์ SFTP ที่ถูกจำกัดสิทธิ์เท่านั้น
บันทึกการเปลี่ยนแปลง:
sudo systemctl restart ssh.service
sudo systemctl status ssh.service
จากนั้นเชื่อมต่อจากเทอร์มินัลอื่น:
sftp alice@server.example.com
ภายใน SFTP ให้ทดสอบ:
pwd
ls
put test.txt
ls -l
จากการตั้งค่าข้างต้น ไดเร็กทอรี SFTP เริ่มต้นควรจะเป็น/filesเครื่องหมายทับที่แสดงโดย SFTP คือรากของ chroot ไม่ใช่รากของเซิร์ฟเวอร์จริง
การพยายามเข้าถึงเชลล์ตามปกติไม่ควรทำให้ได้เชลล์แบบไม่จำกัด:
ssh alice@server.example.com
เนื่องจากForceCommand internal-sftpฟังก์ชันนี้จะแทนที่เซสชันที่ร้องขอด้วยเซิร์ฟเวอร์ SFTP ที่กำลังดำเนินการอยู่ บัญชีนี้จึงถูกสร้างขึ้นโดยเจตนาเพื่อการถ่ายโอนไฟล์ ไม่ใช่เพื่อการเรียกใช้คำสั่ง
ขั้นตอนที่ 8: ยืนยันว่าผู้ใช้ไม่สามารถหลบหนีออกจากคุกได้
ทดสอบขอบเขตอย่างชัดเจน: เส้นทางต่างๆ เช่น เส้นทางของโฮสต์/etcและ/rootจะต้องไม่ปรากฏให้เห็นภายนอก chroot
ลองเลื่อนขึ้นไปเหนือระดับรากที่ปรากฏ และตรวจสอบเส้นทางโฮสต์ที่สำคัญ:
cd ..
ls /
ls /etc
ls /root
ภายใน chroot นั้น/จะแทนที่/srv/sftp/aliceอยู่ IP ของโฮสต์ หากคุณไม่ได้สร้าง ไดเร็กทอรี etcใดๆ ภายใน jail นั้น ผู้ใช้จะไม่สามารถเข้าถึงที่อยู่ IP หรือไดเร็กทอรีจริงrootของโฮสต์ได้/etc/root
ทดสอบการอัปโหลดเข้าไปในระบบ/filesด้วย การกำหนดค่าที่ป้องกันการหลบหนีแต่ทำให้ระบบทั้งหมดเป็นแบบอ่านอย่างเดียวโดยไม่ได้ตั้งใจนั้นปลอดภัย แต่ไม่เหมาะสำหรับบัญชีอัปโหลด
การแก้ไขปัญหา: “สิทธิ์การเป็นเจ้าของหรือโหมดที่ไม่ถูกต้องสำหรับไดเร็กทอรี chroot”
หากการเข้าสู่ระบบล้มเหลวทันที ให้ตรวจสอบบันทึกการทำงานของบริการ SSH:
sudo journalctl -fu ssh.service
คู่มือ OpenSSH ของ Ubuntu แนะนำให้ใช้บันทึกการบริการ SSH สำหรับการแก้ไขปัญหา หากพบข้อผิดพลาดเกี่ยวกับสิทธิ์การเป็นเจ้าของหรือโหมด ให้ตรวจสอบทุกไดเร็กทอรีแม่:
namei -l /srv/sftp/alice
โฟลเดอร์ chroot ต้องเป็นของ root และไม่สามารถเขียนได้โดยกลุ่มหรือบุคคลอื่น ข้อผิดพลาดที่พบบ่อยคือ:
sudo chown alice:alice /srv/sftp/alice
อย่าแก้ปัญหาด้วยการลดความเข้มงวดของการตรวจสอบ OpenSSH ให้ย้ายพื้นที่ที่ผู้ใช้สามารถเขียนได้ไปไว้ใต้ระดับรากของ chroot แทน:
sudo chown root:root /srv/sftp/alice
sudo chmod 755 /srv/sftp/alice
sudo chown alice:alice /srv/sftp/alice/files
แล้วถ้าผู้ใช้ต้องการเข้าถึงเชลล์ SSH ไม่ใช่แค่ SFTP ล่ะ?
ChrootDirectoryสามารถใช้งานร่วมกับเชลล์แบบโต้ตอบได้เช่นกัน แต่การตั้งค่าจะซับซ้อนกว่ามาก OpenSSH ระบุว่า chroot แบบโต้ตอบนั้นต้องการอย่างน้อยเชลล์และ/devโหนดพื้นฐาน รวมถึงไบนารี ไลบรารี ไฟล์การแก้ไขชื่อ และส่วนประกอบอื่นๆ ที่จำเป็นสำหรับคำสั่งที่คุณอนุญาต
สำหรับบัญชีผู้ใช้ที่มีการควบคุมอย่างเข้มงวด การสร้าง "คุก" ดังกล่าวอาจเป็นสิ่งที่สมเหตุสมผล แต่สำหรับการเข้าถึงคำสั่ง Linux ทั่วไป มักจะสร้างภาระในการบำรุงรักษา: การอัปเดตความปลอดภัยสำหรับเครื่องมือและไลบรารีต่างๆ จะต้องสะท้อนอยู่ภายในคุกด้วย หากความต้องการที่แท้จริงของคุณคือ "อนุญาตให้บุคคลนี้เรียกใช้คำสั่งได้ แต่แยกพวกเขาออกจากโฮสต์" คอนเทนเนอร์, VM หรือบริการที่จำกัดเฉพาะกิจมักจะตรวจสอบได้ง่ายกว่า
การปรับปรุงด้านความปลอดภัยที่ควรเพิ่มเข้ามา
การจำกัดการเข้าถึงไดเร็กทอรีเป็นเพียงชั้นเดียวเท่านั้น สำหรับเซิร์ฟเวอร์ที่เชื่อมต่อกับอินเทอร์เน็ต ควรพิจารณาสิ่งต่อไปนี้ด้วย:
- ควรใช้การตรวจสอบสิทธิ์ด้วยคีย์สาธารณะ SSH สำหรับบัญชีผู้ใช้ที่เป็นมนุษย์และระบบอัตโนมัติในกรณีที่สามารถทำได้
- อย่าให้
sudoสิทธิ์การเข้าถึง การถ่ายโอนไฟล์แก่ผู้ใช้ที่มีสิทธิ์จำกัด
- สงวนไว้
DisableForwarding yesสำหรับบัญชี SFTP เท่านั้น เพื่อป้องกันไม่ให้การเชื่อมต่อ SSH ถูกนำไปใช้ในทางที่ผิด เช่น การสร้างอุโมงค์หรือการส่งต่อเอเจนต์
- จำกัดขนาดของไดเร็กทอรีที่สามารถเขียนได้ให้มีขนาดเล็กที่สุดเท่าที่เวิร์กโฟลว์ต้องการ
- ตรวจสอบ
journalctl -u ssh.serviceและกำหนดสิทธิ์การเป็นเจ้าของไฟล์หลังจากเพิ่มผู้ใช้แล้ว
- เปิดเซสชันผู้ดูแลระบบไว้ตลอดเวลาขณะทดสอบการเปลี่ยนแปลงการกำหนดค่า SSH ระยะไกล
สำหรับพฤติกรรมที่แน่นอนของChrootDirectory, Match, ForceCommand, และDisableForwardingให้ใช้คู่มือการกำหนดค่าเซิร์ฟเวอร์ OpenSSH ของ Ubuntu 24.04สำหรับโครงสร้างการกำหนดค่า การตรวจสอบความถูกต้อง คำสั่งรีสตาร์ท และการบันทึกข้อมูลเฉพาะของ Ubuntu โปรดดูเอกสารอย่างเป็นทางการของเซิร์ฟเวอร์ OpenSSH ของ Ubuntu
สรุปแล้ว
หากเป้าหมายคือ “บัญชี SSH นี้สามารถอัปโหลดและดาวน์โหลดไฟล์ได้เฉพาะภายในไดเร็กทอรีเดียวเท่านั้น” ให้ใช้ไดเร็กทอรีที่ root เป็นเจ้าของChrootDirectoryวางเนื้อหาที่เขียนได้ในไดเร็กทอรีลูกที่ผู้ใช้เป็นเจ้าของ และบังคับใช้internal-sftpตรวจสอบความsshd -tถูกต้องก่อนรีสตาร์ท จากนั้นทดสอบทั้งเส้นทางการอัปโหลดที่อนุญาตและการพยายามเข้าถึงภายนอก chroot วิธีนี้จะสร้างขอบเขตความปลอดภัยที่เล็กและเข้าใจง่ายโดยไม่ต้องสร้างสภาพแวดล้อม Linux ที่สมบูรณ์ภายใน chroot