gethostbyname与DNS

一句话总结

域名查询(Domain Name Query)在Linux上的执行主要由glibc库函数gethostbynamegethostbyaddr来完成,通过strace跟踪可知gethostbyname的执行流程如下:

  1. 连接socket文件/var/run/nscd/socket,通过nscd进程缓存的内容来获取。nscd会实时监测/etc/hosts/etc/resolv.conf文件内容的变化并缓存,具体请参考/etc/nscd.conf中的说明。

  2. 如果没有nscd服务,则通过/etc/nsswitch.conf中的hosts配置项来决定域名查询获取顺序。通常该配置项为"hosts: files dns",则表示先读/etc/hosts,否则就读/etc/resolv.confDNS服务器发出域名解析请求。

注:关于DNS与dig命令的介绍请阅读阮一峰老师的文章DNS原理入门

strace跟踪gethostbyname

先介绍下我的系统环境:

# cat /etc/centos-release 
CentOS release 6.6 (Final)

# uname -a
Linux vm-10-11-174-154 2.6.32-926.504.30.3.letv.el6.x86_64 #1 SMP Mon Aug 3 16:29:31 CST 2015 x86_64 x86_64 x86_64 GNU/Linux

# ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 3月  25 2016 /lib64/libc.so.6 -> libc-2.12.so*

# /lib64/libc.so.6 
GNU C Library stable release version 2.12, by Roland McGrath et al.
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.4.7 20120313 (Red Hat 4.4.7-16).
Compiled on a Linux 2.6.32 system on 2016-02-16.
Available extensions:
    The C stubs add-on version 2.1.2.
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    BIND-8.2.3-T5B
    RT using linux kernel aio
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

没有配置nscd的服务器上,用strace追踪gethostbyname,其大致流程摘录如下(省略的部分用......表示)。库函数gethostbyname的使用可参考该页面

# strace ./gethostbyname "lecloud.com"
execve("./gethostbyname", ["./gethostbyname", "lecloud.com"], [/* 32 vars */]) = 0
brk(0)                                  = 0x741000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa832c1e000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 4
fstat(4, {st_mode=S_IFREG|0644, st_size=61583, ...}) = 0
mmap(NULL, 61583, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fa832c0e000
close(4)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 4
......
open("/etc/resolv.conf", O_RDONLY)      = 4
......
socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 4
connect(4, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(4)                                = 0
socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 4
connect(4, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(4)                                = 0
open("/etc/nsswitch.conf", O_RDONLY)    = 4
......
open("/etc/host.conf", O_RDONLY)        = 4
......
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4
......
socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
gettimeofday({1481080561, 158097}, NULL) = 0
poll([{fd=4, events=POLLOUT}], 1, 0)    = 1 ([{fd=4, revents=POLLOUT}])
sendto(4, "Zq\1\0\0\1\0\0\0\0\0\0\7lecloud\3com\0\0\1\0\1", 29, MSG_NOSIGNAL, NULL, 0) = 29
poll([{fd=4, events=POLLIN}], 1, 5000)  = 1 ([{fd=4, revents=POLLIN}])
ioctl(4, FIONREAD, [77])                = 0
recvfrom(4, "Zq\201\200\0\1\0\3\0\0\0\0\7lecloud\3com\0\0\1\0\1\300\f\0"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, [16]) = 77
close(4)                                = 0
exit_group(0)                           = ?

要想查看某个程序是否调用gethostbyname,只需用ltrace命令跟踪一下查看其库函数调用即可:

# ltrace ping -c 1 baidu.com 2>&1 | grep gethostbyname
gethostbyname("baidu.com")                       = 0x7f21dfaf16e0

注:在man gethostbyname中有一句:

The gethostbyname() and gethostbyaddr() functions are obsolete. Applications should use getaddrinfo(3) and getnameinfo(3) instead.

其它

nscd

笔者所在公司的服务器上并没有配置nscd,但笔者的阿里云个人服务器上却默认配置了nscd。从man nscd摘录如下:

/usr/sbin/nscd - Name Service Cache Daemon

Nscd is a daemon that provides a cache for the most common name service requests. The default configuration file, /etc/nscd.conf, determines the behavior of the cache daemon.

The daemon will try to watch for changes in configuration files appropriate for each database (e.g. /etc/passwd for the passwd database or /etc/hosts and /etc/resolv.conf for the hosts database), and flush the cache when these are changed.

dnsmasq

Linux服务器上一般都会配置dnsmasq服务,用于缓存DNS请求结果,节省应用程序的域名解析时间。笔者的笔记本Ubuntu 16.04 LTS也默认配置了dnsmasq,同样笔者的macOS Sierra上也默认有一个叫mDNSResponder的服务。dnsmasq简介如下:

dnsmasq - A lightweight DHCP and caching DNS server.

It is intended to provide coupled DNS and DHCP service to a LAN. Dnsmasq accepts DNS queries and either answers them from a small, local, cache or forwards them to a real, recursive, DNS server.

dnsmasq通常会绑定本地127.0.0.1:53,假设配置的DNS服务器是Google Public DNS,则dnsmasq的配置/etc/dnsmasq.conf一般如下:

listen-address=127.0.0.1
bind-interfaces
no-hosts
no-resolv
#all-servers
cache-size=10000
no-negcache
max-cache-ttl=600
filter-aaaa
server=8.8.8.8
server=8.8.4.4

这样,/etc/resolv.conf的配置如下。注意第一项nameserver是本地IP127.0.0.1,也就利用上了dnsmasq的DNS缓存功能。

nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4

网络上广泛使用的DNS服务器通常是bind,简介如下:

BIND (Berkeley Internet Name Domain) is an implementation of the DNS (Domain Name System) protocols. BIND includes a DNS server (named), which resolves host names to IP addresses; a resolver library (routines for applications to use when interfacing with DNS); and tools for verifying that the DNS server is operating properly.

named - /usr/sbin/named

dig

strace追踪可知,dig命令是通过读配置文件/etc/resolv.conf,然后向其中列出的DNS服务器发出DNS请求。

# strace dig baidu.com 2>&1 | grep "/etc/resolv.conf"
open("/etc/resolv.conf", O_RDONLY)      = 10

程序跟踪与网络抓包

在日常开发和学习中,遇到问题或对某个东西感到疑惑的时候,对程序进行调用跟踪和对网络进行抓包,是非常有效的分析方式。

strace来跟踪系统函数调用,细节请参考man strace

ltrace来跟踪库函数调用,细节参考man ltrace

wireshark(GUI)、tsharktcpdump来进行网络抓包,细节参考各自的man说明页。

更加强大和复杂的动态追踪技术,请参考SystemTap和DTrace(DTrace for Linux 2016, wikipedia),我还没尝试过。还可以阅读大神章亦春(春哥)写的文章动态追踪技术漫谈

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,744评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,505评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,105评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,242评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,269评论 6 389
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,215评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,096评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,939评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,354评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,573评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,745评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,448评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,048评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,683评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,838评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,776评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,652评论 2 354

推荐阅读更多精彩内容

  • NAME dnsmasq - A lightweight DHCP and caching DNS server....
    ximitc阅读 2,850评论 0 0
  • dnsmasq是什么我就不说了,请自行百度。 目前我需要使用的用途是:1.dhcp(分配一个或者多个内网ip地址)...
    dnaEMx阅读 16,133评论 0 6
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 在使用consul做docker容器服务化的过程中,使用到了dnsmasq做DNS请求转发,于是研究了下DNS协议...
    __七把刀__阅读 3,995评论 2 13
  • 1. 概述 在网络环境中一般用户只需要在浏览器中输入url如www.sunny.com就可以到对应服务器获取相应的...
    ghbsunny阅读 2,888评论 0 7