หยุดสองบริการ Linux ที่แย่งกันเป็นเจ้าของ /etc/resolv.conf
ตรวจสอบว่าใครเป็นเจ้าของไฟล์ก่อนแก้ไข แฟล็กแบบแก้ไม่ได้เพียงซ่อนความขัดแย้งไว้ และการเชื่อมต่อใหม่หรือการต่ออายุ DHCP ก็ย้อนการซ่อม DNS ด้วยมือซ้ำแล้วซ้ำเล่า
DNS ยังคงย้อนกลับไปสถานะเดิม การเชื่อมต่อ VPN ใหม่ยกเลิกการแก้ไขของคุณ และในที่สุดก็มีคนในทีมเสนอให้ล็อกไฟล์ ลำดับนั้นเป็นอาการ ไม่ใช่วิธีแก้: สององค์ประกอบต่างเชื่อว่าตนเป็นเจ้าของ /etc/resolv.conf และตัวที่เขียนทีหลังเป็นฝ่ายชนะ การล็อกไฟล์ไม่ได้แก้ปัญหาความขัดแย้งเรื่องความเป็นเจ้าของ เพียงซ่อนไว้พร้อมกับทำให้องค์ประกอบที่คุณต้องการจริง ๆ เสียหาย ทำงานตรวจสอบสี่ข้อด้านล่างตามลำดับ และแก้ไขการจัดวางในระดับที่เป็นเจ้าของ ไม่ใช่ที่ตัวไฟล์
การตรวจสอบ 1: เป็นซิมลิงก์หรือไม่ และชี้ไปที่ใด
เริ่มจากตัวไฟล์เอง เพราะเส้นทางที่คุณแก้ไขอาจไม่ใช่ไฟล์เลยก็ได้ ซิมลิงก์ที่ชี้ไปยังไดเรกทอรีรันไทม์ของตัวแก้ไขชื่อมีพฤติกรรมต่างจากไฟล์ปกติที่สคริปต์ไคลเอนต์เขียนทับโดยสิ้นเชิง:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
ลิงก์ไปยังเส้นทาง stub ของ systemd-resolved หมายความว่าเนื้อหาของไฟล์ถูกสร้างขึ้น และการแก้ไขด้วยมือจะถูกเขียนทับในเหตุการณ์ถัดไป ไฟล์ปกติที่มีบรรทัด nameserver มักถูกเขียนโดยไคลเอนต์หรือฮุก DHCP ที่ทำงานเมื่อเชื่อมต่อ ทั้งสองอย่างถูกต้อง สิ่งสำคัญคือต้องรู้ว่าคุณมีแบบไหนก่อนจะเปลี่ยนแปลงอะไร
การตรวจสอบ 2: แดมอนตัวใดกำลังทำงาน
ค้นหาว่าอะไรทำงานอยู่จริง ไม่ใช่สิ่งที่ติดตั้งไว้ ในดิสทริบิวชันสมัยใหม่อาจมีตัวแก้ไขชื่อหลายตัว และตัวที่ถือพอร์ต 53 บนอินเทอร์เฟซ loopback คือตัวที่ตอบ:
systemctl status systemd-resolved --no-pager
resolvectl status
ss -lunp | grep ':53'
ผลลัพธ์สถานะระบุเซิร์ฟเวอร์ DNS ต่อลิงก์และโดเมนการกำหนดเส้นทาง ซึ่งเป็นแผนที่ที่คุณต้องใช้สำหรับ split DNS หากชื่อภายในต้องไปยังเซิร์ฟเวอร์ภายในและอย่างอื่นไปยังเซิร์ฟเวอร์สาธารณะ นโยบายนั้นอยู่ในโดเมนต่อลิงก์ และการทำให้แบนเป็นรายการ nameserver แบบคงที่ในไฟล์จะทำให้ความแตกต่างนั้นหายไปอย่างเงียบ ๆ
การกำหนดค่า NetworkManager เองเป็นตัวตัดสินว่าจะใช้แบ็กเอนด์ใด การตั้งค่า dns= ในไฟล์กำหนดค่าหลักเลือกได้ระหว่างตัวแก้ไขชื่อภายใน dnsmasq, systemd-resolved และ none และดิสทริบิวชันอาจเลือกให้คุณแล้ว อ่านการตั้งค่านั้นก่อนตัดสินใจว่า “การซ่อม DNS” หมายถึงอะไรบนโฮสต์นี้
การตรวจสอบ 3: ไคลเอนต์ VPN ได้รับอนุญาตให้เขียนอะไร
ความขัดแย้งมักอยู่ที่นี่ ไคลเอนต์ VPN ที่เขียนไฟล์ตัวแก้ไขชื่อทับโดยตรงจะต่อสู้กับบริการใดก็ตามที่ดูแลไฟล์เดียวกัน และผู้แพ้คือตัวที่ทำงานก่อน เวอร์ชัน OpenVPN ใหม่ ๆ สามารถส่งการตั้งค่า DNS ให้ systemd-resolved แทนการเขียนไฟล์ทับ ซึ่งเป็นพฤติกรรมร่วมมือที่คุณต้องการ สคริปต์เก่าและฮุกที่เขียนด้วยมือมักเรียกเครื่องมือช่วยที่ล้าสมัยหรือเพียงเขียนทับไฟล์
สถานการณ์ของ WireGuard คล้ายกันในด้านรูปร่าง: การกำหนดค่าอินเทอร์เฟซเองไม่ได้จัดการ DNS แต่เครื่องมือรอบ ๆ จัดการ ผ่านตัวช่วยตัวแก้ไขชื่อหรือการรวมกับ resolved หากติดตั้งตัวช่วยดังกล่าวสองตัว ทั้งคู่จะพยายามใช้โลกทัศน์ของตนเมื่อเชื่อมต่อ
อ่านฮุกขึ้นและลงของไคลเอนต์แทนการเดา ไม่กี่บรรทัดของ shell ใน /etc/openvpn/up.sh หรือไดเรกทอรีที่เทียบเท่าอธิบายพฤติกรรมที่ดูเหมือนสุ่ม และที่นั่นคือจุดที่คุณทำให้ไคลเอนต์ร่วมมือแทนที่จะแข่งขัน
การตรวจสอบ 4: แก้ไขที่เจ้าของ ไม่ใช่ที่ไฟล์
เมื่อรู้ว่าใครเป็นเจ้าของแล้ว ให้กำหนดค่า DNS ผ่านอินเทอร์เฟซที่เจ้าของนั้นรองรับ สำหรับ systemd-resolved นั่นหมายถึงการตั้งค่าต่อลิงก์และโดเมนการกำหนดเส้นทางแทนไฟล์คงที่ สำหรับ NetworkManager หมายถึงการตั้งค่า DNS ของโปรไฟล์การเชื่อมต่อและแบ็กเอนด์ที่เลือก สำหรับดิสทริบิวชันที่ใช้การรวม resolvconf หมายถึงการเขียนผ่านตัวช่วยนั้น
อย่าทำให้ไฟล์เป็นแบบแก้ไม่ได้ แอตทริบิวต์แบบแก้ไม่ได้จะหยุดการต่ออายุ DHCP ที่ถูกต้องและการอัปเดต VPN ไปพร้อมกับสิ่งที่คุณกำลังต่อสู้ด้วย และปล่อยระบบไว้ในสภาพที่การอัปเกรดแพ็กเกจหรือการเชื่อมต่อครั้งถัดไปก่อให้เกิดความล้มเหลวที่ไม่มีใครอธิบายได้จากคอนฟิกูเรชัน มันปกปิดความขัดแย้งเรื่องความเป็นเจ้าของ ซึ่งเป็นสิ่งที่คุณพยายามจะแก้ไข
ในกรณีที่สององค์ประกอบต้องอยู่ร่วมกันจริง ๆ ให้งานที่แตกต่างกัน ปล่อยให้นายจัดการเครือข่ายเป็นเจ้าของคอนฟิกูเรชันระดับอินเทอร์เฟซ ให้ไคลเอนต์ VPN สนับสนุน DNS และโดเมนต่อลิงก์ผ่านการรวมเดียวกัน และลบสคริปต์ที่สามที่เขียนไฟล์โดยตรง เอกสารของ systemd-resolved อธิบายโหมดที่รองรับและสิ่งที่แต่ละโหมดเปิดเผยใน /etc/resolv.conf เลือกโหมดที่ตรงกับปริมาณนโยบายที่คุณต้องเก็บรักษา หาก split DNS สำคัญ การจัดวางแบบ stub ที่มีโดเมนต่อลิงก์จะรักษาไว้ ขณะที่โหมดที่คัดลอกเซิร์ฟเวอร์ต้นทางลงในไฟล์จะทำให้แบนอย่างเงียบ ๆ
ตรวจสอบหลังการเชื่อมต่อใหม่ ไม่ใช่หลังการแก้ไข
ไฟล์ที่ดูถูกต้องทันทีหลังการเปลี่ยนแปลงของคุณไม่ได้พิสูจน์อะไร เพราะเหตุการณ์ถัดไปยังไม่เกิดขึ้น กระตุ้นลำดับที่เคยทำให้มันเสีย: ลดอุโมงค์ลงแล้วยกขึ้นใหม่ ต่ออายุสัญญาเช่า DHCP หรือสลับอินเทอร์เฟซ แล้วอ่านค่าเดิมอีกครั้ง
resolvectl query build.corp.example
resolvectl query example.com
resolvectl status | head -40
จากนั้นยืนยันความแตกต่างที่สำคัญ: ชื่อภายในแก้ได้ผ่านเซิร์ฟเวอร์ภายใน ขณะที่ชื่อสาธารณะยังใช้งานได้ คอนฟิกูเรชันที่ส่งทุกอย่างไปยังเซิร์ฟเวอร์ภายในดูดีจนกว่าจะมีคนพยายามเข้าถึงอินเทอร์เน็ตผ่านอุโมงค์ และคอนฟิกูเรชันที่ส่งทุกอย่างไปยังเซิร์ฟเวอร์สาธารณะจะรั่วชื่อภายใน
บันทึกเจ้าของ แบ็กเอนด์ และโหมดซิมลิงก์ในบันทึกการปรับใช้ ย่อหน้าเดียวนั้นเปลี่ยนการอัปเกรดแพ็กเกจในอนาคตจากเหตุการณ์เป็นรายการตรวจทาน และป้องกันไม่ให้คนถัดไปค้นพบความขัดแย้งเดิมด้วยคำสั่ง chattr