(CentOS7)設定していないホスト名がつく

投稿者: | 2019年4月8日
みなさんこんにちは。ヒロウミです。

最近、検証用のサーバを立てていて不思議に思っていたことを調査してみようと思います。
内容としては、「ホスト名を設定した覚えがないのに、サーバにホスト名が付いている」という状況についてです。「は?何言ってんの?」という方もいらっしゃるでしょうが、この状況に出くわした時は「なんだこれ?」状態だったので一応まとめておきます。

事象

* 新規にインストールしたサーバに設定した覚えのないホスト名が自動で付与されている
* /etc/hostnameには該当のホスト名は記述されていない(localhost.localdomainが記述されている)
* hostnamectlコマンドで明示的に設定していない(そもそもインストールが完了し、再起動した直後の状態)
* kickstartなどの自動インストール設定でホスト名の設定は行なっていない

環境

* ローカルネットワークの閉じた自宅検証環境
* CentOS7 on KVM

結論から言えば、「サーバに付与したIPに対して、サーバ起動時にDNSの逆引きが行われており、逆引きに成功したホスト名が設定されていた」という内容でした。
この挙動のことを全く知らなかったので「え、/etc/hostname に設定がないのになんでホスト名ついてんの?」とちょっと困りました。
「こんなの常識だろ」という声も聞こえてきそうですが、自分はちょっとハマったので調査の経緯をまとめておこうと思います。

まず、インストール直後のサーバに /etc/hostname が設定されていないことを確認します。
[root@test02 ~]# cat /etc/hostname
localhost.localdomain
[root@test02 ~]#
上記のように「localhost.localdomain」というデフォルトの値が入っていますが、unameコマンドでホスト名を確認してみると「test02」というホスト名が返ってきます。
[root@test02 ~]# uname -n
test02.internal.example.com
「そもそもこのホスト名はどっから引っ張んてきてるん?」と思い 「straceコマンドでunameが実行時に参照しているファイル名がわからないかなー」と思ってstraceを実行。
[root@test02 ~]# strace uname -n
execve("/bin/uname", ["uname", "-n"], [/* 18 vars */]) = 0
brk(NULL)                               = 0x13d8000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6f7c717000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=18845, ...}) = 0
mmap(NULL, 18845, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6f7c712000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340$\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2151672, ...}) = 0
mmap(NULL, 3981792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6f7c12a000
mprotect(0x7f6f7c2ec000, 2097152, PROT_NONE) = 0
mmap(0x7f6f7c4ec000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c2000) = 0x7f6f7c4ec000
mmap(0x7f6f7c4f2000, 16864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6f7c4f2000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6f7c711000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6f7c70f000
arch_prctl(ARCH_SET_FS, 0x7f6f7c70f740) = 0
mprotect(0x7f6f7c4ec000, 16384, PROT_READ) = 0
mprotect(0x606000, 4096, PROT_READ)     = 0
mprotect(0x7f6f7c718000, 4096, PROT_READ) = 0
munmap(0x7f6f7c712000, 18845)           = 0
brk(NULL)                               = 0x13d8000
brk(0x13f9000)                          = 0x13f9000
brk(NULL)                               = 0x13f9000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=106075056, ...}) = 0
mmap(NULL, 106075056, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6f75c00000
close(3)                                = 0
uname({sysname="Linux", nodename="test02.internal.example.com", ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 64), ...}) = 0
ioctl(1, TCGETS, {B9600 opost isig icanon echo ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6f7c716000
write(1, "test02.internal.example.com\n", 28test02.internal.example.com
) = 28
close(1)                                = 0
munmap(0x7f6f7c716000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
[root@test02 ~]#
これと言って、それっぽそうなファイルにアクセスしてる形跡がねー。と思いながらunameコマンドが、「uname({sysname=”Linux”, nodename=”test02.internal.example.com”, …}) = 0」で、unameシステムコールを発行してるんだということを知りました。そこでunameシステムコールのマニュアルをちょっと確認します。
[root@test02 ~]# man 2 uname
~~snip~~
DESCRIPTION
       uname() returns system information in the structure pointed to by buf.  The utsname struct is defined in <sys/utsname.h>:

           struct utsname {
               char sysname[];    /* Operating system name (e.g., "Linux") */
               char nodename[];   /* Name within "some implementation-defined
                                     network" */
               char release[];    /* Operating system release (e.g., "2.6.28") */
               char version[];    /* Operating system version */
               char machine[];    /* Hardware identifier */
           #ifdef _GNU_SOURCE
               char domainname[]; /* NIS or YP domain name */
           #endif
           };

       The length of the arrays in a struct utsname is unspecified (see NOTES); the fields are terminated by a null byte ('\0').
~~snip~~
ここで何やらnodenameメンバ変数に「char nodename[]; /* Name within “some implementation-defined network” */」と注釈がついているのを発見。ネットワーク内の名前?
ここで、「そういやオレ、ローカル検証環境でDNSの設定やってたな」ということを思い出します。早速DNSサーバの逆引き設定を確認。あった。こいつのせいか?
[root@fw01 ~]# grep "test02" /var/named/192.168.1
210             IN PTR  test02.internal.example.com.
本当にこの設定が参照されているのかを確認します。
予想があってれば「test02」システムブート時にDNSサーバに対して、「test02」から逆引きが走るはずなのでDNSサーバでtcpdumpを張っておきます。そして「test02」を再起動。すると、3行目にある通り「PTR? 210.1.168.192.in-addr.arpa. (44)」と、逆引きの問い合わせがありました。
[root@test02 ~]# reboot
[root@fw01 ~]# tcpdump -i ens6 src host 192.168.1.210
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens6, link-type EN10MB (Ethernet), capture size 262144 bytes

20:54:06.808386 ARP, Request who-has test02.internal.example.com tell test02.internal.example.com, length 46
20:54:06.875458 ARP, Request who-has ns.internal.example.com tell test02.internal.example.com, length 46
20:54:06.876021 IP test02.internal.example.com.34510 > ns.internal.example.com.domain: 36070+ PTR? 210.1.168.192.in-addr.arpa. (44)
20:54:07.043879 IP test02.internal.example.com.39084 > ns.internal.example.com.domain: 60321+ A? 0.centos.pool.ntp.org. (39)
20:54:07.043909 IP test02.internal.example.com.39084 > ns.internal.example.com.domain: 20403+ AAAA? 0.centos.pool.ntp.org. (39)
20:54:07.050686 IP test02.internal.example.com.46289 > ns.internal.example.com.domain: 915+ A? 1.centos.pool.ntp.org. (39)
20:54:07.050715 IP test02.internal.example.com.46289 > ns.internal.example.com.domain: 29605+ AAAA? 1.centos.pool.ntp.org. (39)
20:54:07.055909 IP test02.internal.example.com.58553 > ns.internal.example.com.domain: 8184+ A? 2.centos.pool.ntp.org. (39)
20:54:07.055937 IP test02.internal.example.com.58553 > ns.internal.example.com.domain: 59142+ AAAA? 2.centos.pool.ntp.org. (39)
20:54:07.059669 IP test02.internal.example.com.54411 > ns.internal.example.com.domain: 27407+ A? 3.centos.pool.ntp.org. (39)
20:54:07.059692 IP test02.internal.example.com.54411 > ns.internal.example.com.domain: 47901+ AAAA? 3.centos.pool.ntp.org. (39)
unameがシステム起動時に呼ばれてるかまでは確認できていません。マニュアルにあった「ネットワーク内の名前」というキーワードからあたりをつけて調べてみました。utsname構造体のnodename変数に値が代入されるタイミングまで探して、そっから追ってくのもありかもしれませんが、、、
まぁもしかすると、これ以外にも同様の事象が発生する原因があるかもしれませんがひとまずこんなところで調査は終了とします。
それではまた。

追記
(2019/04/12)
・/etc/hostsに自身のIPに対応するホスト名を記載している場合でも設定される模様 参考

uname – システムコールの説明 – Linux コマンド集 一覧表