วิธีทำ Sandbox จำกัดสิทธิ์โปรแกรมบน Linux ด้วย Landlock โดยไม่ต้องใช้ Root

9 นาที 15 views บันทึกเป็น PDF
วิธีทำ Sandbox จำกัดสิทธิ์โปรแกรมบน Linux ด้วย Landlock โดยไม่ต้องใช้ Root

อยากให้โปรแกรมปลอดภัยขึ้นไหม? มาเรียนรู้วิธีใช้ Landlock กักบริเวณโปรแกรม (Sandbox) ให้เข้าถึงไฟล์ได้จำกัดโดยไม่ต้องง้อสิทธิ์ Root มือใหม่ก็ทำตามได้ง่าย ๆ

ทำความรู้จัก Landlock วิธีจำกัดสิทธิ์โปรแกรมแบบไม่ต้องง้อ Root

ถ้าคุณกำลังฝึกเขียนโปรแกรมบน Linux คุณอาจเคยได้ยินเรื่องการทำ Sandbox (การกักบริเวณโปรแกรมไม่ให้เข้าถึงไฟล์อื่นในเครื่อง) ซึ่งปกติเรามักต้องใช้เครื่องมือซับซ้อนอย่าง Docker หรือต้องขอสิทธิ์ Root (สิทธิ์ผู้ดูแลระบบสูงสุด) แต่ Landlock คือเทคโนโลยีใน Kernel (หัวใจหลักของระบบปฏิบัติการ) ที่ปล่อยให้โปรแกรมของเรา "ล็อกตัวเอง" ได้โดยไม่ต้องใช้สิทธิ์พิเศษใดๆ เลย

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

Landlock ถูกรวมเข้ากับ Linux Kernel มาตั้งแต่ปี 2021 แล้ว แต่หลายคนยังไม่รู้ว่ามันใช้งานง่ายแค่ไหน เราจะมาสร้างโปรแกรมที่สั่งให้ระบบปฏิบัติการจำกัดสิทธิ์ตัวเองกัน โดยไม่ต้องผ่านการตั้งค่าที่ยุ่งยากหรือต้องติดตั้งซอฟต์แวร์เสริมเพิ่มแต่อย่างใด

เตรียมความพร้อมและตรวจสอบระบบก่อนเริ่ม

ก่อนจะเริ่มเขียนโค้ด เราต้องเช็กก่อนว่าคอมพิวเตอร์ของเราพร้อมใช้ Landlock หรือไม่ เนื่องจากมันเป็นฟีเจอร์ของ Kernel คุณต้องใช้ Linux Kernel เวอร์ชัน 5.13 ขึ้นไป และต้องมีการเปิดใช้งานตัวเลือกความปลอดภัยนี้ไว้ในระบบ ซึ่งโดยปกติแล้ว Ubuntu หรือ Fedora เวอร์ชันใหม่ๆ จะเปิดมาให้เลยอยู่แล้ว

วิธีเช็กง่ายที่สุดคือการใช้คำสั่งใน Terminal (หน้าจอพิมพ์คำสั่ง) เพื่อดูว่าระบบมองเห็น Landlock หรือไม่ ถ้าคำสั่งที่คุณรันออกมามีคำว่า landlock โผล่ขึ้นมา แสดงว่าคุณพร้อมลุยแล้ว แต่ถ้าไม่เจอ คุณอาจต้องไปแก้ค่าใน Bootloader (โปรแกรมเริ่มระบบ) ของเครื่อง ซึ่งเป็นจุดที่มือใหม่หลายคนมักพลาดเพราะลืมตรวจสอบขั้นตอนนี้ก่อนเริ่มเขียนโค้ด

หากคุณรันคำสั่งแล้วไม่พบ Landlock อย่าเพิ่งตกใจ ให้ลองตรวจสอบไฟล์หัวข้อ (Header files) ในเครื่องด้วยว่ามีไฟล์ linux/landlock.h อยู่หรือไม่ ถ้าทุกอย่างครบถ้วน เราก็สามารถเขียนโปรแกรมที่จำกัดสิทธิ์ตัวเองได้ทันทีโดยไม่ต้องใช้สิทธิ์ Sudo (คำสั่งขอสิทธิ์ผู้ดูแล) เลยแม้แต่นิดเดียว

# ตรวจสอบว่าระบบรองรับ Landlock หรือไม่
grep landlock /sys/kernel/security/lsm

# ตรวจสอบว่ามีไฟล์หัวข้อสำหรับการเขียนโปรแกรมหรือไม่
ls /usr/include/linux/landlock.h

คำสั่งแรกคือการค้นหาในระบบว่ามีโมดูลความปลอดภัยชื่อ landlock ทำงานอยู่ไหม ส่วนคำสั่งที่สองคือการเช็กว่าคอมพิวเตอร์ของคุณมีชุดคำสั่ง (Library) สำหรับเรียกใช้งาน Landlock หรือยัง ถ้าผลลัพธ์แสดงรายชื่อโมดูลที่มีคำว่า landlock อยู่ในบรรทัดแรก แสดงว่าระบบพร้อมทำงาน ส่วนคำสั่ง ls ควรจะแสดงชื่อไฟล์ขึ้นมา หากไม่เจอไฟล์แสดงว่าต้องติดตั้ง Kernel Headers (ไฟล์พื้นฐานสำหรับพัฒนาโปรแกรมในระดับระบบ) เพิ่มเติมครับ

เข้าใจหลักการทำงานผ่าน 3 คำสั่งระบบ

ในการใช้งาน Landlock เราไม่ต้องใช้ Library อื่นเลย เราจะคุยกับ Kernel โดยตรงผ่าน Syscall (คำสั่งเรียกใช้งานฟังก์ชันของระบบปฏิบัติการ) ทั้งหมด 3 ตัว คือ landlock_create_ruleset, landlock_add_rule และ landlock_restrict_self ซึ่งทำหน้าที่ต่างกันอย่างชัดเจนในการสร้างและบังคับใช้กฎ

ขั้นตอนแรกคือการสร้าง Ruleset (ชุดกฎความปลอดภัย) เพื่อบอก Kernel ว่าเราจะคุมอะไรบ้าง ต่อมาคือการเพิ่มกฎว่าอนุญาตให้เข้าถึงโฟลเดอร์ไหนได้บ้าง สุดท้ายคือการประกาศใช้กฎนั้นกับตัวเอง ซึ่งจุดที่มือใหม่มักสับสนคือค่า handled_access_fs เพราะหลายคนคิดว่ามันคือการ "อนุญาต" แต่จริงๆ แล้วมันคือการ "บอกว่าเราจะควบคุมอะไร" ถ้าเราใส่ค่าการอ่านลงไป ระบบจะบล็อกการอ่านทั้งหมดทันทีจนกว่าเราจะเพิ่มข้อยกเว้น

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

สร้างโปรแกรมจำกัดสิทธิ์ตัวเอง

มาลองเขียนโค้ดกันจริงๆ เลยดีกว่า โปรแกรมนี้จะทำหน้าที่เปิดไฟล์ใน /etc ได้ แต่ถ้าพยายามไปอ่านไฟล์ใน /tmp มันจะถูกปฏิเสธทันที เราจะใช้ฟังก์ชัน prctl เพื่อตั้งค่า PR_SET_NO_NEW_PRIVS ก่อนเสมอ เพราะเป็นเงื่อนไขบังคับที่ทำให้ระบบมั่นใจว่าโปรแกรมจะไม่ไปแอบยกระดับสิทธิ์ตัวเองผ่านช่องทางอื่น

สังเกตว่าเราใช้ O_PATH ในการเปิดโฟลเดอร์ เพื่อให้เราได้ File Descriptor (ตัวระบุไฟล์) มาใช้งานโดยไม่ต้องมีสิทธิ์อ่านไฟล์ในโฟลเดอร์นั้นจริงๆ นี่เป็นเทคนิคที่ฉลาดมาก เพราะช่วยให้เรากำหนดกฎได้โดยไม่ละเมิดความปลอดภัยเสียเอง หลังจากตั้งกฎเสร็จแล้ว เราก็สั่ง restrict_self เพื่อล็อกตัวเองไว้ตลอดกาลจนกว่าโปรแกรมจะจบการทำงาน

ถ้าคุณลืมใส่ prctl โปรแกรมจะแจ้งเตือนว่า Operation not permitted (ไม่มีสิทธิ์ทำรายการ) ทันที เพราะ Kernel จะไม่ยอมให้คุณจำกัดสิทธิ์ตัวเองถ้าคุณยังมีโอกาสไปเพิ่มสิทธิ์ผ่านโปรแกรมอื่นได้ นี่คือกลไกป้องกันการ "แหกคุก" ที่ออกแบบมาเพื่อความปลอดภัยสูงสุดครับ

// ใช้คำสั่ง syscall เพื่อคุยกับ Kernel โดยตรง
// ใน main ให้เรียก create_ruleset และ restrict_self
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
    perror("prctl"); // แจ้งเตือนหากตั้งค่าความปลอดภัยไม่ผ่าน
    return 1;
}
// restrict_self จะทำให้กฎมีผลกับโปรแกรมทันทีและถาวร
if (restrict_self(ruleset_fd)) {
    perror("landlock_restrict_self");
    return 1;
}

ส่วนของโค้ดนี้คือหัวใจสำคัญ prctl เป็นการบอกระบบว่าโปรแกรมนี้จะไม่ขอสิทธิ์เพิ่มขึ้นอีก ส่วน restrict_self คือการรัดเข็มขัดความปลอดภัยให้แน่นขึ้น ผลลัพธ์ที่ได้คือเมื่อรันโปรแกรมแล้ว ระบบจะยอมให้อ่านไฟล์ใน /etc/hostname ได้ปกติ แต่ถ้าลองอ่าน /tmp/secret.txt จะขึ้นข้อความว่า Permission denied (ถูกปฏิเสธสิทธิ์) ทันทีครับ

กฎของ Landlock ที่ต้องระวัง

สิ่งที่คนเริ่มใช้ Landlock มักจะพลาดคือ "กฎมันรวมกันไม่ได้" สมมติคุณสร้างกฎแรกอนุญาตโฟลเดอร์ A แล้วสร้างกฎสองอนุญาตโฟลเดอร์ B ผลลัพธ์จะไม่ใช่การอนุญาตทั้ง A และ B แต่จะเป็นการ "ตัด" สิทธิ์ที่เหลือทิ้งไปเรื่อยๆ จนสุดท้ายคุณอาจจะเข้าถึงอะไรไม่ได้เลย

เปรียบเทียบง่ายๆ เหมือนการตัดกระดาษ ถ้าคุณตัดส่วนที่ไม่ต้องการทิ้งไปแล้ว คุณไม่สามารถเอาส่วนที่ตัดไปแล้วกลับมาแปะใหม่ได้ Landlock ทำงานในลักษณะเดียวกัน คือมันมีแต่จะทำให้พื้นที่การทำงานแคบลงเรื่อยๆ ดังนั้นถ้าคุณต้องการให้โปรแกรมเข้าถึงได้หลายที่ คุณต้องใส่ทุกเส้นทางไว้ในกฎชุดเดียวตั้งแต่เริ่มสร้าง

อีกเรื่องที่สำคัญคือ "การสืบทอด" ถ้าโปรแกรมของคุณสั่งรันโปรแกรมลูก (Child process) โปรแกรมลูกเหล่านั้นจะติดกฎความปลอดภัยนี้ไปด้วยโดยอัตโนมัติ ซึ่งเป็นเรื่องดีในแง่ความปลอดภัย แต่ถ้าคุณลืมวางแผนไว้ก่อน อาจทำให้โปรแกรมลูกทำงานไม่ได้เพราะเข้าถึงไฟล์ที่จำเป็นไม่ได้ครับ

สรุป: เอาไปประยุกต์ใช้ในงานจริง

การเข้าใจ Landlock ช่วยให้คุณก้าวข้ามความเป็นโปรแกรมเมอร์มือใหม่ที่เขียนโค้ดแค่ให้รันได้ ไปสู่การเป็นคนเขียนโค้ดที่คำนึงถึง Security (ความปลอดภัย) เป็นหลัก คุณสามารถนำไปใช้ในโปรเจกต์อย่างเช่นโปรแกรมจัดการไฟล์ หรือเครื่องมือที่ต้องรันสคริปต์จากผู้ใช้คนอื่น เพื่อป้องกันไม่ให้โปรแกรมเหล่านั้นเข้าถึงไฟล์สำคัญในเครื่องคุณ

ลองเริ่มจากโปรเจกต์เล็กๆ ของคุณเอง เช่น เขียนโปรแกรมอ่านไฟล์คอนฟิก (ไฟล์ตั้งค่า) แล้วลองจำกัดสิทธิ์ให้มันอ่านได้เฉพาะไฟล์ในโฟลเดอร์นั้นเท่านั้น การฝึกทำแบบนี้จะทำให้คุณเข้าใจการทำงานของ Kernel และความปลอดภัยในระดับลึก ซึ่งเป็นทักษะที่บริษัทซอฟต์แวร์ระดับโลกมองหาในตัวโปรแกรมเมอร์

จำไว้ว่าความปลอดภัยไม่ใช่เรื่องไกลตัว แม้จะเป็นเพียงโปรแกรมเมอร์จูเนียร์ การเขียนโค้ดที่ปลอดภัยตั้งแต่บรรทัดแรกคือจุดเริ่มต้นของการเป็นมืออาชีพครับ เริ่มต้นฝึกใช้ Landlock วันนี้ แล้วคุณจะเห็นภาพชัดขึ้นว่าระบบปฏิบัติการปกป้องเราอย่างไร และเราจะช่วยระบบปกป้องข้อมูลของเราได้อย่างไรบ้าง


ที่มา: How to Sandbox a Linux Process with Landlock, No Root Required — freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

เบื่อไหมที่ต้องสลับหน้าจอไปมาเพื่อจัดการเซิร์ฟเวอร์? มาลองใช้ Easy SSH ปลั๊กอิน VS Code ที่ช่วยให้คุณรีโมทผ่าน Terminal ได้สะดวก แถมโหลดไฟล์ได้ง่ายแค่กด Ctrl+click

ที่มา: DEV Community

4 hours ago 11 นาที
3 views
วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

อยากทำแอปท่องเที่ยวแต่ดึงข้อมูลราคาจาก Google Hotels ไม่ได้? มาดูวิธีใช้ Apify Actor ช่วยดึงข้อมูลแบบอัตโนมัติด้วย Python ง่ายๆ ไม่ต้องกลัวเว็บพัง

ที่มา: DEV Community

7 hours ago 8 นาที
5 views
วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

เคยไหม? โค้ดรันได้ในเครื่องแต่พอปล่อยจริงกลับพัง! มาดูวิธีตรวจสอบความพร้อมของโปรเจกต์ก่อนอัปขึ้น GitHub ด้วยเครื่องมือ ReleaseReady กัน

ที่มา: DEV Community

11 hours ago 9 นาที
5 views