如何从DHCP服务器获取主机名


Answers:


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

eth0wlan0从中要获取主机名的接口的名称替换。在大多数情况下eth0wlan0应保持不变。

确保可读性...

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

就这样。在下一个dhcp响应中,您的主机名将自动更新。


该脚本实际上使用DNS查询(使用host命令)提取与分配的IP地址关联的主机名。DHCP服务器实际上可以显式设置主机名选项(选项12),该选项可能与您从IP上的DNS查询获得的主机名不同(如果DNS上不存在IP的PTR记录,则这也可能会失败。 )
Ale


3

d_inevitable的答案几乎解决了我的问题,但并没有完全解决。问题是尽管:

  1. DHCP服务器正在发送主机名(通过添加

    option host name 'client1' 
    

    在dhcpd.conf中),而我实际上是通过使用wirehark捕获并分析DHCP产品的内容来进行验证的

  2. DHCP客户端期望DHCP服务器提供主机名(通过添加

    request host-name 
    

    在dhclient.conf中)

客户端没有获得新的主机名(通过键入即可轻松验证

hostname

在终端中并获得旧的主机名,如果我已删除内容/文件,则没有主机名)。结果,由d_inevitable提出的解决方案只是复制一个空字符串。

为了解决这个问题,我应用了一个粗糙的解决方案,除非您像我以前那样迫切希望使它起作用,否则通常不应遵循该解决方案。

首先,使用编辑功能打开DHCP客户端控制脚本:

sudo vi /sbin/dhclient-script

在那里,您将必须找到功能

set_hostname()

只需使用搜索,它就会显示出来。现在,至少在我的计算机上,此函数具有三个if-then-else条件,它们相互封装在一起:

#设置主机名set_hostname(){本地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(){本地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

Oli的答案显然是错误的(“您没有从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的dhclient似乎不支持此功能!

但是,dhcpcd5开箱即用。停止dhclient,安装dhcpcd5,运行dhcpcd,续订租约,然后欺骗,将DHCP客户端上的主机名设置为从DHCP服务器发送的名称。没有dhclient-exit-hooks.d脚本,没有黑客rc.local,什么也没有。

作为结束语,我花了很多时间尝试使用ISC的dhclient使其工作。即使服务器发送了主机名,也绝对没有喜悦。

我对该问题的最初解决方案是编写一些可爱的代码rc.local以检测网络何时启动,并强制(以我为例)进行搜索/etc/hosts以获取主机名,然后hostname使用该主机名运行。它可以正常工作,但是在网络启动之前,您的主机名可能是错误的(第一次部署主机时,我将删除/etc/hostname,因此,主机名称要localhost等到/etc/init.d/hostname.sh start网络启动后我才能运行-因此,在首次获取新名称时,需要启动两次-一次获取您的主机名,一次在一切启动时使该名称可用...)。


1

您没有从DHCP服务器获取主机名。

您可以主机名发送到服务器,这可能会更改您分配的IP。您可以通过编辑网络管理器连接(该字段称为DHCP客户端ID)来更改发送的名称,也可以以root用户身份进行编辑/etc/dhcp/dhclient.conf。查找显示以下内容的行:

send host-name "<hostname>";

...然后更改<hostname>为您喜欢的任何东西。


默认情况下,Ubuntu将通过路由器获取DNS设置(如果它发送了它们),但是我怀疑您是在谈论本地DNS / mDNS,在这里您可以通过其主机名访问其他计算机。这在Ubuntu中称为Ahavi或Zeroconf,默认情况下已安装。

您应该能够通过以下方式访问计算机 <hostname>.local


我的网络上有dns和dhcp(Windows 2008)服务器。Ant会为每个IP分配主机名和dns名称,但是ubuntu不会更新其主机名和dns名称。我应该能够通过键入查看此分配的主机名,hostname并通过键入来查看域hostname -d。所以它的fqdn应该是hostname.domain
Oguz Bilgic '02

AFAIR如果客户端未加入Windows域,则Windows DHCP服务器将不会动态更新Windows DNS条目。我不确定,不过...取决于Windows DHCP / DNS配置
奇怪的原因2012年

默认情况下,12.04的这一行是“发送主机名= gethostname();” 然后您可以在命令行上输入“主机名”来查看该值。默认情况下,这对Windows网络不会有任何影响。按照原始问题。
2013年

尽管默认情况下安装了zeroconf,但它绝对不可靠。坦白地说,它工作时会感到惊讶,因为ping主机名或主机名.local很少会成功,即使几个月来我的网络没有任何变化。
塞林2015年

1
这不是真的。虽然您可以发送您的主机名到DHCP服务器send host-name "example.com";,以获得一个特定的IP地址,你可以也要求一个带request host-name;
德米特里·格里戈里耶夫


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,这应该会自动发生,因此您不必编写脚本。但是,如果要将主机名设置为FQDN,则需要将d_inevitable的脚本更改为

hostname=${new_host_name}.${new_domain_name}

同样,所有这些仅在您使用静态租约时才有效。


0

没有足够的声誉来发表评论,但是我想piggy带以前的答案,因为它几乎可以使用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")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.