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

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

我希望 Ubuntu 从DHCP客户端。默认安装Ubuntu 11.10(Oneiric Ocelot)不会这么做。

同样的问题被问到,但尚未解决Ubuntu 论坛

答案1

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- 因此,当第一次获得新名称时,您需要启动两次 - 一次获取您的主机名,一次在一切启动时让该名称可用...)。

答案2

使用时请注意Ubuntu 18.04不再需要绑定脚本。如果localhost/etc/hostnameDHCP 中将安装的主机名设置为,则客户端将在启动时使用 DHCP 发出的名称(如果存在)自动设置主机名。运行时,hostnamectl它将列为localhost永久主机名,并将 DHCP 发出的任何内容列为临时主机名。

testaccount@dhcp-hostname:~$ hostnamectl
   Static hostname: localhost
Transient hostname: dhcp-hostname

答案3

有一种方法可以使用 dhcp hook 的小脚本来实现,如下所述这里

创建新文件:

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为您要从中获取主机名的接口的名称。在大多数情况下eth0wlan0应该保持不变。

确保它是可读的...

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

就这样。下次 dhcp 响应时,您的主机名将自动更新。

答案4

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

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

    option host name 'client1' 
    

    在 dhcpd.conf 中),我实际上通过使用 wireshark 捕获和分析 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() { 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 或应该可以按预期工作。如果你和我一样处于极度沮丧的状态,希望这能对你有所帮助。

相关内容