คอนเทนเนอร์ LXC ที่ไม่ได้รับสิทธิพิเศษคืออะไร


20

มันหมายความว่าอย่างไรถ้าคอนเทนเนอร์ Linux (คอนเทนเนอร์ LXC) เรียกว่า "unprivileged"

คำตอบ:


20

คอนเทนเนอร์ LXC ที่ไม่ได้รับสิทธิพิเศษเป็นสิ่งที่ใช้ประโยชน์จากเนมสเปซผู้ใช้ ( ) คือคุณลักษณะของเคอร์เนลที่ช่วยให้การ map ช่วงของ UIDs บนโฮสต์ลงใน namespace ภายในซึ่งผู้ใช้ที่มี UID 0 สามารถอยู่ได้อีกครั้ง

ตรงกันข้ามกับการรับรู้เบื้องต้นของฉันเกี่ยวกับคอนเทนเนอร์ LXC ที่ไม่ได้รับสิทธิพิเศษชั่วขณะหนึ่งนี่ไม่ได้หมายความว่าภาชนะนั้นจะต้องเป็นของผู้ใช้โฮสต์ที่ไม่มีสิทธิพิเศษ นั่นเป็นเพียงความเป็นไปได้เพียงอย่างเดียว

ที่เกี่ยวข้องคือ:

  1. ระบุช่วงของ UID รองและ GID ที่กำหนดไว้สำหรับผู้ใช้โฮสต์ ( usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  2. ... และช่วงนี้ถูกแมปในการกำหนดค่าคอนเทนเนอร์ ( lxc.id_map = ...)

ดังนั้นแม้rootสามารถเป็นเจ้าของคอนเทนเนอร์ที่ไม่มีสิทธิพิเศษเนื่องจาก UID ที่มีประสิทธิภาพของกระบวนการคอนเทนเนอร์บนโฮสต์จะสิ้นสุดภายในช่วงที่กำหนดโดยการแมป

อย่างไรก็ตามสำหรับ rootคุณจะต้องกำหนด ID ผู้ใต้บังคับบัญชาก่อน ซึ่งแตกต่างจากผู้ใช้สร้างขึ้นผ่านทางadduser, rootจะไม่ได้มีช่วงของรหัสผู้ใต้บังคับบัญชาที่กำหนดโดยค่าเริ่มต้น

โปรดทราบว่าช่วงที่คุณให้เต็มนั้นอยู่ที่การกำจัดของคุณดังนั้นคุณอาจมี 3 คอนเทนเนอร์ที่มีบรรทัดการกำหนดค่าต่อไปนี้ (แสดงเฉพาะการแมป UID):

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

สมมติว่าrootเป็นเจ้าของ UID รองระหว่าง 100000 ถึง 400000 เอกสารทั้งหมดที่ฉันพบแนะนำให้ใช้ ID ผู้ใต้บังคับบัญชา 65536 ต่อคอนเทนเนอร์บางคนใช้ 100000 เพื่อทำให้อ่านได้ง่ายขึ้น

กล่าวอีกนัยหนึ่ง: คุณไม่จำเป็นต้องกำหนดช่วงเดียวกันให้กับแต่ละคอนเทนเนอร์

ด้วยมากกว่า 4 พันล้าน (~ 2^32รหัสรองที่เป็นไปได้ ) นั่นหมายความว่าคุณสามารถใจกว้างได้เมื่อจัดการช่วงรองให้กับผู้ใช้โฮสต์ของคุณ

คอนเทนเนอร์ที่ไม่มีสิทธิพิเศษที่เป็นเจ้าของและดำเนินการโดยรูท

การถูนั้นอีกครั้ง แขก LXC ที่ไม่ได้รับสิทธิพิเศษไม่จำเป็นต้องเรียกใช้โดยผู้ใช้ที่ไม่มีสิทธิพิเศษบนโฮสต์

การกำหนดค่าคอนเทนเนอร์ของคุณด้วยการแมป UID / GID รองเช่นนี้:

lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000

ที่ผู้ใช้ rootบนโฮสต์เป็นเจ้าของที่ได้รับช่วง ID รองจะช่วยให้คุณ จำกัด ผู้เข้าพักได้ดียิ่งขึ้น

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

โดยปกติเมื่อทำการค้นหาข้อมูลเกี่ยวกับ LXC ในเว็บคุณจะได้รับแจ้งว่าไม่สามารถทำการเข้าร่วมกับแขก LXC ที่ไม่มีสิทธิ์ได้โดยอัตโนมัติ แต่ที่เป็นจริงโดยเฉพาะการเริ่มต้นสำหรับภาชนะเหล่านั้นซึ่งไม่ได้อยู่ในการจัดเก็บข้อมูลทั้งระบบสำหรับบรรจุ (ปกติบางอย่างเช่น/var/lib/lxc) หากพวกเขา (ซึ่งมักจะหมายถึงพวกเขาถูกสร้างขึ้นโดยรูทและเริ่มโดยรูท) มันเป็นเรื่องที่แตกต่าง

lxc.start.auto = 1

จะทำงานได้ค่อนข้างดีเมื่อคุณใส่ลงในคอนเทนเนอร์ของคุณ

รับสิทธิ์และการกำหนดค่าที่ถูกต้อง

ฉันดิ้นรนกับตัวเองเล็กน้อยดังนั้นฉันจึงเพิ่มหัวข้อที่นี่

นอกเหนือจากตัวอย่างข้อมูลการกำหนดค่าที่รวมอยู่ด้วยlxc.includeซึ่งมักจะมีชื่อ/usr/share/lxc/config/$distro.common.conf(ที่$distroชื่อของ distro) คุณควรตรวจสอบว่ามี/usr/share/lxc/config/$distro.userns.confระบบของคุณหรือไม่และรวมไว้ด้วย เช่น:

lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf

นอกจากนี้ยังเพิ่มการแมป ID รอง:

lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535

ซึ่งหมายความว่าโฮสต์ UID 100000 อยู่root ในเนมสเปซผู้ใช้ของแขก LXC

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

# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs

สิ่งนี้จะช่วยให้คุณสามารถเรียกใช้คอนเทนเนอร์หลังจากความพยายามครั้งแรกของคุณอาจมีข้อผิดพลาดเกี่ยวกับการอนุญาต


4
คำตอบที่ดี - แต่lxcไม่จำเป็นสำหรับสิ่งนี้ คุณสามารถสร้างภาชนะ namespace ใด ๆ โดยใช้เครื่องมือutil-linux unshareคุณสามารถป้อนกล่าวว่าภาชนะที่ใช้เครื่องมือutil-linux nsenterเครื่องมือหลังยังช่วยให้คุณสามารถเพิ่มกระบวนการที่กำลังทำงานอยู่ในคอนเทนเนอร์ที่สร้างไว้แล้วโดยไม่ต้องใช้มัน การสนับสนุนเนมสเปซถูกนำไปใช้ในเคอร์เนล
mikeserv

4
@mikeserv: คุณหมายถึงว่าคุณไม่จำเป็นต้องใช้ LXC เพื่อใช้งานusernsใช่ไหม? ฉันรู้ว่า. ฉันรู้ว่าตอนนี้ Docker มีห้องสมุดของตัวเองที่ใช้สิ่งอำนวยความสะดวกเหล่านี้ แต่คุณจะจัดระบบทั้งหมดโดยไม่ต้องใช้สิ่งอำนวยความสะดวกที่นำเสนอโดย LXC อย่างไร แล้วทำไมคุณถึงทำอย่างนั้น? ฉันหมายถึงการมีแอปพลิเคชันเดียวและรวมกับchrootสิ่งนี้สามารถช่วยได้ แต่ LXC ได้รวมชื่อพื้นที่ (UTS, mount ฯลฯ ฯลฯ ) เข้าด้วยกันเพื่อรวมระบบทั้งหมด
0xC0000022L

2
เอาละ ... อย่างที่ฉันบอกunshareไปแล้วว่าทำสิ่งนี้ได้อย่างน่าชื่นชมสำหรับทุก ๆ / ทุก namespaces - และคุณจะได้รับ/procเมาท์ส่วนตัวแยกต่างหากพร้อม cli-switch เดี่ยว หากโปรแกรมเดียวเป็นinitของคุณและchrootเป็นinitramfsแล้วคุณจะได้รับภาชนะทั้งในไม่กี่วินาทีแบน
mikeserv

0

หากต้องการติดตาม 0xC0000022L ซึ่งโซลูชันทำงานได้ดีสำหรับฉันฉันได้เขียนสคริปต์ Perl เพิ่มขึ้น - uid-gid.pl เพื่อทำการเปลี่ยนแปลงการเป็นเจ้าของที่จำเป็นโดยอัตโนมัติดังนั้นไฟล์ภายในคอนเทนเนอร์ LXC จะถูกแมปอย่างถูกต้อง

หากไม่มีการตั้งค่าที่เสนอนี้ไฟล์ภายในรูทคอนเทนเนอร์ LXC ที่เป็นของ 0 / root บนโฮสต์หลักจะอยู่ภายในคอนเทนเนอร์ LXC เองจะถูกแมปกับ 65534 / ไม่มีใคร ในการแม็พกับ 0 / root ภายในคอนเทนเนอร์ LXC จะต้องอยู่ใน 100000 บนโฮสต์

นี่คือคำอธิบายที่นี่https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/และสคริปต์สามารถรับโดยตรงบน gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.