การยืนยันตัวตนผ่าน PAM ใช้ได้เมื่อรันเองแต่ล้มเหลวเมื่อเป็นบริการ OpenVPN
การล็อกอินผ่าน PAM ที่ใช้ได้จากเชลล์ root แต่ล้มเหลวภายใต้ systemd ชี้ไปที่ตัวช่วย ไม่ใช่รหัสผ่าน แยกสิทธิ์ การเข้าถึงไฟล์ และ SELinux ออกจากกัน
การยืนยันตัวตนผ่าน PAM อาจสำเร็จเมื่อคุณรันไคลเอนต์เองและล้มเหลวด้วย AUTH_FAILED ทันทีที่ systemd เริ่มโปรไฟล์เดียวกัน รหัสผ่านไม่เปลี่ยนระหว่างการรันเหล่านั้น สิ่งที่เปลี่ยนคือชุดข้อจำกัดรอบโปรเซสที่ถามคำถามกับ PAM PAM ตอบผ่านตัวช่วยที่ความสามารถในการเปลี่ยนข้อมูลรับรองของตัวเองคือสิ่งที่ยูนิตที่เสริมความแข็งแกร่งตัดออกไป หาตัวช่วยนั้นและขอบเขตที่มันต้องการก่อนที่คุณจะแตะรายการความสามารถ
unix_chkpwd คือไบนารีที่ตอบคำถามของ PAM
เมื่อใช้การยืนยันตัวตนด้วยรหัสผ่านภายในเครื่อง pam_unix นานๆ ครั้งจะอ่านไฟล์แฮชเอง มันเรียกใช้ unix_chkpwd ซึ่งดิสทริบิวชันติดตั้งเป็น setuid root หรือ setgid shadow เพื่อให้ตรวจรหัสผ่านหนึ่งรายการในนามของโปรเซสที่ไม่ควรอ่าน /etc/shadow ถอนความสามารถในการได้มาซึ่งตัวตนนั้น ตัวช่วยจะตรวจให้เสร็จไม่ได้ โมดูลจึงคืนค่าความล้มเหลวในการยืนยันตัวตนตามปกติ
จากนั้นความล้มเหลวจะดูเหมือนปัญหาเรื่องข้อมูลรับรองในทุกบันทึกที่ไคลเอนต์มองเห็น นั่นคือกับดัก ไคลเอนต์รายงานสิ่งที่ PAM บอก ส่วน PAM รายงานเพียงว่าสแตกตอบว่าไม่ การรันตัวช่วยเองในฐานะ root ก็ไม่ได้พิสูจน์อะไร เพราะมันใช้เส้นทางสิทธิ์ที่บริการไม่เคยใช้ อ่านยูนิตที่ systemd โหลดจริง แล้วอ่านบันทึกของระบบสำหรับความพยายามที่มันทำ สองมุมมองนั้นแยกปัญหาของแซนด์บ็อกซ์ออกจากปัญหาของรหัสผ่านผิด
อ่านยูนิตก่อนอ่านบันทึกรหัสผ่าน
ยูนิตที่แพ็กเกจมาอาจมี drop-in ที่คุณไม่ได้เขียน และการกำหนดค่าที่มีผลจริงคือผลลัพธ์ที่หลอมรวมกัน พิมพ์ยูนิตตามที่ systemd มองเห็น พร้อมการตั้งค่าแซนด์บ็อกซ์ที่ตัดสินว่าตัวช่วยจะยกระดับตัวเองได้หรือไม่ การตรวจแบบอ่านอย่างเดียวก็เพียงพอในขั้นนี้
systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -bคำสั่งแรกแสดงว่ายูนิตและ drop-in มาจากไหน ซึ่งสำคัญเพราะการแทนที่ที่เพิ่มเมื่อหลายเดือนก่อนมีอายุยืนกว่าความจำว่าเหตุใดมันจึงมีอยู่ คำสั่งที่สองพิมพ์ค่าแซนด์บ็อกซ์ที่สองหัวข้อถัดไปพึ่งพา
เปรียบเทียบสิ่งที่คุณเห็นกับโฮสต์ที่ใช้งานได้ซึ่งมีดิสทริบิวชันและเวอร์ชันเดียวกัน ความแตกต่างใน User, CapabilityBoundingSet หรือ NoNewPrivileges คือเบาะแสที่ชัดเจน ส่วนความแตกต่างในคอมเมนต์ร้อยแก้วไม่ใช่ จดค่าต่างๆ ไว้ก่อนเปลี่ยนสิ่งใด เพราะการเปรียบเทียบภายหลังกับเป้าหมายที่เคลื่อนไหวไม่ได้พิสูจน์อะไร หากบริการทำงานเป็นบัญชีที่ไม่มีสิทธิ์พิเศษโดยมีชุดขอบเขตว่างเปล่า ตัวช่วยแทบไม่มีอะไรให้ทำงานด้วย
การแปลงข้อมูลรับรอง การเข้าถึงไฟล์ และนโยบายคือสามขอบเขต
เริ่มจากสิ่งที่เกิดขึ้นระหว่าง exec ไบนารี setuid หรือไฟล์ที่มี file capabilities กระตุ้นการแปลงข้อมูลรับรอง ตัวตนที่ได้จึงไม่ใช่ความต่อเนื่องของผู้เรียก ชุดขอบเขตจำกัดสิ่งที่ไบนารีนั้นได้มา และ NoNewPrivileges บล็อกการได้ setuid, setgid และ file capabilities โดยสิ้นเชิง หนึ่งในสามข้อนั้นสามารถหยุดตัวช่วยได้ในขณะที่หน้าที่อื่นทั้งหมดของบริการยังคงอยู่
ต่อไป แยกการข้ามการตรวจตามดุลพินิจแบบกว้างออกจากการเข้าถึงเพื่ออ่านแบบแคบ CAP_DAC_OVERRIDE ข้ามการตรวจตามดุลพินิจแทบทุกที่ ขณะที่ CAP_DAC_READ_SEARCH ครอบคลุมการอ่านและการเดินผ่านไดเรกทอรีด้วยอำนาจเพิ่มเติมของตัวเอง ทั้งสองเป็นเครื่องมือต่างกันที่มีรัศมีผลกระทบต่างกัน และไม่มีอันใดเป็นวิธีเขียนว่าให้ PAM อ่านไฟล์ shadow
สุดท้าย ถามว่านโยบายภาคบังคับอนุญาตการกระทำนั้นเลยหรือไม่ ความสามารถของ Linux ไม่ได้แทนที่ SELinux และการมีมันไม่ได้พิสูจน์อะไรเกี่ยวกับกฎการบังคับประเภท มองการปฏิเสธการเข้าถึงไฟล์และการปฏิเสธความสามารถเป็นหลักฐานที่ต่างกัน เพราะมันระบุการแก้ไขที่ต่างกันและบ่อยครั้งเจ้าของที่ต่างกัน อ่านทุกฟิลด์ของบันทึกแทนคำเดียวว่า denied โปรแกรมใดกระทำการนั้น มันทำงานในโดเมนใด มันแตะเป้าหมายประเภทใด คลาสใดของออบเจกต์ที่เกี่ยวข้อง และนโยบายปฏิเสธสิทธิ์ใด - แต่ละอย่างจำกัดคำตอบคนละทาง
ดึงการปฏิเสธออกจากบันทึกการตรวจสอบ
บนโฮสต์ในโหมด enforcing ร่องรอยการตรวจสอบเป็นที่เดียวที่บันทึกการปฏิเสธ สอบถามเหตุการณ์ล่าสุดและอ่านเทียบกับตราเวลาของการล็อกอินที่ล้มเหลว ไม่ใช่เวลาที่คุณเริ่มสืบสวน
ausearch -m AVC,USER_AVC -ts recentผลลัพธ์ว่างเปล่าไม่ใช่หลักฐานของความบริสุทธิ์ มันหมายความว่าการตรวจสอบไม่ได้เก็บข้อมูล หรือหน้าต่างเวลาของคุณพลาดความพยายามนั้น และทั้งสองความเป็นไปได้ต้องถูกตัดออกก่อนที่คุณจะตัดนโยบายออก
แนวทางแก้ปัญหา SELinux ของ Red Hat วางการตรวจป้ายกำกับและการกำหนดค่าไว้ก่อนการสร้างกฎอนุญาต ซึ่งเป็นลำดับที่ถูกต้องสำหรับปัญหานี้ด้วย ไบนารีตัวช่วยที่ติดป้ายผิดและช่องว่างในนโยบายให้การปฏิเสธที่คล้ายกันแต่ต้องแก้ต่างกัน การสร้างกฎอนุญาตสำหรับความผิดพลาดเรื่องป้ายกำกับจะซ่อนข้อบกพร่องและปล่อยให้การอัปเดตแพ็กเกจครั้งถัดไปนำกลับมา ยืนยันป้ายกำกับบนตัวช่วยที่ติดตั้งไว้ก่อนเขียนนโยบายใดๆ
พิสูจน์การเปลี่ยนแปลงด้วยการล็อกอินที่สำเร็จหนึ่งครั้งและที่ถูกปฏิเสธหนึ่งครั้ง
เปลี่ยนเฉพาะขอบเขตที่คุณพิสูจน์แล้ว จากนั้นทดสอบทั้งสองผลลัพธ์ บัญชีที่ควรยืนยันตัวตนได้ต้องสำเร็จ และบัญชีที่มีรหัสผ่านผิดต้องยังคงล้มเหลว การเปลี่ยนแปลงที่ทำให้ทุกความพยายามสำเร็จได้ถอดการยืนยันตัวตนออกแทนที่จะซ่อมมัน
ทำความพยายามเชื่อมต่อจริงและอ่าน journal ทันทีหลังจากนั้น บรรทัดที่พิสูจน์การแก้ไขคือรายการ pam_unix(openvpn:auth) สำหรับความพยายามนั้น มันควรระบุว่าการยืนยันตัวตนสำเร็จ และไม่มีบันทึก AVC ใดที่มีวินาทีเดียวกัน
journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpnอุโมงค์ที่ใช้งานได้ยังต้องเชื่อมต่อใหม่ด้วย เพราะการเปลี่ยนแปลงแซนด์บ็อกซ์ทำให้การเชื่อมต่อครั้งที่สองเสียบ่อยกว่าครั้งแรก ตรวจสอบซ็อกเก็ตที่สร้างขึ้นหลังการเชื่อมต่อใหม่และยืนยันว่ายูนิตเดิมยังให้บริการอยู่