ไฟล์ / etc / hosts อ้างถึงไฟล์กำหนดค่าอื่น


37

ฉันจะให้/etc/hostsไฟล์อ้างถึงไฟล์กำหนดค่าอื่นสำหรับรายการของโฮสต์ได้อย่างไร

ตัวอย่าง/etc/hosts:

 ## My Hosts
 127.0.0.1   localhost
 255.255.255.255 broadcasthost

 #Other Configurations
 <Link to /myPath/to/MyConfig/ConfigFile.txt>

 #Other Addresses
 3.3.3.3 MyAwesomeDomain.com
 4.4.4.4 SomeplaceIWantToGoTo.com

ConfigFile.txt

##My additional Hosts
1.1.1.1 SomeLocation.com
2.2.2.2 AnotherLocation.com

ฉันจะเพิ่มลิงค์ / การอ้างอิงไปยัง/etc/hostsไฟล์ที่จะโหลด ConfigFile.txt ได้อย่างไร

คำตอบ:


39

คุณทำไม่ได้ รูปแบบสำหรับ/etc/hostsค่อนข้างง่ายและไม่รองรับการรวมไฟล์เพิ่มเติม

มีวิธีการสองสามอย่างที่คุณสามารถใช้แทนได้:

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

  • ตั้งค่าบริการชื่ออื่น (NIS, LDAP, ฯลฯ ) ตรวจสอบ glibc NSS docs สำหรับสิ่งที่รองรับ โดยส่วนตัวฉันคิดว่าคุณควรใช้ DNS ในเกือบทุกกรณี

  • สร้าง/etc/hosts.dไดเรกทอรีของคุณเองหรือคล้าย ๆ กันและเขียนสคริปต์บางตัวเพื่อเชื่อมโยงมันเข้าด้วยกัน (เล็กน้อยที่สุด: cat /etc/hosts.d/*.conf > /etc/hostsถึงแม้ว่าคุณอาจต้องการให้ดีขึ้นเล็กน้อยเช่นแทนที่การเรียงลำดับเริ่มต้นตามตำแหน่งที่ตั้งปัจจุบัน) และเรียกใช้สคริปต์ตอนบู๊ตหรือ จาก cron หรือด้วยตนเองทุกครั้งที่คุณอัปเดตไฟล์

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


ขอบคุณ! ฉันสงสัยว่าทำไมความพยายามแต่ละครั้งจึงล้มเหลว มันจะง่ายมากถ้าเป็นไปได้ แต่ฉันจะใช้ /etc/hosts.d
DogEatDog

8
@DogEatDog ฉันแนะนำให้ใช้เซิร์ฟเวอร์ DNS ในเครื่อง Dnsmasq ติดตั้งง่ายมาก ในการแจกแจงที่ใช้งานง่ายคุณติดตั้งแพ็กเกจและใช้งานได้
Gilles 'หยุดความชั่วร้าย'

@Gilles พูดถูกต้อง - dnsmasq ทำในสิ่งที่คุณต้องการบนเครือข่ายในบ้าน ช่วยให้คุณกำหนด IP แบบคงที่ให้กับทรัพยากร LAN ทั้งหมดของคุณโดยที่อยู่ MAC มอบชื่อโฮสต์และแก้ไขคำขอให้พวกเขา - ทั้งหมดในขณะที่ปล่อยให้โฮสต์ที่ไม่รู้จักผ่านไปยังเซิร์ฟเวอร์ DNS ต้นทาง
moodboom

@moodboom & Gilles ขอบคุณสำหรับคำแนะนำที่ฉันได้บันทึกไว้ในคำตอบ ไม่แน่ใจว่าฉันใช้ dnsmasq ย้อนกลับไปในปี 2013 แต่ตอนนี้ฉันกำลังอยู่ในขณะนี้อย่างแน่นอน
Derobert

การขยาย Glob จะถูกจัดเรียง (อย่างน้อยใน Bash ตามLC_COLLATE) ดังนั้นข้อแม้ในคำตอบของคุณจะไม่ถูกนำมาใช้
l0b0

2

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

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

นี่คือตัวอย่าง: คุณต้องการสร้างโฮสต์จากรัฐ terraform terraform-inventoryผ่าน

ผลลัพธ์ของสินค้าคงคลังที่เกี่ยวข้อง (ตัวอย่างเช่นการจับคู่แท็ก "ชื่อ" EC2 กับกลุ่มของหนึ่งโฮสต์ที่แน่นอนแต่ละรายการ):

$ terraform-inventory --list | jq 'with_entries(select(.key | match("^name_")))'
{
  "name_myhost-a": [
    "10.101.118.131"
  ],
  "name_myhost-b": [
    "10.101.111.189"
  ]
}

print-updated-hosts-entries.sh

#!/bin/sh
exec terraform-inventory --list | \
    jq -r 'to_entries |
           map(select(.key | match("^name_"))) |
           map(.value[0] + " " + .key[5:]) |
           join("\n")'

เอาต์พุตสคริปต์:

./print-updated-hosts-entries.sh
10.101.118.131 myhost-a
10.101.111.189 myhost-b

และบรรทัดคำสั่งเพื่ออัพเดตบล็อกที่ทำเครื่องหมาย/etc/hostsด้วยเอาต์พุตสคริปต์ :

sudo cp /etc/hosts "/etc/hosts.bak.$(date +%Y%m%d%H%M%S)" && \
    (
        sed -n '1,/^# MYMARKER BEGIN/{/^# MYMARKER BEGIN/!p;}' /etc/hosts; \
        echo "# MYMARKER BEGIN"; \
        ./print-updated-hosts-entries.sh; \
        echo "# MYMARKER END"; \
        sed -n '/^# MYMARKER END/,${/^# MYMARKER END/!p;}' /etc/hosts; \
    ) | \
    sudo tee /etc/hosts.new | \
    sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p' && \
        sudo mv /etc/hosts.new /etc/hosts

คำอธิบาย:

  • บรรทัดแรกสร้างการสำรองข้อมูลอย่างชัดเจน
  • เชลล์ย่อยในวงเล็บมีการsedเรียกสองครั้งเพื่อพิมพ์บรรทัดทั้งหมดก่อนและหลังเครื่องหมายเริ่มต้น / สิ้นสุดตามลำดับ เราแทรกเครื่องหมายในกรณีใด ๆ ใส่เอาท์พุทสคริปต์ในระหว่างบรรทัดเหล่านั้น แม้ว่าสคริปต์จะล้มเหลว แต่เราก็ยังต้องมีเนื้อหาโดยรอบของ/etc/hosts(และการสำรองข้อมูลในสถานการณ์ภัยพิบัติ)
  • sudo tee /etc/hosts.new เขียนเนื้อหา piped ลงในไฟล์ใหม่
  • sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p' พิมพ์บล็อกที่อัพเดตเพื่อความสะดวก
  • sudo mv /etc/hosts.new /etc/hostsย้ายไฟล์ใหม่เข้าที่ สิ่งนี้จะต้องทำในขั้นตอนที่แยกต่างหากเพราะหากบัฟเฟอร์ของท่อหมดพื้นที่tee /etc/hostsจะเริ่มเขียนไฟล์ในขณะที่เนื้อหาที่มีอยู่ยังคงถูกอ่าน

1

ฉันมีข้อกำหนดที่คล้ายกันสำหรับฉันในการทำงานอย่างราบรื่นจากสถานที่ต่าง ๆ ด้วย IP แบบไดนามิกโดยเฉพาะเมื่อฉันใช้เครื่องเสมือน วิธีแก้ปัญหาง่าย ๆ ของฉันมีดังนี้:

  1. สร้างสคริปต์เพื่ออัปเดตรายการโฮสต์สำหรับแต่ละเอนทิตี เช่นถ้าฉันมีโฮสต์ชื่อ 'myhost.net' พร้อมด้วยโดเมนย่อย 'app.myhost.net' ฉันจะเรียกใช้สคริปต์นั้นและระบุที่อยู่ IP ที่จะเขียนสำหรับแต่ละโดเมนและบันทึกไว้ในไฟล์โฮสต์ที่เรียกว่า 'โฮสต์ของฉัน' สคริปต์เดียวกันมีค่าสถานะเพื่อลบหรืออัปเดตไฟล์โฮสต์เดียว

  2. สร้างสคริปต์อื่นเพื่อรวมไฟล์เหล่านั้นเข้ากับ / etc / hosts สคริปต์นี้จะค้นหาไฟล์โฮสต์ทั้งหมดที่คุณสร้างและรวมเข้ากับไฟล์โฮสต์เดียวที่ / etc / hosts

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

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