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

ความสามารถครอบคลุมอะไร

ภายในเนมสเปซของตน โปรเซสที่ถือ NET_ADMIN สามารถยกอินเทอร์เฟซขึ้นและลง กำหนดที่อยู่ เพิ่มและลบเส้นทาง และเขียนกฎไฟร์วอลล์ ซึ่งเป็นกลุ่มการทำงานที่ capabilities(7) รวบรวมไว้ภายใต้ความสามารถนี้ นอกจากนี้ยังปรับการตั้งค่าระดับอินเทอร์เฟซที่ควบคุมว่าวิธีที่เคอร์เนลจัดคิวและกรองทราฟฟิกได้ ลูกค้า VPN มักต้องการบางส่วนในตอนเริ่มต้นและไม่ต้องการสิ่งอื่นหลังจากนั้น รูปอิมเมจส่วนใหญ่จึงขอสิทธิ์มากกว่าที่ใช้

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

เนมสเปซกำหนดรัศมีของความเสียหาย

คอนเทนเนอร์บนเครือข่ายบริดจ์ของตนเองเข้าถึง loopback ของตนเอง อินเทอร์เฟซของตนเอง และตารางเส้นทางของตนเอง การให้ NET_ADMIN ที่นั่นทำให้ลูกค้า VPN สร้างอุโมงค์ได้โดยไม่แตะการตัดสินใจด้านเส้นทางของโฮสต์ ซึ่งเป็นรูปแบบที่อิมเมจคอนเทนเนอร์ส่วนใหญ่ถือว่าเป็นเช่นนั้น

เปลี่ยนคอนเทนเนอร์นั้นไปใช้เครือข่ายของโฮสต์ แล้วการให้สิทธิ์เดียวกันจะแก้ไขเส้นทางของโฮสต์และไฟร์วอลล์ของโฮสต์ เพราะไม่มีเนมสเปซแยกเหลืออยู่ ลูกค้าที่ควรจัดการอุโมงค์เดียวสามารถเปลี่ยนเส้นทางทราฟฟิกของทั้งเครื่องได้ และข้อผิดพลาดในสคริปต์ฉีกของมันจะทิ้งกฎที่ไม่มีใครเขียนไว้บนโฮสต์ ไม่มีอะไรในความสามารถเปลี่ยนไป บริบทต่างหากที่เปลี่ยน นี่คือเหตุผลที่ไฟล์ compose เดียวกันทำงานต่างกันบนสองโฮสต์

ข้อกำหนดเบื้องต้นสามข้อที่หลอมเป็นหนึ่ง

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

services:
  vpn:
    image: example/vpn-client:latest
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

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

ให้การทำงานที่แคบ ไม่ใช่โหมด

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

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

ความลับเป็นอีกการตัดสินใจหนึ่ง การถือ NET_ADMIN ไม่ได้บอกอะไรเกี่ยวกับตัวตนของคู่ค้าที่ลูกค้าแสดง ข้อมูลรับรองที่โหลด หรือวิธีหมุนเวียนข้อมูลเหล่านั้น การบริหารเครือข่ายไม่ได้ให้ความไว้วางใจ

ตรวจสอบการเปลี่ยนแปลงและบันทึกว่าเหตุใดการให้สิทธิ์นี้จึงมีอยู่

ยืนยันว่าคอนเทนเนอร์ได้รับอะไรจริงก่อนแก้ปัญหาอุโมงค์ การตรวจสอบด้านล่างรายงานความสามารถที่เพิ่มและโหมดเครือข่าย จากนั้นแสดงให้เห็นว่ารายการอินเทอร์เฟซเป็นอย่างไรจากภายใน:

docker inspect --format '{{.HostConfig.CapAdd}} {{.HostConfig.NetworkMode}} {{.HostConfig.Privileged}}' vpn
docker exec vpn sh -c 'grep CapEff /proc/self/status'
docker exec vpn ip -br addr
docker exec vpn ip route

หากมีความสามารถอยู่แต่รายการอินเทอร์เฟซยังว่าง แสดงว่าลูกค้าล้มเหลวก่อนที่จะสร้างอะไรได้ และที่ต่อไปที่ควรดูคือบันทึกของคอนเทนเนอร์ หากมีอุโมงค์อยู่แต่ทราฟฟิกไม่ไหล ตารางเส้นทางภายในคอนเทนเนอร์จะตอบคำถามถัดไป

ทดสอบเส้นทางฉีกด้วย เพราะลูกค้าที่เขียนกฎไฟร์วอลล์อาจทิ้งกฎเหล่านั้นไว้ หยุดคอนเทนเนอร์และตรวจสอบชุดกฎของโฮสต์อีกครั้งหากใช้เครือข่ายของโฮสต์ การให้สิทธิ์ที่จำเป็นเพียงสองวินาทีตอนเริ่มต้นไม่ควรอธิบายในไฟล์ compose ว่าเป็นข้อกำหนดถาวรโดยไม่มีบันทึกที่อธิบายเรื่องนี้

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

บทความที่เกี่ยวข้อง