สิทธิ์ใน Linux ตอบคำถามว่า «ใครอ่านไฟล์นี้ได้» AppArmor ตอบอีกคำถามหนึ่ง: «โปรแกรมนี้ทำอะไรได้บ้าง» ความต่างปรากฏตอนถูกเจาะ web shell ทำงานในฐานะผู้ใช้ของเว็บเซิร์ฟเวอร์และได้รับสิทธิ์ทั้งหมดของมัน — นั่นคือสิทธิ์อ่านระบบไปกว่าครึ่ง โปรไฟล์ของ AppArmor จำกัดกระบวนการให้อยู่กับรายการสิ่งที่มันต้องใช้ในการทำงาน และความพยายามอ่าน /etc/shadow หรือรัน /bin/bash ก็จบลงด้วยการถูกปฏิเสธไม่ว่าสิทธิ์ของผู้ใช้จะเป็นอย่างไร
อะไรเปิดใช้อยู่แล้ว
sudo aa-status
ผลลัพธ์ตอบสามคำถาม: มีโปรไฟล์โหลดอยู่กี่ตัว ในนั้นอยู่ในโหมด enforce และ complain กี่ตัว และกระบวนการใดทำงานโดยไม่มีโปรไฟล์เลย บน Ubuntu ทั่วไปจะมีโปรไฟล์อยู่หลายสิบตัว แต่เกือบทั้งหมดเป็นของโปรแกรมสนับสนุนอย่าง man และ tcpdump บริการหลัก — nginx, Apache, PHP-FPM — มักไม่อยู่ในรายการที่ถูกจำกัด
สามโหมดที่ควรแยกให้ออก:
- enforce — กฎถูกบังคับใช้ ทุกอย่างที่เกินถูกปฏิเสธ;
- complain — การละเมิดถูกบันทึกลงเจอร์นัลเท่านั้น ไม่มีอะไรถูกบล็อก โหมดสำหรับการปรับจูน;
- unconfined — ไม่มีโปรไฟล์ โปรแกรมทำงานโดยไม่มีข้อจำกัด
ส่วนที่มีประโยชน์ที่สุดของผลลัพธ์ aa-status คือส่วนสุดท้าย: กระบวนการที่รับฟังบนเครือข่ายและไม่ถูกจำกัดด้วยอะไรเลย นั่นคือรายการที่ควรเริ่มต้น
เครื่องมือ
sudo apt install apparmor-utils
ถ้าไม่มีแพ็กเกจนั้น คำสั่ง aa-complain, aa-enforce และ aa-logprof ก็จะไม่อยู่ในระบบ แม้ AppArmor เองจะทำงานอยู่
เปิดใช้โปรไฟล์อย่างไรโดยไม่หยุดบริการ
ลำดับเป็นเรื่องพื้นฐาน โปรไฟล์ที่เปลี่ยนเป็น enforce ทันทีมีความน่าจะเป็นสูงที่จะปฏิเสธสิ่งที่บริการต้องการ และบริการก็จะหยุดทำงาน — โดยปกติไม่ใช่ทันที แต่ในการดำเนินการที่เกิดขึ้นไม่บ่อยอย่างการอัปโหลดไฟล์หรือการส่งเมล
ลำดับที่ถูกต้อง:
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
ทำงานหนึ่งสัปดาห์ในโหมดนั้น ครอบคลุมทุกสถานการณ์ที่ไม่ปกติ: การสำรองข้อมูล การอัปเดต การอัปโหลดไฟล์ขนาดใหญ่ จากนั้นไล่ดูสิ่งที่สะสมไว้:
sudo aa-logprof
คำสั่งนี้ไล่ผ่านการละเมิดที่ถูกบันทึกและถามทีละข้อว่าจะอนุญาตหรือไม่ ตรงนี้ต้องใส่ใจ: อนุญาตสิ่งที่เป็นส่วนหนึ่งของงานบริการจริง ๆ ไม่ใช่ทุกอย่างที่ผ่านตา — มิฉะนั้นคุณจะได้โปรไฟล์ที่อนุญาตทุกอย่าง และความหมายก็สูญไป
และเมื่อถึงตอนนั้นจึงค่อย:
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
ดูการปฏิเสธได้ที่ไหน
การละเมิดทั้งหมดไปลงที่เจอร์นัลของเคอร์เนล:
sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log
ไฟล์ที่สองจะมีถ้าติดตั้ง auditd ไว้ — และเมื่อมีมัน บันทึกจะละเอียดกว่าอย่างเห็นได้ชัด บันทึกการปฏิเสธแสดงชื่อโปรไฟล์ การดำเนินการที่ร้องขอ และเส้นทางที่ถูกเข้าถึง เท่านั้นก็พอที่จะบอกได้ว่าควรแก้โปรไฟล์หรือควรดีใจที่มันทำงาน
มีอาการหนึ่งที่ควรจำ: บริการทำตัวแปลก — อ่านไฟล์ตั้งค่าไม่ได้ เขียนลงไดเรกทอรีไม่ได้ เปิดซ็อกเก็ตไม่ได้ — ในขณะที่ล็อกของมันเองแสดงข้อผิดพลาด «permission denied» ทั้งที่สิทธิ์ถูกต้องอย่างชัดเจน นั่นเกือบทุกครั้งคือ AppArmor และสิ่งแรกที่ต้องทำคือดูในเจอร์นัลของเคอร์เนล
มาตรการเชิงปฏิบัติ ไม่ใช่เชิงทฤษฎี
โปรไฟล์สำหรับ PHP-FPM หรือ nginx คุ้มค่าในแบบที่จับต้องได้ เมื่อกระบวนการถูกจำกัด web shell ที่เข้าถึงเว็บไซต์ก็อ่านไฟล์ระบบไม่ได้ รันเชลล์ไม่ได้ และเขียนอะไรนอกไดเรกทอรีที่อนุญาตไม่ได้ เว็บไซต์ที่ถูกเจาะก็ยังเป็นเว็บไซต์ที่ถูกเจาะแทนที่จะกลายเป็นสิทธิ์เข้าถึงทั้งเครื่อง — และการเปลี่ยนผ่านตรงนั้นแหละคือความเสียหายส่วนใหญ่
ลำดับการนำมาใช้ที่สมเหตุสมผล: เริ่มจากโปรไฟล์ของสิ่งที่หันออกสู่อินเทอร์เน็ต (เว็บเซิร์ฟเวอร์ PHP-FPM) จากนั้นฐานข้อมูล แล้วจึงตามความจำเป็น ไม่จำเป็นต้องเปิดทุกอย่างพร้อมกัน และไม่มีชุดสำเร็จรูปที่ใช้ได้ทั่วไป: โปรไฟล์ขึ้นอยู่กับว่าไฟล์ของคุณอยู่ที่ไหน
ควรตรวจอะไรเป็นประจำ
โปรไฟล์กลับไปเป็น unconfined บ่อยกว่าที่คิด: การอัปเดตแพ็กเกจอาจแทนที่ไฟล์โปรไฟล์ การแก้จุดบกพร่องด้วยมือทิ้งบริการไว้ใน complain และบริการใหม่ก็มาโดยไม่มีโปรไฟล์เลย ตัวเลขสองตัวมีประโยชน์: มีโปรไฟล์กี่ตัวอยู่ใน enforce และมีกระบวนการที่หันสู่เครือข่ายกี่ตัวที่ยัง unconfined การเปลี่ยนแปลงของตัวใดตัวหนึ่งควรค่าแก่การรับรู้ ภาพเมื่อรวมไว้บนหน้าเดียวเป็นอย่างไรดูได้ที่เดโมด้านล่าง