หนึ่งเซิร์ฟเวอร์แล็บ สามบทบาทความเชื่อใจ หนึ่งโดเมนความล้มเหลว
จุดเข้า VPN บริการส่วนตัว และงาน CI ต้องการสิทธิ์แยกจากกันแม้อยู่บนเซิร์ฟเวอร์เดียว จงแยกบทบาท แยกเครือข่าย และรักษาการกู้คืนผ่านคอนโซล
ทุกอย่างทำงานได้จนกว่าตัวรันบิลด์จะต้องการซ็อกเก็ตโฮสต์ตัวเดียวกับที่แขก VPN ใช้ และเมื่อถึงตอนนั้นก็ไม่มีใครอธิบายได้ว่าทำไมงานหนึ่งจึงอ่านคีย์ของเกตเวย์ได้ ทุกอย่างถูกติดตั้งบนเครื่องเดียวเพราะมันพอดี และแขกทุกตัวได้สิทธิ์กว้างเพราะนั่นคือวิธีที่เร็วที่สุดที่จะทำให้มันทำงานได้ ผลลัพธ์คือโฮสต์ที่มีเส้นแบ่งความเชื่อใจเป็นสายไฟ การแยกบทบาทใช้แรงน้อยกว่าที่ฟังดู และมันเริ่มจากการตั้งชื่อให้กับมัน
สามบทบาทที่ตอนนี้แบ่งทุกอย่างร่วมกัน
จุดเข้า VPN ชุดบริการส่วนตัว และตัวรันบิลด์ต้องการสิ่งที่แตกต่างกัน ตัวแรกต้องมีพอร์ตสาธารณะและเครือข่ายฝั่งส่วนตัวที่แคบ ตัวที่สองต้องมีที่จัดเก็บถาวรและความลับของแอปพลิเคชัน ตัวที่สามรันโค้ดที่คนอื่นเขียน
การให้สิทธิ์เดียวกันกับทั้งสามคือสิ่งที่ทำให้อาการสับสน เพราะหลังจากนั้นตัวใดตัวหนึ่งก็ส่งผลต่อตัวอื่นได้ งานบิลด์ที่เข้าถึงซ็อกเก็ตของไฮเปอร์ไวเซอร์ได้คืองานที่หยุด VPN ได้ แขกบริการที่มีเส้นทางไปยังเครือข่ายจัดการก็เปลี่ยนการตั้งค่าสวิตช์ได้ ปัญหาคือสิทธิ์ และรายการโปรเซสเป็นเพียงที่ที่มันปรากฏออกมา การตั้งชื่อบทบาทก่อนจะทำให้แต่ละสิทธิ์มีที่อยู่ของมัน
ภาพร่างด้านล่างเป็นจุดเริ่มต้นของการแยกนั้น ไม่ใช่คำสัญญาเรื่องความพร้อมใช้งานสูง จงถือว่ามันเป็นสมมติฐานที่ต้องพิสูจน์ ไม่ใช่การออกแบบที่เสร็จแล้ว
แยกสามบทบาท ไม่ใช่สามโปรเซส
แขกสามตัวบนโฮสต์เดียวให้ชุดสิทธิ์สามชุดและตำแหน่งเครือข่ายสามตำแหน่ง พวกมันไม่ได้ให้โดเมนความล้มเหลวสามโดเมน และการออกแบบควรพูดเรื่องนี้ให้ดัง
การแยกจะช่วยได้ก็ต่อเมื่อการถูกเจาะของแขกตัวหนึ่งไม่มอบสิทธิ์ให้ตัวอื่นโดยอัตโนมัติ และนั่นคือการตั้งค่าของไฮเปอร์ไวเซอร์ ไม่ใช่ธรรมเนียมการตั้งชื่อ การเรียก VM ว่าเกตเวย์ไม่ได้หยุดแขกตัวอื่นไม่ให้ไปถึงโฮสต์ จงอ่านการตั้งค่าของสวิตช์เสมือนแทนชื่อโฮสต์ แล้วยืนยันว่าแขกแต่ละตัวอยู่ตรงที่คุณคิด
host
├─ vpn-gw 10.60.10.2/24 public 51820/udp only
├─ services 10.60.0.10/24 no route to the management network
└─ ci-runner 10.60.20.2/24 outbound only, no host socket
จดโทโพโลยีลงไปแล้วตรวจสอบด้วยเครื่องมือที่เป็นเจ้าของมัน แขกที่โผล่บนบริดจ์ผิดเป็นข้อค้นพบ ไม่ใช่รายละเอียด จงแก้เครือข่ายก่อนที่จะเปลี่ยนการตั้งค่าบริการใด ๆ
ให้แขก VPN เปิดเฉพาะประตูที่มันเป็นเจ้าของ
ประกาศพอร์ตอุโมงค์ที่เราเตอร์และไม่มีอะไรอื่น พอร์ตจัดการของแขกควรอยู่บนเส้นทางจัดการ ไม่ใช่บนอินเทอร์เน็ต และอินเทอร์เฟซของไฮเปอร์ไวเซอร์เองก็อยู่ที่นั่นด้วย
เครือข่ายฝั่งส่วนตัวควรไปถึงบริการที่ผู้ใช้ระยะไกลต้องการและหยุดอยู่แค่นั้น การยืนยันตัวตนของแอปพลิเคชันยังเปิดอยู่ เพราะอุโมงค์คือการขนส่ง ไม่ใช่การเข้าสู่ระบบ จงทำให้ตารางเส้นทางของแขก VPN เล็กพอที่จะอธิบายได้ในประโยคเดียว ถ้าคุณอธิบายมันให้ง่ายขนาดนั้นไม่ได้ เส้นแบ่งก็พร่าไปแล้ว
virsh net-list --all
virsh net-dumpxml lab-private
sudo nft list ruleset | grep -n -E '51820|10.60'
อะไรก็ตามที่ฟังอยู่บนโฮสต์และไม่ได้จำเป็นต่อการจัดการไม่ควรฟังเลย นั่นรวมถึง API ของไฮเปอร์ไวเซอร์ ซึ่งปล่อยให้เปิดเผยบนอินเทอร์เฟซสาธารณะได้ง่าย
งานบิลด์ต้องการขอบเขตอีกแบบหนึ่ง
งาน CI รันคำสั่งที่รีโพสิทอรีควบคุม ดังนั้นความเชื่อใจของมันขึ้นกับว่าใครผลักโค้ดได้ ตัวรันแบบเชลล์รันคำสั่งเหล่านั้นในฐานะผู้ใช้ของตัวรันบนโฮสต์ ซึ่งเป็นขอบเขตที่กว้างที่สุดที่มี
ตัวรันแบบคอนเทนเนอร์แคบกว่า และคอนเทนเนอร์ที่ได้สิทธิ์พิเศษก็ไม่ใช่หนึ่งในพวกที่แคบ จงเก็บตัวรันไว้ในแขกของมันเองพร้อมขอบเขตเครือข่ายของมันเอง และให้สิทธิ์เฉพาะการเข้าถึงอาร์ติแฟกต์และการติดตั้งที่งานต้องการ เวิร์กเกอร์แบบใช้ครั้งเดียวลดสถานะที่เก็บไว้ แต่ไม่ลดการเข้าถึงหรือการเปิดเผยความลับ ทั้งสองอย่างยังต้องมีขีดจำกัดที่ชัดเจน
แขกบริการเป็นเจ้าของข้อมูล แผนสำรองข้อมูลของมันจึงเป็นแผนที่ต้องใช้งานได้ จงเก็บรีโพสิทอรี ไฟล์อัปโหลด และฐานข้อมูลไว้ในตารางเวลาเดียวกัน จงทดสอบการกู้คืนแทนการอ่านสถานะงาน
วางแผนสำหรับความล้มเหลวที่ทั้งสามใช้ร่วมกัน
โฮสต์หนึ่งตัวคือโดเมนความล้มเหลวหนึ่งโดเมน การรีบูตจะพาอุโมงค์และบริการส่วนตัวทุกตัวหายไปในเวลาเดียวกัน และนั่นคือตอนที่เส้นทางเข้าไปข้างในสำคัญที่สุด
จงรักษาการเข้าถึงคอนโซลที่ไม่ขึ้นกับแขก VPN ไม่ว่าจะเป็นคอนโซลจริง อินเทอร์เฟซจัดการนอกแบนด์ หรือคอนโซลของผู้ให้บริการ สแนปช็อตที่เก็บไว้บนดิสก์เดียวกันไม่ใช่สำเนาที่เป็นอิสระ และแบ็กอัปที่รันอยู่ภายในแขกที่มันปกป้องก็ไม่ใช่เช่นกัน จากนั้นจงทดสอบการเริ่มแบบเย็นเป็นลำดับ ไม่ใช่เป็นรายการตรวจสอบ โฮสต์ เครือข่ายเสมือน เส้นทางอุโมงค์ และแอปพลิเคชันที่ตั้งชื่อไว้หนึ่งตัวภายใต้บัญชีธรรมดา
virsh list --all
systemctl is-active libvirtd
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://10.60.0.10/
ss -ltnp | grep -E ':51820|:443'
ลำดับการเริ่มโปรเซสไม่ได้พิสูจน์อะไรเกี่ยวกับเส้นทางและ DNS ดังนั้นจงทดสอบเส้นทาง ไม่ใช่สถานะของยูนิต เส้นทางคือสิ่งที่ผู้ใช้ระยะไกลต้องการจริง ๆ