Файл / 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 был загружен?

DogEatDog
источник

Ответы:

40

Ты не можешь Формат для /etc/hostsдовольно прост, и не поддерживает включение дополнительных файлов.

Есть пара подходов, которые вы могли бы использовать вместо:

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

  • Настройте другую службу имен (NIS, LDAP и т. Д.). Проверьте glibc NSS docs для того, что поддерживается. Лично я думаю, что вы должны использовать DNS в большинстве случаев.

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

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

derobert
источник
Благодарность! Мне было интересно, почему каждая попытка не удалась. Было бы намного проще, если бы это было возможно, но я буду использовать /etc/hosts.d
DogEatDog
8
@DogEatDog Я рекомендую запустить локальный DNS-сервер. Dnsmasq очень прост в настройке; в удобных для пользователя дистрибутивах вы устанавливаете пакет, и он просто работает.
Жиль "ТАК - перестань быть злым"
@ Жиль правильно понял - dnsmasq, скорее всего, делает именно то, что вы хотите в домашней сети. Он позволяет назначать статические IP-адреса всем ресурсам локальной сети по MAC-адресу, присваивать им имена хостов и разрешать их запросы - и все это позволяет неизвестным хостам проходить через вышестоящий DNS-сервер.
moodboom
@moodboom & Gilles Спасибо, что предложили, я отметил это в ответе. Не уверен, что я использовал dnsmasq еще в 2013 году, но я, конечно, сейчас.
Дероберт
Расширения глобуса сортируются (по крайней мере, в Bash, согласно LC_COLLATE), поэтому предостережение в вашем ответе не применяется.
мая
2

Это невозможно, так как формат обычно глубоко закодирован в libc платформ. Однако это можно себе представить , что ОС добавляет эту функцию, что делает его не кроссплатформенное решение.

Кроме того, вы можете автоматически обновить определенный блок в вашем файле hosts. Это особенно полезно, если у вас есть скрипт, который динамически выводит записи хоста для определенного проекта или около того (возможно, с изменением 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 записывает содержимое канала в новый файл
  • sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p' печатает обновленный блок для удобства
  • sudo mv /etc/hosts.new /etc/hostsперемещает новый файл на место Это должно быть сделано на отдельном шаге, потому что если в буфере конвейера не хватит места, tee /etc/hostsначнется запись файла, пока существующий контент еще читается.
AndiDog
источник
1

У меня было аналогичное требование для меня, чтобы работать без проблем из разных мест с динамическими IP-адресами, особенно с тех пор, как я использую виртуальные машины. Мое простое решение этого заключается в следующем:

  1. Создайте скрипт для обновления записей хоста для каждой сущности. Например, если у меня есть хост с именем «myhost.net», с поддоменами «app.myhost.net», я бы вызвал этот скрипт и предоставил IP-адрес, который будет записан для каждого домена и сохранен в файле хоста с именем «мой хозяин». Этот же скрипт имеет флаг для удаления или обновления одного файла хоста.

  2. Создайте другой скрипт для объединения этих файлов в / etc / hosts. Этот скрипт найдет все файлы хостов, которые вы создали, и объединит их в один файл хостов в / etc / hosts.

Это сработало для меня отлично. Я работаю удаленно, и иногда по какой-либо причине мне приходится перемещаться между локациями, и меня обременяет требование редактировать этот файл столько раз. Вместо этого я просто запускаю ОДИН скрипт. Да, один сценарий. Первый скрипт автоматически запускает другой, чтобы выполнить объединение автоматически.

DesmondCampbell
источник