Le fichier / etc / hosts fait référence à un autre fichier de configuration

38

Comment puis-je obtenir que le /etc/hostsfichier fasse référence à un autre fichier de configuration pour sa liste d'hôtes?

Exemple /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

Comment puis-je ajouter un lien / une référence dans un /etc/hostsfichier tel que ConfigFile.txt soit chargé?

Les chiens mangent les chiens
la source

Réponses:

40

Tu ne peux pas. Le format de /etc/hostsest assez simple et ne prend pas en charge l’inclusion de fichiers supplémentaires.

Il existe plusieurs approches que vous pouvez utiliser à la place:

  • Configurez un serveur DNS (éventuellement local uniquement). Certains d'entre eux offrent beaucoup de flexibilité et vous pouvez certainement répartir vos fichiers hôtes sur plusieurs fichiers, voire sur des machines. D’autres (comme Dnsmasq) offrent une flexibilité moindre (mais suffisante), mais sont faciles à configurer. Si vous essayez d'inclure la même liste d'hôtes sur plusieurs machines, alors DNS est probablement la bonne réponse.

  • Configurez un autre service de noms (NIS, LDAP, etc.). Recherchez dans la documentation NSS glibc ce qui est pris en charge. Personnellement, je pense que vous devriez utiliser le DNS dans la plupart des cas.

  • Créez-vous un /etc/hosts.drépertoire ou similaire, et écrivez quelques scripts pour les concaténer (le plus trivial:, cat /etc/hosts.d/*.conf > /etc/hostsbien que vous souhaitiez probablement un peu mieux, par exemple, remplacer le tri par défaut par les paramètres régionaux actuels) et exécuter ce script au démarrage, ou cron, ou manuellement chaque fois que vous mettez à jour les fichiers.

Personnellement, à la maison comme au travail, pour pouvoir résoudre les noms d’ordinateur à partir de tous les appareils, je lance BIND 9. Cela prend quelques heures à apprendre, cependant.

derobert
la source
Merci! Je me demandais pourquoi chaque tentative échouait. Ce serait tellement plus facile si c'était possible, mais j'utiliserai le
fichier
8
@DogEatDog Je recommande d'exécuter un serveur DNS local. Dnsmasq est très facile à configurer. sur les distributions conviviales, vous installez le paquet et cela fonctionne.
Gilles 'SO- arrête d'être méchant'
@Gilles a le droit: Dnsmasq fait probablement ce que vous voulez sur un réseau domestique. Il vous permet d'attribuer des adresses IP statiques à toutes vos ressources LAN par adresse MAC, de leur attribuer des noms d'hôte et de résoudre leurs demandes, tout en laissant les hôtes inconnus passer au travers d'un serveur DNS en amont.
moodboom
@moodboom & Gilles Merci d'avoir suggéré cela, je l'ai noté dans la réponse. Je ne sais pas si j'utilisais dnsmasq en 2013, mais je le suis certainement maintenant.
derobert
Les développements globaux sont triés (au moins dans Bash, selon LC_COLLATE), de sorte que la mise en garde dans votre réponse ne s'applique pas.
l0b0
2

Ce n'est pas possible, car le format est généralement profondément codé dans la libc des plateformes. Cependant, il est imaginable qu'un système d'exploitation ajoute cette fonctionnalité, ce qui en fait une solution non multiplateforme.

Vous pouvez également mettre à jour automatiquement un certain bloc dans votre fichier hosts. Ceci est particulièrement utile si vous avez un script qui génère dynamiquement des entrées d’hôte pour un projet donné (ou peut-être avec des adresses IP changeantes).

Voici un exemple: vous voulez créer des hôtes à partir de l’état Terraform via terraform-inventory.

Résultats d'inventaire pertinents (par exemple, mappage d'une balise "Nom" EC2 sur des groupes comprenant exactement un hôte chacun):

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

Sortie du script:

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

Et la ligne de commande pour mettre à jour un bloc marqué /etc/hostsavec la sortie du script :

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

Explication:

  • La première ligne crée évidemment une sauvegarde
  • Le sous-shell entre parenthèses a deux sedappels pour imprimer toutes les lignes avant et après le début / la fin du marqueur, respectivement. Nous insérons les marqueurs dans tous les cas, en plaçant la sortie du script entre ces lignes. Même si le script échoue, nous devons toujours entourer le contenu de /etc/hosts(et la sauvegarde dans un scénario catastrophique).
  • sudo tee /etc/hosts.new écrit le contenu diffusé dans un nouveau fichier
  • sed -n '/^# MYMARKER BEGIN/,/^# MYMARKER END/p' imprime le bloc mis à jour pour plus de commodité
  • sudo mv /etc/hosts.new /etc/hostsdéplace le nouveau fichier en place. Cela doit être effectué dans une étape distincte, car si le tampon de canal manque d'espace, tee /etc/hostsl'écriture du fichier commence alors que le contenu existant est encore en cours de lecture.
AndiDog
la source
1

J'ai eu le même besoin de travailler de manière transparente depuis différents emplacements avec des adresses IP dynamiques, en particulier depuis que j'utilise des machines virtuelles. Ma solution simple à ceci est la suivante:

  1. Créez un script pour mettre à jour les entrées d'hôte pour chaque entité. Par exemple, si j'ai un hôte appelé "myhost.net", avec "app.myhost.net" des sous-domaines, j'appellerai ce script et fournirai une adresse IP qui sera écrite pour chaque domaine et enregistrée dans un fichier hôte appelé 'mon hôte' Le même script a un drapeau pour supprimer ou mettre à jour un seul fichier hôte.

  2. Créez un autre script pour fusionner ces fichiers dans / etc / hosts. Ce script trouvera tous les fichiers hôtes que vous avez créés et les fusionnera en un seul fichier hôte dans / etc / hosts.

Cela a fonctionné pour moi parfaitement. Je travaille à distance et ai parfois besoin de changer de lieu pour une raison ou une autre et je serais surchargé par la demande de modifier ce fichier autant de fois. Au lieu de cela, je viens d'exécuter UN script. Oui, un script. Le premier script exécute automatiquement l'autre pour effectuer la fusion automatiquement.

DesmondCampbell
la source