Как получить имя хоста с сервера DHCP

Ответы:

6

Есть способ сделать это с помощью небольшого скрипта для ловушки dhcp, как описано здесь .

Создайте новый файл:

sudoedit /etc/dhcp/dhclient-exit-hooks.d/hostname

и вставьте следующий код:

#!/bin/sh
# Filename:     /etc/dhcp/dhclient-exit-hooks.d/hostname
# Purpose:      Used by dhclient-script to set the hostname of the system
#               to match the DNS information for the host as provided by
#               DHCP.
#


# Do not update hostname for virtual machine IP assignments
if [ "$interface" != "eth0" ] && [ "$interface" != "wlan0" ]
then
    return
fi


if [ "$reason" != BOUND ] && [ "$reason" != RENEW ] \
   && [ "$reason" != REBIND ] && [ "$reason" != REBOOT ]
then
        return
fi

echo dhclient-exit-hooks.d/hostname: Dynamic IP address = $new_ip_address
hostname=$(host $new_ip_address | cut -d ' ' -f 5 | sed -r 's/((.*)[^\.])\.?/\1/g' )
echo $hostname > /etc/hostname
hostname $hostname
echo dhclient-exit-hooks.d/hostname: Dynamic Hostname = $hostname

Замените eth0и wlan0на имена интерфейсов, из которых вы хотите получить имя хоста. В большинстве случаев eth0и wlan0должно оставаться прежним.

Убедитесь, что это читабельно ...

chmod a+r /etc/dhcp/dhclient-exit-hooks.d/hostname

Это все. При следующем ответе dhcp ваше имя хоста будет обновлено автоматически.

d_inevitable
источник
этот сценарий фактически использует DNS-запрос (используя hostкоманду) для извлечения имени хоста, связанного с назначенным IP-адресом. Серверы DHCP могут на самом деле явно установить опцию имени хоста (опция 12), которая потенциально может отличаться от имени хоста, которое вы получаете из DNS-запроса на IP (это также может привести к сбою, если в DNS не существует записи PTR для IP-адреса). )
Ale
4

Вы можете получить ваше имя хоста от вашего DHCP-сервера - это часть спецификации DHCP.

https://tools.ietf.org/html/rfc1533#section-3.14

«Эта опция указывает имя клиента»

Дейв Моррис
источник
3
Как вы получаете сервер для его отправки?
Олат
3

Ответ d_inevitable почти решил мою проблему, но не полностью. Проблема заключалась в том, что хотя:

  1. DHCP-сервер отправлял имя хоста (добавив

    option host name 'client1' 
    

    в dhcpd.conf), и я фактически проверил это, захватив и проанализировав содержимое предложения DHCP с помощью wireshark

  2. DHCP-клиент ожидал имя хоста от DHCP-сервера (добавив

    request host-name 
    

    в dhclient.conf)

Клиент не получил новое имя хоста (легко проверить, набрав

hostname

в терминале и получить старое имя хоста, или нет имени хоста, если я удалил содержимое / файл). В результате предложенное решение d_inevitable только копировало пустую строку.

Чтобы решить эту проблему, я применил грубое решение, за которым обычно не следует следовать, если только вы не отчаянно пытаетесь заставить его работать, как я.

Сначала откройте с возможностью редактирования сценарий управления клиентом DHCP:

sudo vi /sbin/dhclient-script

Там вам нужно будет найти функцию

set_hostname()

Просто используйте поиск, и он должен прийти прямо вверх. Теперь, по крайней мере на моем компьютере, эта функция имеет три условия if-then-else, инкапсулированных друг в друга:

# установить имя хоста set_hostname () {local current_hostname

if [ -n "$new_host_name" ]; then
    current_hostname=$(hostname)

    # current host name is empty, '(none)' or 'localhost' or differs from new one from DHCP
    if [ -z "$current_hostname" ] ||
       [ "$current_hostname" = '(none)' ] ||
       [ "$current_hostname" = 'localhost' ] ||
       [ "$current_hostname" = "$old_host_name" ]; then
       if [ "$new_host_name" != "$old_host_name" ]; then
           hostname "$new_host_name"
       fi
    fi
fi }

Теперь вам нужно принудительно назначить новое имя хоста вашему хосту, несмотря ни на что. Поэтому вы хотите закомментировать два инкапсулированных if-then-else. Результат должен выглядеть примерно так:

# установить имя хоста set_hostname () {local current_hostname

if [ -n "$new_host_name" ]; then
    current_hostname=$(hostname)

    # current host name is empty, '(none)' or 'localhost' or differs from new one from DHCP
    #if [ -z "$current_hostname" ] ||
    #   [ "$current_hostname" = '(none)' ] ||
    #   [ "$current_hostname" = 'localhost' ] ||
    #   [ "$current_hostname" = "$old_host_name" ]; then
    #   if [ "$new_host_name" != "$old_host_name" ]; then
           hostname "$new_host_name"
    #   fi
    #fi
fi }

Теперь d_inevitable или это должно работать как ожидалось. Надеюсь, это поможет, если вы в таком же отчаянном отчаянии, как и я.

Джордж
источник
3

Ответ Оли явно ложный («Вы не получаете свое имя хоста от сервера DHCP»), о чем свидетельствуют другие ответы здесь, а также мой недавний опыт работы с системой RHEL7. Указанная система получила имя хоста от сервера DHCP.

И действительно, в файлах конфигурации DHCP есть вещи, которые должны это сделать. Например:

host host4 {   # verified                                                                                                                                                                                                                   
  hardware ethernet  41:88:22:11:33:22;
  fixed-address 192.168.0.4;                                                                                                                                                                                 
  option host-name "host4";
}

Предполагается, что хост говорит, что его зовут host4.

Оказывается, клиент ISC НЕ ВИДЕТСЯ, ЧТОБЫ ПОДДЕРЖАТЬ ЭТО!

Тем не менее, dhcpcd5 делает, из коробки. Остановите dhclient, установите dhcpcd5, запустите dhcpcd, возобновите аренду и poof, в качестве имени вашего хоста на вашем DHCP-клиенте будет указано имя, отправленное с DHCP-сервера. Нет dhclient-exit-hooks.dсценариев, нет взломов rc.local, ничего.

В заключение, я потратил много времени, пытаясь заставить это работать, используя dhclient ISC. Абсолютно не радость, даже когда сервер отправляет имя хоста.

Моим первоначальным решением проблемы было написание какого-то симпатичного кода, rc.localчтобы определить, когда возникла сеть, и принудительно (в моем случае) /etc/hostsвыполнить поиск, чтобы получить имя хоста, а затем запустить hostnameс этим именем хоста. Это работает, но до тех пор, пока не появится сеть, ваше имя хоста, вероятно, будет неправильным (при первом развертывании хоста я удаляю его /etc/hostname, поэтому имя хоста сохраняется localhostдо тех пор, пока я не смогу работать, как /etc/init.d/hostname.sh startтолько сеть начнет работать - поэтому при первом получении нового имени вам нужно загрузиться дважды - один раз, чтобы получить ваше имя хоста, и один раз, чтобы это имя было доступно, когда все запускается ...).

RustyCar
источник
1

Вы не получаете свое имя хоста от сервера DHCP.

Вы можете отправить свое имя хоста на сервер, который может изменить назначенный вам IP-адрес. Вы можете изменить то, какое имя отправляется, отредактировав свое соединение с Network Manager (поле называется DHCP Client ID), или вы можете редактировать (как root) /etc/dhcp/dhclient.conf. Ищите строку, которая говорит:

send host-name "<hostname>";

... и смени <hostname>на что хочешь.


По умолчанию Ubuntu получает настройки DNS от маршрутизатора (если он их отправляет), но я подозреваю, что вы говорите о локальном DNS / mDNS, где вы можете получить доступ к другим компьютерам по их имени хоста. Это называется Ahavi или Zeroconf в Ubuntu и устанавливается по умолчанию.

Вы должны иметь возможность получить доступ к вашему компьютеру <hostname>.local

Оли
источник
У меня есть DNS и DNS-сервер (Windows 2008) в моей сети. Ant он назначает имя хоста и имя DNS каждому ip, но Ubuntu не обновляет его имя хоста и имя DNS. Я должен быть в состоянии увидеть это назначенное имя хоста, набрав hostnameи домен, набрав hostname -d. так что это fqdn должно быть hostname.domain
Oguz Bilgic
AFAIR, если клиент не присоединен к домену Windows, сервер DHCP Windows не будет динамически обновлять записи DNS Windows. Я не совсем уверен, хотя ... зависит от конфигурации Windows DHCP / DNS
oddfellow
По умолчанию в 12.04 есть строка «send host-name = gethostname ();» и вы можете увидеть это значение, набрав «hostname» в командной строке. По умолчанию это не окажет никакого влияния на сеть Windows. Согласно оригинальному вопросу.
Móż
Хотя zeroconf установлен по умолчанию, он ужасно ненадежен. Я откровенно удивлен, когда это работает, так как pinging hostname или hostname.local редко приводит к успеху, хотя в моей сети за месяцы ничего не изменилось.
Cerin
1
Это не совсем так. Хотя вы можете отправить свое имя хоста на DHCP-сервер с send host-name "example.com";целью получения определенного IP-адреса, вы также можете запросить его с помощью request host-name;.
Дмитрий Григорьев
1

Если найдено, это может быть ошибка скриптов dhcpclient. http://blog.schlomo.schapiro.org/2013/11/setting-hostname-from-dhcp-in-debian.html

Попробуй очистить $ old_host_name при продлении ip

echo unset old_host_name> /etc/dhcp/dhclient-enter-hooks.d/unset_old_hostname

Также статический файл / etc / hostname имеет приоритет перед dhcp-ответом, поэтому оставьте его пустым

> / etc / hostname

Протестировано на Ubuntu 14.04 и сервере dnsmasq.

Адам
источник
1

Обратите внимание, что при использовании Ubuntu 18.04 сценарии встраивания больше не нужны. Если имя хоста установки установлено localhostв /etc/hostnameDHCP-клиенте, при запуске будет автоматически задано имя хоста, используя имя, выданное DHCP, если оно есть. При запуске hostnamectlон будет указан localhostкак постоянное имя хоста, а все, что DHCP выдает как временное имя хоста.

testaccount@dhcp-hostname:~$ hostnamectl
   Static hostname: localhost
Transient hostname: dhcp-hostname
Джастин скотт
источник
0

Ответ зависит от того, используете ли вы статическую аренду на DHCP-сервере. Если да, то нет необходимости получать имя хоста из DNS. Вы можете изменить эту строку в решении d_inevitable

hostname=$(host $new_ip_address | cut -d ' ' -f 5)

в

hostname=${new_host_name}

Но это должно происходить автоматически, если ваше имя хоста изначально установлено в localhost.localdomain, поэтому вам не нужно писать скрипт. Однако, если вы хотите установить полное имя хоста в полное доменное имя, вам нужно изменить скрипт d_inevitable на

hostname=${new_host_name}.${new_domain_name}

Опять же, все это работает, только если вы используете статический лизинг.

user248850
источник
0

У меня недостаточно репутации, чтобы комментировать, но я бы хотел добавить свой ответ к предыдущему ответу, так как он почти решил проблему для меня, используя крючок dhclient.

Я обнаружил, что с использованием стандартного ISC DHCP-сервера вышеупомянутый хук выводит имя хоста с символом «.» символ точки в конце имени хоста по какой-то причине.

Итак, в предыдущем ответе вам может понадобиться «вырезать» посторонний период с помощью sed:

hostname=$(host $new_ip_address | cut -d ' ' -f 5)

Станет:

hostname=$(host $new_ip_address | cut -d ' ' -f 5 | sed -e "s/\.$//g")
Майкл Р. Хайнс
источник