/ etc / hosts файл посилається на інший файл конфігурації


38

Як я можу змусити /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 буде завантажений?

Відповіді:


40

Ви не можете. Формат /etc/hostsфайлу досить простий і не підтримує додаткові файли.

Є кілька підходів, які ви можете використати замість цього:

  • Налаштуйте (можливо, лише локальний) DNS-сервер. Деякі з них дають велику гнучкість, і ви, безумовно, можете розповсюджувати свої хост-файли на декілька файлів або навіть на машинах. Інші (наприклад, dnsmasq) пропонують меншу (але все ж достатню) гнучкість, але їх легко налаштувати. Якщо ви намагаєтеся включити той самий список хостів на купу машин, то DNS, ймовірно, є правильною відповіддю.

  • Налаштуйте якусь іншу службу імен (NIS, LDAP тощо). Перевірте документи glibc NSS щодо того, що підтримується. Особисто я думаю, що ви повинні використовувати DNS у більшості випадків.

  • Створіть собі /etc/hosts.dкаталог або подібне, і напишіть кілька сценаріїв, щоб об'єднати їх усі разом (найбільш тривіально: cat /etc/hosts.d/*.conf > /etc/hostsхоча ви, мабуть, захочете трохи краще, наприклад, переозначити сортування за замовчуванням за поточною локаллю) та запустіть цей сценарій під час завантаження, або з cron або вручну, коли ви оновлюєте файли.

Особисто, як вдома, так і на роботі, щоб імена машин можна було вирішити з кожного пристрою, я запускаю BIND 9. Це, однак, потребує кількох годин, щоб навчитися.


Спасибі! Мені було цікаво, чому кожна спроба провалювалася. Це було б набагато простіше, якби це було можливо, але я буду використовувати /etc/hosts.d
DogEatDog

8
@DogEatDog Я рекомендую запустити локальний DNS-сервер. Dnsmasq дуже просто налаштувати; на зручних дистрибутивах ви встановлюєте пакет і він просто працює.
Жил "ТАК - перестань бути злим"

@Gilles має правильно - dnsmasq, ймовірно, робить саме те, що ви хочете в домашній мережі. Це дозволяє вам призначати статичні IP-адреси всім вашим локальним ресурсам за MAC-адресою, надавати їм імена хостів та вирішувати запити на них - все, нехай невідомі хости проходять до верхнього сервера DNS.
moodboom

@moodboom & Gilles Дякую, що ви запропонували це, я зазначив це у відповіді. Не впевнений, чи використовував я dnsmasq ще в 2013 році, але я, безумовно, зараз.
дероберт

Глобальні розширення відсортовані (принаймні, у Баші, відповідно до 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-update-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 записує контентний вміст у новий файл
  • 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.

Це спрацювало для мене чудово. Я працюю віддалено, і іноді мені потрібно переходити між місцями з будь-якої причини, і мене б обтяжувала вимога редагувати цей файл стільки разів. Натомість я просто запускаю ОДИН сценарій. Так, один сценарій. Перший скрипт автоматично запускається другий, щоб зробити злиття автоматично.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.