DNS 和 http proxy

19 Jul 2017 . . Comments

最近小被dns折腾了一下。记录一下折腾经过

ping dl.bintray.com 显示 ping: unknown host dl.bintray.com。但是这台服务器 是一个缓存dl.bintray.com的服务器,一直可以缓存远端网站的内容。

curl也不行

[user@host ~]$ curl -vv  dl.bintray.com
Rebuilt URL to: dl.bintray.com/
* Curl_ipv4_resolve_r failed for dl.bintray.com
* Couldn't resolve host 'dl.bintray.com'
* Closing connection 0
curl: (6) Couldn't resolve host 'dl.bintray.com'

dig /etc/resolv.conf里面的nameserver也没有结果

[user@host ~]$ dig dl.bintray.com +short
[user@host ~]$

于是我加了一个可用的nameserver,然后直接dig还是不行,但是@nameserver有结果

[user@host ~]$ dig dl.bintray.com +short
[user@host ~]$ dig dl.bintray.com @name-server-ip +short
75.126.118.188

ping依然不行

[user@host nscd]#  ping  dl.bintray.com
ping: unknown host dl.bintray.com

关于/etc/resolv.conf

resolv.conf的内容如下:

[root@hkp3plg021 nscd]# cat /etc/resolv.conf
search some.domain
options timeout:0 attempts:1 rotate
nameserver ip1
nameserver ip2
nameserver ip3

其中ip2是可以成功解析外网域名的dns服务器,我原来以为设置多个nameserver会导致 如果在一个nameserver查询失败那么继续到下一个nameserver,但是好像并不是这样,注 意在resolv.conf里面有配置option rotate

  • 如果没有 rotate,永远使用第一个nameserver
  • 如果加了 rotate,其行为也不是失败继续到下一个,而是一种负载均衡的行为,不同的查询会落到不同的nameserver。man page如下
rotate  sets RES_ROTATE in _res.options, which causes round robin selection of nameservers from among those listed. 
        This has the effect of spreading the query load among all listed servers, rather than having all clients 
        try the first listed server first every time.
  • 即使加了rotate, 对同一个domain的查询也是在同一个nameservers上,只有下一个不同的domain才会使用下一个nameserver,比如
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.pandatv.com
ping: unknown host www.pandatv.com
[user@host nscd]# ping www.google.com.se
PING www.google.com.se (81.169.200.26) 56(84) bytes of data.
  • 好像我需要重启nscd,这是一个本机的缓存服务,这些更改才能立马见效
[user@host nscd]# /etc/init.d/nscd reload
  • /etc/nsswitch.conf控制了域名解析的顺序
[user@host nscd]# grep host /etc/nsswitch.conf
#hosts:     db files nisplus nis dns
hosts:      files dns

这里可以看到先查看 /etc/hosts,然后再使用dns服务器。

  • dig/nslookup,如果不指定服务器,永远使用第一个nameserver

总的来说还是挺坑爹的。

proxy

设置http_proxy的时候,解析的是代理服务器的域名,目的域名的解析发生在代理服务 器上。这本来应该是一件比较明显的事情,但是有的时候就是会忽略。

[user@host ~]$ strace -o a.log curl  -vv   dl.bintray.com -o index.html
* Rebuilt URL to: dl.bintray.com/
* Curl_ipv4_resolve_r failed for dl.bintray.com
* Couldn't resolve host 'dl.bintray.com'
* Closing connection 0
curl: (6) Couldn't resolve host 'dl.bintray.com'

####less a.log

open("/etc/resolv.conf", O_RDONLY)      = 3
.........
.........
socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = 0
sendto(3, "\2\0\0\0\4\0\0\0\17\0\0\0dl.bintray.com\0", 27, MSG_NOSIGNAL, NULL, 0) = 27
poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])

可以看到这里发送给nscd的请求是 dl.bintray.com

当设置了http_proxy之后,同样的命令

socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = 0
sendto(3, "\2\0\0\0\4\0\0\0\16\0\0\0apxy1.domain.name\0", 26, MSG_NOSIGNAL, NULL, 0) = 26

可以看到请求的是http_proxy的域名。