Plik / etc / hosts odwołuje się do innego pliku konfiguracyjnego

38

Jak sprawić, by /etc/hostsplik odwoływał się do innego pliku konfiguracyjnego dla jego listy hostów?

Przykład /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

Jak dodać łącze / odniesienie do /etc/hostspliku, aby plik ConfigFile.txt został załadowany?

Pies je psa
źródło

Odpowiedzi:

40

Nie możesz Format dla /etc/hostsjest dość prosty i nie obsługuje dołączania dodatkowych plików.

Zamiast tego możesz zastosować kilka metod:

  • Skonfiguruj serwer DNS (prawdopodobnie tylko lokalny). Niektóre z nich zapewniają dużą elastyczność i zdecydowanie możesz rozłożyć pliki hosta na wiele plików, a nawet na komputery. Inne (takie jak dnsmasq) oferują mniejszą (ale wciąż wystarczającą) elastyczność, ale są łatwe do skonfigurowania. Jeśli próbujesz dołączyć tę samą listę hostów na wielu komputerach, DNS jest prawdopodobnie właściwą odpowiedzią.

  • Skonfiguruj inną usługę nazw (NIS, LDAP itp.). Sprawdź w dokumentacji glibc NSS, czy jest obsługiwana. Osobiście uważam, że powinieneś używać DNS w większości przypadków.

  • Stwórz sobie /etc/hosts.dkatalog lub podobny i napisz kilka skryptów, aby połączyć je wszystkie razem (najbardziej trywialne: cat /etc/hosts.d/*.conf > /etc/hostschociaż prawdopodobnie będziesz chciał trochę lepiej np. Przesłonić domyślne sortowanie według bieżących ustawień regionalnych), i uruchom ten skrypt podczas rozruchu, lub z crona lub ręcznie przy każdej aktualizacji plików.

Osobiście, zarówno w domu, jak i w pracy, aby nazwy komputerów były rozwiązywalne z każdego urządzenia, uruchamiam BIND 9. Nauka wymaga jednak kilku godzin.

derobert
źródło
Dzięki! Zastanawiałem się, dlaczego każda próba kończyła się niepowodzeniem. Byłoby o wiele łatwiej, gdyby było to możliwe, ale
użyję
8
@DogEatDog Polecam uruchomienie lokalnego serwera DNS. Dnsmasq jest bardzo łatwy w konfiguracji; w przyjaznych dla użytkownika dystrybucjach instalujesz pakiet i to po prostu działa.
Gilles 'SO - przestań być zły'
@Gilles ma rację - dnsmasq prawdopodobnie robi dokładnie to, co chcesz w sieci domowej. Pozwala przypisywać statyczne adresy IP do wszystkich zasobów sieci LAN według adresu MAC, nadawać im nazwy hostów i rozpatrywać żądania - wszystko to jednocześnie pozwalając nieznanym hostom przejść do nadrzędnego serwera DNS.
moodboom 11.11.16
@moodboom & Gilles Dziękujemy za sugestię, zauważyłem to w odpowiedzi. Nie jestem pewien, czy korzystałem z dnsmasq w 2013 roku, ale na pewno teraz.
derobert
Rozszerzenia glob są sortowane (przynajmniej według Bash LC_COLLATE), więc zastrzeżenie w twojej odpowiedzi nie ma zastosowania.
l0b0
2

Nie jest to możliwe, ponieważ format jest zwykle głęboko zakodowany w libc platform. Jednak jest to sobie wyobrazić, że OS dodaje tej funkcji, co czyni go non rozwiązanie cross-platform.

Alternatywnie możesz automatycznie zaktualizować określony blok w pliku hosts. Jest to szczególnie przydatne, jeśli masz skrypt, który dynamicznie wyświetla wpisy hosta dla określonego projektu (prawdopodobnie ze zmieniającymi się adresami IP).

Oto przykład: chcesz utworzyć hosty ze stanu Terraform za pośrednictwem terraform-inventory.

Odpowiednie wyniki inwentaryzacji (na przykład mapowanie znacznika EC2 „Nazwa” na grupy dokładnie jednego hosta):

$ 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")'

Wyjście skryptu:

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

I wiersz polecenia, aby zaktualizować zaznaczony blok w /etc/hostswyniku działania skryptu :

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

Wyjaśnienie:

  • Pierwsza linia oczywiście tworzy kopię zapasową
  • Podpowłoka w nawiasach zawiera dwa sedwywołania, aby wydrukować wszystkie linie odpowiednio przed i po początku / końcu znacznika. W każdym przypadku wstawiamy znaczniki, umieszczając wynik skryptu między tymi wierszami. Nawet jeśli skrypt nie powiedzie się, nadal musimy otoczyć zawartość /etc/hosts(i kopię zapasową w katastrofalnym scenariuszu).
  • sudo tee /etc/hosts.new zapisuje potokową zawartość w nowym pliku
  • sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p' drukuje zaktualizowany blok dla wygody
  • sudo mv /etc/hosts.new /etc/hostsprzenosi nowy plik na miejsce. Należy to zrobić w osobnym kroku, ponieważ jeśli w buforze potoku zabraknie miejsca, tee /etc/hostszacznie się zapisywać plik, gdy istniejąca zawartość jest nadal odczytywana.
AndiDog
źródło
1

Mam podobny wymóg płynnej pracy z różnych lokalizacji z dynamicznymi adresami IP, zwłaszcza, że ​​korzystam z maszyn wirtualnych. Moje proste rozwiązanie tego jest następujące:

  1. Utwórz skrypt, aby zaktualizować wpisy hosta dla każdej jednostki. Na przykład, jeśli mam hosta o nazwie „myhost.net” z subdomenami „app.myhost.net”, wywołałbym ten skrypt i podałby adres IP, który zostanie zapisany dla każdej domeny i zapisany w pliku hosta o nazwie 'mój gospodarz'. Ten sam skrypt ma flagę do usunięcia lub aktualizacji jednego pliku hosta.

  2. Utwórz kolejny skrypt, aby scalić te pliki w / etc / hosts. Ten skrypt znajdzie wszystkie utworzone pliki hosta i scali je w pojedynczy plik hosts w / etc / hosts.

To działało dla mnie idealnie. Pracuję zdalnie i czasami potrzebuję przemieszczać się między lokalizacjami z jakiegokolwiek powodu i byłbym obciążony potrzebą edytowania tego pliku tak wiele razy. Zamiast tego po prostu uruchamiam JEDEN skrypt. Tak, jeden skrypt. Pierwszy skrypt automatycznie uruchamia drugi, aby wykonać automatyczne scalanie.

DesmondCampbell
źródło