主机名区分大小写 – getent的不同输出

[root@GFVM4 ~]# hostname GFVM4 [root@GFVM4 ~]# [root@GFVM4 ~]# [root@GFVM4 ~]# getent hosts gfvm4 192.168.122.151 GFVM4 [root@GFVM4 ~]# getent hosts GFVM4 fe80::5054:ff:feac:787 GFVM4 [root@GFVM4 ~]# [root@GFVM4 ~]# [root@GFVM4 ~]# [root@GFVM4 ~]# ifconfig ens5 ens5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.122.151 netmask 255.255.255.0 broadcast 192.168.122.255 inet6 fe80::5054:ff:feac:787 prefixlen 64 scopeid 0x20<link> ether 52:54:00:ac:07:87 txqueuelen 1000 (Ethernet) RX packets 452 bytes 33008 (32.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 204 bytes 26112 (25.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@GFVM4 ~]# 

上述预期的行为?

正如你所看到的,我已经设置了所有大写HOSTNAME GFVM4。

如果我使用相同的名称(全部大写),则返回ipv6地址。 如果我使用小字母主机名,则返回ipv4地址。

这是正确的行为?

将Fedora21作为基于qemu的虚拟机运行。

谢谢

这不会是一个完整的答案,只是想分享我的研究结果,而且太长,不适合评论…

首先,如果你想回复getent你需要在/etc/nsswitch.conf /etc/hosts等中有正确的configuration。我有一个Fedora 22,它有以下行/etc/nsswitch.conf

 hosts: files mdns4_minimal [NUTFOUND=return] dns myhostname 

getent hosts localhostgetent hosts LOCALHOST给出不同的结果。 但是在我改变了/etc/nsswitch.conf hosts: files ,他们给出了相同的结果。

我认为,当你有多个来源search,他们可能会以不同的方式处理案件,并给出不一致的结果。

其次,你可能想试试getent ahost 。 它使用getaddrinfo()而不是gethostbyname2() 。 至less在我的情况下,它给出了更一致的答案。 看man getent

第三,我发现有趣的是阅读源代码getent.c,并通过ltrace getent hosts localhost观察跟踪。 在那里你可以看到inet_pton()gethostbyname2() 。 您还可以通过ltrace -S跟踪系统调用,并且可以查看打开了哪些文件,例如/etc/hosts

以下是ltrace的输出。 在AF_INET(2)之前尝试AF_INET6(10)。

 [a@localhost ~]$ ltrace getent hosts LOCALHOST __libc_start_main([ "getent", "hosts", "LOCALHOST" ] <unfinished ...> mtrace() = <void> setlocale(LC_ALL, "") = "en_US.UTF-8" textdomain("libc") = "libc" argp_parse(0x606440, 3, 0x7ffc1cf8a7c8, 0) = 0 strcmp("hosts", "hosts") = 0 inet_pton(10, 0x7ffc1cf8c67a, 0x7ffc1cf8a680, 0) = 0 inet_pton(2, 0x7ffc1cf8c67a, 0x7ffc1cf8a680, 0x658e2f20) = 0 gethostbyname2(0x7ffc1cf8c67a, 10, 0x7ffc1cf8a680, 0x658e2f20) = 0 gethostbyname2(0x7ffc1cf8c67a, 2, -20, 0x7f166586c8f5) = 0x7f1665b16260 inet_ntop(2, 0xc47000, 0x7ffc1cf8a620, 46) = 0x7ffc1cf8a620 printf("%-15s %s", "127.0.0.1", "localhost.localdomain") = 37 __overflow(0x7f1665b13620, 32, 0, 0x7fffffda) = 32 fputs_unlocked(0xc47041, 0x7f1665b13620, 0x7f1665d36025, 0xfbad2a84) = 1 __overflow(0x7f1665b13620, 10, 0xc47050, 0x74736f686c61636f127.0.0.1 localhost.localdomain localhost ) = 10 +++ exited (status 0) +++ 

最后,我的build议是1)在/etc/nsswitch.conf控制getent的来源; 或者2)维护你自己的数据库/字典。

只是一个猜测,但从http://linuxmanpages.net/manpages/fedora21/man1/getent.1.html

主机当没有提供密钥时,使用sethostent(3),gethostent(3),
                    和endhostent(3)枚举主机数据库。 什么时候
                    提供一个或多个键参数,将每个键传递给
                     gethostbyaddr(3)或gethostbyname2(3),取决于
                    是否对inet_pton(3)的调用表示密钥是
                     IPv6或IPv4地址,并显示结果。

http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/usr.bin/getent/getent.c“if(argc == 2)”表示“%getent hosts”(不提供密钥) ,所以这是执行:

  for (i = 2; i < argc; i++) { if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0) he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6); else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0) he = gethostbyaddr(addr, INADDRSZ, AF_INET); else he = gethostbyname(argv[i]); if (he != NULL) hostsprint(he); else { rv = RV_NOTFOUND; break; } } 

我在C中并不是很棒,而且我发现的一个简单的Googlesearch引用了NetBSD,但是似乎如果第一个inet_pton( http://linuxmanpages.net/manpages/fedora21/man3/inet_pton.3.html )findIPv6的条目,则跳过IPv4的第二个function。 另外,我一开始并没有看到案件的强迫(意思是说,案情无效)。

也就是说,GFVM4可能有两个条目,一个是上层,另一个是低层。 较高的一个可能有一个IPv6地址相关联。

为了确认(或不),如果您能提供确认或不确认不同情况下的不同条目,那将是非常好的。 如果得到证实,我会说这是getent软件的预期行为。