จำกัดการแชร์ Samba ให้เหลือผู้ใช้หนึ่งคนและที่อยู่ VPN หนึ่งที่อยู่
พารามิเตอร์ valid users และ hosts allow ของ Samba ไม่ได้จับคู่บุคคลกับที่อยู่ ชื่อการแชร์สองชื่อสามารถแสดงคู่นั้นได้ และการทดสอบคู่ไขว้ก็พิสูจน์ได้
การออกแบบนี้สับสนระหว่างสิทธิ์สองอย่าง คือ ใครใช้ไดเรกทอรีได้ และที่อยู่ใดเชื่อมต่อได้เลย การเขียนรายการบัญชีไว้ข้างรายการต้นทางดูเหมือนการจับคู่ แต่ Samba ประเมินสองรายการนั้นเป็นเงื่อนไขอิสระจากกัน ผู้ใดผ่านทั้งสองเงื่อนไขก็ได้รับอนุญาต ซึ่งเป็นกฎที่กว้างกว่าที่ผู้ดูแลส่วนใหญ่ตั้งใจ ทางแก้คือจัดรูปแบบการแชร์ใหม่ หรือเพิ่มชั้นนโยบายที่แสดงคู่ได้
ความเชื่อผิด: สองรายการสร้างกฎเดียว
เอกสารอ้างอิง smb.conf นิยาม valid users และ hosts allow เป็นพารามิเตอร์สองตัวที่ไม่เกี่ยวข้องกัน และการตั้งทั้งสองบนการแชร์เดียวคือจุดที่ความสับสนเริ่ม ตั้ง valid users = mira, tomas และ hosts allow = 10.77.0.21, 10.77.0.22 แล้วจะยอมรับสี่ชุดผสม คือ Mira จากที่อยู่ใดก็ได้ และ Tomas จากที่อยู่ใดก็ได้ ไม่มีสิ่งใดในการกำหนดค่าเชื่อมชื่อแรกกับที่อยู่แรก และลำดับที่ชื่อปรากฏไม่มีความหมาย การสลับลำดับ การเพิ่มบรรทัด hosts allow ที่สอง หรือการใส่ชื่อหนึ่งชื่อต่อบรรทัดไม่เปลี่ยนอะไร ผลลัพธ์คือผลคูณของสองรายการ ไม่ใช่การแมประหว่างกัน
สิ่งที่คนส่วนใหญ่ต้องการจริง ๆ แคบกว่า คือ Mira จากที่อยู่เดียวเท่านั้น และ Tomas จากอีกที่อยู่หนึ่งเท่านั้น นิยามการแชร์เดียวไม่มีไวยากรณ์สำหรับการผูกนั้น และไม่มีลำดับใดที่ชาญฉลาดพอจะสร้างมันขึ้นมา นี่คือรูปแบบนโยบายที่ Samba ไม่แสดงออกภายในแชร์เดียว และนั่นคือที่ที่ความเชื่อผิดยังคงอยู่
สิ่งที่ Samba ประเมิน และลำดับการประเมิน
ขั้นตอนดำเนินตามลำดับคงที่ และลำดับที่ผิดให้การวินิจฉัยที่ผิด ไคลเอนต์เปิดการเชื่อมต่อ ตรวจโฮสต์ส่วนกลางหากมีการกำหนดค่า การตั้งเซสชันพิสูจน์ตัวตนบัญชี จากนั้นไคลเอนต์เชื่อมต่อกับการแชร์ ซึ่งรายการโฮสต์ของการแชร์นั้น valid users และการตั้งค่าอ่านอย่างเดียวถูกนำมาใช้ และเมื่อไฟล์ถูกเปิดเท่านั้นสิทธิ์ของระบบไฟล์ของตัวตนที่พิสูจน์แล้วจึงตัดสิน แต่ละขั้นปฏิเสธคำขอได้เอง และการผ่านขั้นหนึ่งไม่บอกอะไรเกี่ยวกับขั้นถัดไป ผลลัพธ์สำคัญคือบัญชีเป็นที่รู้จักแล้วเมื่อประเมินรายการโฮสต์ของการแชร์ และรายการโฮสต์ยังไม่มีวิธีระบุชื่อบัญชีนั้น
นี่คือเหตุผลที่การแชร์ผูกผู้ใช้หนึ่งคนกับที่อยู่หนึ่งที่อยู่ไม่ได้ hosts allow และ valid users เป็นเงื่อนไขแยกที่ใช้ในขั้นเชื่อมต่อทรีเดียวกัน และแต่ละเงื่อนไขตอบคำถามของตัวเอง เงื่อนไขโฮสต์ไม่เคยรับชื่อบัญชีเป็นอินพุต จึงเขียนเป็นรายผู้ใช้ไม่ได้ มีเพียงการแชร์ที่สอง หรือชั้นนโยบายนอก Samba เท่านั้นที่แสดงคู่ได้
ค่าโกลบอลสำคัญเพราะวิธีสืบทอด การแชร์ที่ละเว้น hosts allow สืบทอดค่าโกลบอล และการแชร์ที่ตั้งค่าของตัวเองใช้ค่านั้นแทนค่าโกลบอล ไม่ใช่เพิ่มเติม ดังนั้นรายการโกลบอลที่กว้างจะขยายการแชร์ที่ไม่เคยตั้งค่าพารามิเตอร์ และไม่ทำอะไรกับการแชร์ที่กำหนดค่าของตัวเอง รัน testparm -s แล้วอ่านค่าต่อการแชร์ที่มันพิมพ์ออกมา เพราะผลลัพธ์นั้นคือนโยบายที่ใช้จริง ไม่ใช่ไฟล์บนดิสก์
การจำกัดการแชร์เดียวก็ไม่ทำอะไรกับส่วนที่เหลือของเซิร์ฟเวอร์ การแชร์อื่น คิวเครื่องพิมพ์ และการเชื่อมต่อ IPC ต่างมีกฎของตัวเอง ดังนั้นการออกแบบที่พึ่งรายการที่อยู่ของการแชร์เดียวจึงปกป้องเส้นทางเดียว ไม่ใช่โฮสต์
สองชื่อการแชร์บนไดเรกทอรีเดียว
เมื่อไดเรกทอรีเดียวกันต้องเข้าถึงได้โดยสองคนจากสองที่อยู่ ให้เปิดเผยสองครั้งด้วยชื่อที่ต่างกัน แต่ละบล็อกมีบัญชีหนึ่งบัญชีและต้นทางหนึ่งต้นทาง ซึ่งเปลี่ยนคู่ให้เป็นสิ่งที่การกำหนดค่าบังคับได้ ต้นทุนคือแต่ละคนใช้ชื่อการแชร์ต่างกันเพื่อเข้าถึงไฟล์เดียวกัน และนั่นต้องเป็นการเปลี่ยนแปลงโดยเจตนาที่ฝั่งไคลเอนต์
[shared-mira]
path = /srv/shared
guest ok = no
read only = yes
valid users = mira
hosts allow = 10.77.0.21
hosts deny = ALL
[shared-tomas]
path = /srv/shared
guest ok = no
read only = yes
valid users = tomas
hosts allow = 10.77.0.22
hosts deny = ALL
ประตูการแชร์ไม่ใช่สิทธิ์ของระบบไฟล์ ตัวตนทั้งสองยังต้องเข้าถึงไดเรกทอรีผ่าน ACL พื้นฐาน และการตั้งค่าอ่านอย่างเดียวเป็นชั้นที่สองไม่ใช่ชั้นเดียว ให้สิทธิ์เขียนเฉพาะเมื่อกระบวนการทำงานต้องการ แล้วตรวจสอบว่าไฟล์ที่สร้างโดยตัวตนหนึ่งยังใช้ได้กับอีกตัวตน
ทั้งสองบล็อกชี้ไปที่เส้นทางเดียว การเปลี่ยนแปลงในไดเรกทอรีจึงส่งผลต่อทั้งสองการแชร์ โดยปกติแล้วนั่นคือเป้าหมาย แต่มันยังหมายความว่าข้อผิดพลาดเรื่องสิทธิ์จะมองเห็นได้โดยผู้ใช้ทั้งสองพร้อมกัน
ที่อยู่ต้นทางพิสูจน์อะไรได้
ที่อยู่ที่ Samba เห็นคือที่อยู่ที่ไปถึงเซิร์ฟเวอร์ ไม่ใช่ที่อยู่ที่ไคลเอนต์คิดว่าตัวเองมี เกตเวย์ VPN ที่แปลงไคลเอนต์ทุกตัวเป็นที่อยู่ต้นทางเดียวจะลบความแตกต่างนั้น ไคลเอนต์ทั้งหมดมาถึงในฐานะโฮสต์เดียวกัน และรายการต้นทางแยกแยะพวกมันไม่ได้อีกต่อไป การจัดสรรที่คงที่ต่อไคลเอนต์และเกตเวย์ที่รักษาต้นทางเป็นเงื่อนไขเบื้องต้นในการใช้ที่อยู่เป็นนโยบายเลย หากไม่มีทั้งสองอย่าง การจำกัดจะวัดเกตเวย์ ไม่ใช่ผู้ใช้
ถึงกระนั้น ที่อยู่ก็ไม่ใช่อุปกรณ์ แล็ปท็อปสองเครื่องหลังที่อยู่ทางอุโมงค์เดียว สัญญาเช่าที่จัดสรรใหม่ และเวิร์กสเตชันที่ใช้ร่วมกันต่างหักล้างสมมติฐานที่ว่าต้นทางระบุตัวบุคคล ควรถือว่าการจำกัดเป็นขอบเขตเครือข่าย และรักษาบัญชี SMB ที่พิสูจน์ตัวตนแล้วเป็นชั้นตัวตน พร้อมข้อมูลรับรองอุปกรณ์เช่นใบรับรองหากต้องการอนุญาตอุปกรณ์
นี่คือเหตุผลที่การออกแบบปิดการแชร์ไม่ใช่เซิร์ฟเวอร์ คู่ที่ถูกปฏิเสธยังเปิดเซสชัน เข้าถึงการแชร์อื่น หรือแสดงรายการเซิร์ฟเวอร์ได้ ซึ่งเป็นผลลัพธ์ที่ต่างจากความล้มเหลวในการพิสูจน์ตัวตนตอนเชื่อมต่อ หากข้อกำหนดคือการปฏิเสธก่อนการพิสูจน์ตัวตน พารามิเตอร์การแชร์ของ Samba ก็เป็นเครื่องมือที่ผิด
พิสูจน์ด้วยคู่ไขว้
ตรวจสอบการกำหนดค่า แล้วทดสอบสี่ชุดผสมด้วยการเชื่อมต่อใหม่แทนเซสชันที่ใช้ซ้ำ คู่ที่ตั้งใจควรเข้าถึงไดเรกทอรี และคู่ไขว้ทั้งสองควรล้มเหลว เซสชันที่แคชไว้จากการทดสอบก่อนหน้าจะตอบแทนชุดผสมที่ผิดอย่างยินดี และทำให้กฎที่เสียดูเหมือนถูกต้อง
testparm -s
smbclient //fileserver/shared-mira -U mira -c 'ls'
smbclient //fileserver/shared-tomas -U tomas -c 'ls'
smbstatus --shares
การตรวจไวยากรณ์พิสูจน์เพียงว่าไฟล์ถูกแยกวิเคราะห์ ข้อมูลรับรอง ACL และการตัดสินใจเรื่องโฮสต์ถูกทดสอบด้วยการเชื่อมต่อจริง ดังนั้นรันคำสั่งไคลเอนต์จากที่อยู่ที่ต้องการทดสอบ และดูว่าขั้นใดปฏิเสธ ถ้าคู่ไขว้สำเร็จ แสดงว่ารายการโฮสต์ที่ใช้จริงกว้างกว่าที่บล็อกบอก และ testparm -s คือสิ่งแรกที่ต้องอ่าน ถ้าคู่ไขว้ล้มเหลวด้วยเหตุผลที่ผิด ผู้ต้องสงสัยคือบัญชีหรือ ACL
การเฝ้าดูเซสชันด้วย smbstatus และการฆ่าพวกมันเป็นการตอบสนองหลังจากเริ่มเข้าถึงแล้ว ไม่ใช่การควบคุมการรับเข้า การบล็อกที่อยู่ที่สังเกตได้ทั้งหมดอาจตัดผู้ใช้ที่ไม่เกี่ยวข้องหลัง NAT เดียวกันด้วย จึงเป็นการตัดสินใจที่อยู่ในการนิยามการแชร์ และการเฝ้าดูอยู่ในกระบวนการตอบสนอง แยกสองอย่างนี้ออกจากกัน และการออกแบบยังคงซื่อสัตย์เกี่ยวกับสิ่งที่มันบังคับใช้