Score:7

ให้สิทธิ์ผู้ใช้ที่ไม่ใช่รูทเพื่อใช้หนึ่งพอร์ต

ธง jp

ฉันโฮสต์เซิร์ฟเวอร์แล็บที่ฉันรูท (และเป็นผู้ใช้ทั่วไป)

ชื่อโดเมนคือ example.org และฉันให้โดเมนย่อยแก่สมาชิกแต่ละคน เช่น bob.example.org สำหรับ Bob และ anna.example.org สำหรับผู้ใช้ Anna ฉันคิดว่าคุณได้รับข้อตกลง :) โดเมนย่อยถูกย้อนกลับพร็อกซีโดยใช้ nginx ไปยังพอร์ตเฉพาะ

คำถามของฉันคือมีวิธีใดบ้างที่ฉันสามารถให้สิทธิ์แก่ผู้ใช้ที่ไม่ใช่รูทเพื่อเริ่มคอนเทนเนอร์นักเทียบท่าในช่วงพอร์ตเฉพาะของพวกเขา ตัวอย่างเช่น Anna ได้รับช่วง 1300-1350 โดยที่พอร์ต 1300 ถูกผูกไว้กับ anna.example.org และพอร์ตอื่นสำรองไว้

ระบบใช้งาน Debian 11 Bullseye และ Docker เวอร์ชันล่าสุด

Cyclic3 avatar
br flag
ฉันจะ * ระวังอย่างมากเกี่ยวกับการให้ผู้ใช้ที่ไม่ใช่รูทเข้าถึงนักเทียบท่ามันง่ายเหมือน `docker run -v /:/pwn -it cyclic3/pwn` เพื่อเข้าถึง r/w อย่างสมบูรณ์ไปยังระบบไฟล์ทั้งหมด และการเพิ่ม `--privileged' นั้นแทบจะใช้งานได้เหมือนกันจากการรูทบนเครื่องนั้น . ฉันเห็นสิ่งนี้ผิดพลาดมาหลายครั้ง รวมถึงใน CTF ที่ดำเนินการโดยบริษัทไซเบอร์ขนาดใหญ่แห่งหนึ่ง ซึ่งตั้งใจให้มีความท้าทายเพียงครั้งเดียว แต่ลงเอยด้วยการเปิดเผยเครื่องจักรทั้งหมดที่ใช้สำหรับหมวดหมู่นั้น สามารถทำได้อย่างปลอดภัย แต่ฉันคิดว่ามันสำคัญมากที่จะเน้นย้ำว่าสิ่งนี้สามารถไปทางใต้ได้ไกลแค่ไหน
Oscar Andersson avatar
jp flag
ความคิดเห็นที่ยอดเยี่ยมเกี่ยวกับเกร็ดเล็กเกร็ดน้อยของ CTF บางครั้งฉันก็แข่งขันด้วยตัวเอง ฟังดูเหมือนการแข่งขันที่สนุก! :) อย่างไรก็ตาม ฉันได้ตัดสินใจที่จะแยกผู้ใช้ออกจากกันโดยสิ้นเชิงโดยใช้คอนเทนเนอร์ที่แตกต่างกัน โดยไม่มีการเข้าถึงโฮสต์ ยกเว้นพอร์ตที่เปิดอยู่บางพอร์ต ขอบคุณที่สละเวลา.
Score:9
ธง td
bob

AFAIK Linux มีเฉพาะพอร์ตที่ได้รับสิทธิพิเศษตามแนวคิดเท่านั้นเมื่อเทียบกับพอร์ตที่ไม่มีสิทธิพิเศษ

พารามิเตอร์การปรับแต่งเคอร์เนลของ Linux net.ipv4.ip_unprivileged_port_start กำหนดว่าพอร์ตใดจะได้รับสิทธิพิเศษ พอร์ตทั้งหมดระหว่าง 0 ถึง net.ipv4.ip_unprivileged_port_start ได้รับสิทธิพิเศษ

พอร์ตที่มีสิทธิพิเศษสามารถใช้ได้เฉพาะโดยกระบวนการที่เริ่มต้นโดยผู้ใช้รูทหรือด้วยสิทธิ์รูท หรือโดยกระบวนการที่กำหนด ความสามารถ CAP_NET_BIND_SERVICE ตัวอย่างเช่น sudo setcap cap_net_bind_service=ep /path/bin/application

พอร์ตอื่นๆ ทั้งหมดไม่มีสิทธิ์ใช้งานและผู้ใช้ทุกคนสามารถใช้ได้ ตราบเท่าที่พอร์ตนั้นยังไม่ได้ใช้งาน

ฉันไม่ทราบวิธีอื่นในการอนุญาตให้ผู้ใช้เฉพาะใช้พอร์ตเฉพาะ

Oscar Andersson avatar
jp flag
ขอบคุณ @บ๊อบ! ฉันคิดว่าจะให้คอนเทนเนอร์นักเทียบท่ากับ Debian 11 แก่ผู้ใช้แต่ละราย ซึ่งพวกเขาสามารถโรมมิ่งได้อย่างอิสระ จากนั้นฉันจะผูกพอร์ต 80 และ 22 กับโดเมนย่อยของโดเมนหลักของฉัน คุณคิดยังไงเกี่ยวกับที่? บางทีมันอาจเพิ่มความปลอดภัยอีกชั้นหนึ่ง
Score:6
ธง in

ก่อนอื่น เฉพาะผู้ใช้ที่เชื่อถือได้เท่านั้นที่ได้รับอนุญาตให้ควบคุม Docker daemon ของคุณ

docker daemon ทำงานเป็นรูทโดยค่าเริ่มต้นในการติดตั้ง Debian Bullseye การเพิ่มผู้ใช้ใน นักเทียบท่า กลุ่มให้สิทธิ์การเข้าถึงรูท psuedo แก่ผู้ใช้เนื่องจากมีการควบคุม docker daemon ที่มีจำนวนการเข้าถึงนั้น ผู้ใช้ทุกคนในกลุ่มนักเทียบท่าจะสามารถควบคุมโฮสต์และคอนเทนเนอร์อื่นๆ ได้อย่างสมบูรณ์ และสามารถเรียกใช้คอนเทนเนอร์ที่ --เผยแพร่พอร์ตใดก็ได้

มีตัวเลือกไม่กี่ตัวในการรักษาความปลอดภัยให้กับการเข้าถึงนักเทียบท่าของผู้ใช้

  1. นักเทียบท่าไร้รูท
  2. ซูโด
  3. เอพีไอ

1. นักเทียบท่าไร้รูท

การตั้งค่านักเทียบท่าที่ไม่มีรูท จะช่วยให้ผู้ใช้แต่ละคนเรียกใช้ docker deamon สำหรับพอร์ตที่ต่ำกว่า 1,024 จะต้องปฏิบัติตาม ข้อมูลพอร์ตที่ไม่มีสิทธิพิเศษ บ็อบจัดให้เนื่องจากผู้ใช้แต่ละคนจะ "เป็นเจ้าของ" เดมอนของตนเอง นักเทียบท่ายังมีให้ คำแนะนำที่เกี่ยวข้อง. สิ่งนี้จะไม่ทำให้แอนนาหยุดรับพอร์ตบ็อบส์

2. ซูโด

วิธีที่ง่ายที่สุดในการอนุญาตให้ผู้ใช้รันคำสั่งนักเทียบท่าคือการจัดเตรียมสคริปต์ควบคุมรูทผ่าน sudo ที่เป็นสแตติก หรือควบคุมอินพุตของผู้ใช้สำหรับอาร์กิวเมนต์ทางเลือก:

#!/bin/bash
นักเทียบท่าเรียกใช้ --detach --เผยแพร่ 1300:1300 anna/app-image
anna ALL=(root) NOPASSWD: /usr/local/bin/start-anna-image

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

3. ปลั๊กอินการอนุญาตหรือ API สำหรับนักเทียบท่า

เนื่องจาก Docker ไม่มีชั้นการอนุญาตใดๆ บน daemon คุณต้องเพิ่มบางอย่างเพื่อควบคุมการเข้าถึงของผู้ใช้

นักเทียบท่ามีมาให้ในตัว ปลั๊กอินการอนุญาต กรอบงานเพื่อเปิดใช้งานสิ่งนี้ ตัวอย่างบางส่วนคือ opa-docker-authz และ casbin-authz-ปลั๊กอิน

คุณสามารถให้ผู้ใช้เข้าถึงรูปแบบของพร็อกซี API ที่ให้การรับรองความถูกต้องและการให้สิทธิ์เหนือสิ่งที่ส่งต่อไปยัง Docker REST API มีไลบรารีนักเทียบท่าสำหรับภาษาโปรแกรมส่วนใหญ่Kubernetes+RBAC เป็นตัวอย่างของ API ที่อยู่ด้านหน้าของ Docker daemon และควบคุมการเข้าถึง (เป็นเพียงอันที่ใหญ่/ซับซ้อนที่ทำได้มากกว่านั้นมาก)

Oscar Andersson avatar
jp flag
ขอบคุณ @matt จริงๆ! คุณพูดถึงข้อดีบางอย่าง ตอนนี้ฉันได้ลองทางเลือกที่ 1 และ 2 แล้ว ฉันรู้สึกว่านักเทียบท่าที่ไม่มีรูทนั้นซับซ้อนเกินไปสำหรับฉัน และ sudo ruleset ต้องใช้เวลามากเกินไปสำหรับฉัน คุณคิดอย่างไรเกี่ยวกับการให้คอนเทนเนอร์ของตนเองแก่ผู้ใช้แต่ละคนซึ่งพวกเขาเพียงแค่ใส่ SSH ขอบเขตผู้ใช้ไม่ครอบคลุมแม้แต่โฮสต์ ประโยชน์ด้านความปลอดภัยของสิ่งนี้ในความเห็นของคุณคืออะไร? ขอบคุณ.
Score:5
ธง cn

ตราบใดที่พอร์ตไม่มีสิทธิพิเศษ ผู้ใช้ที่ไม่ใช่รูทสามารถผูกกับพอร์ตใดก็ได้ (มากกว่า 1,024) พวกเขาสามารถเริ่มคอนเทนเนอร์ด้วย:

นักเทียบท่าเรียกใช้ -- เปิดเผย 1300-1350 <ชื่อภาพ>

มาก่อนได้ก่อน หากโปรแกรมสองโปรแกรมพยายามผูกเข้ากับพอร์ตเดียวกัน มีเพียงโปรแกรมแรกเท่านั้นที่ผูกได้สำเร็จ

สำหรับพอร์ตที่มีสิทธิพิเศษ (น้อยกว่า 1024) คุณต้องมีความสามารถในการรูทหรือ CAP_NET_BIND_SERVICE ดู ความสามารถของผู้ชาย สำหรับรายละเอียด

Oscar Andersson avatar
jp flag
ขอบคุณมีเซีย! ฉันสามารถเพิ่มผู้ใช้ที่ไม่ใช่รูทลงในกลุ่มผู้ใช้นักเทียบท่าและไม่ให้รบกวนพอร์ตที่มีสิทธิพิเศษและคอนเทนเนอร์อื่นๆ ได้หรือไม่ เพื่อไม่ให้ Anna ดู แก้ไข หรือลบคอนเทนเนอร์ของ Bob
cn flag
คอนเทนเนอร์ที่เริ่มต้นโดยผู้ใช้รายเดียวจะได้รับการจัดการโดยผู้ใช้รายนั้นเท่านั้น คุณสามารถจำกัดช่วงพอร์ตที่คอนเทนเนอร์ (หรือแอปพลิเคชันใดๆ) สามารถเชื่อมโยงผ่าน SELinux หรือ AppArmor: https://serverfault.com/a/388334/30946
Matt avatar
in flag
หาก docker daemon ทำงานเป็น `root ` ไม่สำคัญว่าผู้ใช้จะใช้คำสั่ง `docker ใด โดยพื้นฐานแล้วผู้ใช้มีสิทธิ์เข้าถึงรูทผ่านดีมอนซึ่งทำงาน
Matt avatar
in flag
@OscarAndersson ไม่ ผู้ใช้ใด ๆ ในกลุ่ม `docker` ในขณะที่ docker daemon ทำงานในฐานะรูท มีสิทธิ์เข้าถึงรูทไปยังเครื่องและสามารถควบคุมคอนเทนเนอร์อื่น ๆ ได้
Nonny Moose avatar
gb flag
โปรดทราบว่าคุณสามารถส่งต่อพอร์ตนักเทียบท่าไปยังพอร์ตที่มีสิทธิพิเศษได้
Oscar Andersson avatar
jp flag
ขอบคุณ @NonnyMoose นั่นคือสิ่งที่ฉันกำลังทำอยู่ :)
Oscar Andersson avatar
jp flag
ขอบคุณ @MirceaVutcovici ที่ฟังดูน่าสนใจ ฉันจะลองดู :)
Oscar Andersson avatar
jp flag
ใช่ @Matt นั่นเป็นจุดที่ดีจริงๆฉันไม่กังวลเกินไปเกี่ยวกับผู้ใช้ของฉันโดยจงใจทำลายระบบ แต่เพิ่มเติมว่าผู้ใช้บางคนไม่มีประสบการณ์กับระบบ Linux และอาจเปิดช่องโหว่ด้านความปลอดภัยสำหรับแฮ็กเกอร์ ฉันจะนำความคิดเห็นของคุณมาพิจารณา
Score:3
ธง in

โดเมนย่อยถูกย้อนกลับพร็อกซีโดยใช้ nginx ไปยังพอร์ตเฉพาะ

คุณสามารถพร็อกซีโดเมนย่อยไปยังซ็อกเก็ต Unix

    proxy_pass http://unix:/var/run/anna.sock:/;

ทำซ้ำตามความจำเป็นสำหรับแต่ละโดเมนย่อย และตั้งค่าการอนุญาตบนซ็อกเก็ต Unix เพื่อให้เฉพาะผู้ใช้ที่คุณต้องการเท่านั้นที่สามารถฟังที่นั่นได้

โปรดทราบว่าผู้ใช้ที่สามารถเรียกใช้คอนเทนเนอร์ Docker สามารถติดตั้งได้ /etc/passwd เข้าไปในพวกเขาและรับรูต ดังนั้นจึงต้องได้รับการป้องกันแยกต่างหาก

Matt avatar
in flag
เป็นความคิดที่ดี แต่คล้ายกับข้อที่สองของคุณ นักเทียบท่ายังสามารถเมานต์ซ็อกเก็ตใดๆ ก็ได้ เว้นแต่คุณจะเพิ่มการควบคุมรูปแบบอื่นที่ผู้ใช้สามารถเรียกใช้ผ่านนักเทียบท่า
Oscar Andersson avatar
jp flag
Koterpillar และ @matt ฉันสามารถผูก / เผยแพร่ unix socket trough docker ได้หรือไม่หรือฉันควรใช้พอร์ตสำหรับสิ่งนี้ อ่านบางอย่างเกี่ยวกับมันที่นักเทียบท่ายังไม่รองรับอย่างเต็มที่
Oscar Andersson avatar
jp flag
ขอบคุณ Koterpillar ที่กล่าวถึงผลกระทบด้านความปลอดภัยของการให้สิทธิ์การเข้าถึงนักเทียบท่าแก่ผู้ใช้
in flag
เนื่องจากซ็อกเก็ต UNIX เป็นไฟล์ ให้ลองติดตั้งลงในคอนเทนเนอร์
Score:1
ธง pk

แค่อยากเพิ่มมุมมอง...งานเข้าอีกแน่นอน! แต่ที่น่าสนใจ...

พิจารณาใช้งานคอนเทนเนอร์ออร์เคสตรา เช่น Kubernetes. เช็คเอาท์ ชนิด (Kubernetes-in-Docker) สำหรับวิธีที่น่าสนใจในการรันคลัสเตอร์ Kubernetes บนโหนดเดียวที่มีเพียง Docker เท่านั้น

ตัวอย่างเช่น คุณสามารถทำบางอย่างเช่น

  • สร้างเนมสเปซ สำหรับผู้ใช้แต่ละราย เช่น บ็อบ-น และ แอนนา-น.
  • สร้าง บริการ ในแต่ละเนมสเปซ เปิดเผยพอร์ตที่ระบุ
  • ให้ผู้ใช้แต่ละคนมีบทบาท ที่ทำให้พวกเขาสามารถสร้าง ฝัก(การจัดกลุ่มคอนเทนเนอร์) ในเนมสเปซ ทำให้สามารถรับทราฟฟิกจากสิ่งที่กำหนดได้ บริการ ในเนมสเปซของพวกเขา

หากคุณจัดโครงสร้างบทบาทให้ถูกต้อง ผู้ใช้อาจได้รับอนุญาตให้เปิดใช้คอนเทนเนอร์ที่ต้องการในเนมสเปซ แต่จะไม่ได้รับอนุญาตให้แก้ไข บริการ ซึ่งกำหนดพอร์ตที่เปิดเผย

สิ่งนี้ทำให้ง่ายขึ้นเพราะเห็นแก่พื้นที่ แต่สิ่งดั้งเดิมที่บางอย่างเช่น k8s มอบให้นั้นยอดเยี่ยมสำหรับระบบที่มีผู้เช่าหลายคนเช่นนี้

Oscar Andersson avatar
jp flag
ขอบคุณ Budris โพสต์ของคุณสร้างแรงบันดาลใจอย่างแท้จริงและเป็นการทดลองเล็กน้อยถ้าฉันสามารถพูดได้ ฉันเชื่อว่ามันค่อนข้างซับซ้อนเกินไปสำหรับฉัน ขอบคุณ.
Mr.Budris avatar
pk flag
ใช่ บางอย่างเช่น kubernetes อาจเกินความจำเป็นสำหรับสภาพแวดล้อมของคุณ แต่อย่าลืมคำนึงถึงระบบเช่นนี้หากห้องปฏิบัติการของคุณเติบโตขึ้น -- อาจช่วยคุณประหยัดเวลาได้มาก (และเป็นประสบการณ์การเรียนรู้ที่น่าสนใจ) สำหรับอนาคต ไชโย!
Oscar Andersson avatar
jp flag
ขอบคุณ ฉันพร้อมสำหรับประสบการณ์การเรียนรู้อย่างแน่นอน :) (Btw แก้ไขปัญหาของฉันด้วยนักเทียบท่าที่ไม่มีรูท, systemd อ้อยอิ่งในระดับผู้ใช้และผู้ใช้ที่ไม่ใช่รูทปกติบนโฮสต์)

โพสต์คำตอบ

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