curl 和 nslookup 之间的名称查找区别是什么

Xia*_*ing 6 dns nslookup curl dig

当我试图弄清楚 DNS 查询何时会超时时,我迷失了方向。尝试了多种场景(在Linux上):

  1. /etc/resolv.conf 中未配置名称服务器

    ###################### curl #######################
    WRITE_OUT="%{http_code}\t%{time_namelookup}\t%{time_connect}\t\t%{time_starttransfer}\t\t%{time_total}\n"
    
    time curl -k -w "$WRITE_OUT" https://www.google.com/
    000     0.000   0.000           0.000           0.000
    
    curl: (6) Could not resolve host: www.goole.com; Unknown error
    
    real    0m0.009s
    user    0m0.000s
    sys     0m0.006s
    
    ##################### nslookup ####################
    time nslookup www.google.com
    ;; connection timed out; trying next origin
    ;; connection timed out; no servers could be reached
    
    real    0m24.012s
    user    0m0.004s
    sys     0m0.009s
    
    Run Code Online (Sandbox Code Playgroud)

    正如我们所看到的,curl 立即返回(9ms),而 nslookup 需要更长的时间(24s)。这让我非常困惑,curl 的行为更有意义,因为主机上没有指定名称服务器。

  2. 在/etc/resolv.conf中添加无法访问的主机IP,无法ping来模拟名称服务器关闭的情况

    ###################### curl #######################
    time curl -k -w "$WRITE_OUT" https://www.google.com/
    000     0.000   0.000           0.000           19.529  
    curl: (6) Could not resolve host: www.goole.com; Unknown error
    
    real    0m20.535s
    user    0m0.003s
    sys     0m0.005s
    
    ##################### nslookup ####################
    time nslookup www.google.com
    ;; connection timed out; trying next origin
    ;; connection timed out; no servers could be reached
    
    real    0m20.008s
    user    0m0.006s
    sys     0m0.003s
    
    Run Code Online (Sandbox Code Playgroud)

    欢呼!看起来像curl 和nslookup 在同一页面上。

  3. 添加可以 ping 通但没有 DNS 服务的主机 IP 地址,以模拟服务器处于活动状态但名称服务器服务已关闭

    ###################### curl #######################
    time curl -k -w "$WRITE_OUT" https://www.google.com/
    000     0.000   0.000           0.000           4.513
    curl: (6) Could not resolve host: www.goole.com; Unknown error
    
    real    0m5.520s
    user    0m0.004s
    sys     0m0.005s
    
    ##################### nslookup ####################
    time nslookup www.google.com
    ;; connection timed out; trying next origin
    ;; connection timed out; no servers could be reached
    
    
    real    0m20.010s
    user    0m0.006s
    sys     0m0.005s
    
    Run Code Online (Sandbox Code Playgroud)

    又迷茫了!

最令人困惑的部分是,从resolv.conf的 Manual 页面,我们可以看到默认值为timeout5 秒,attempts是 2 倍。所以我认为超时应该是 5 秒 * 2 = 10 秒。但是……令人困惑……

编辑:再次尝试修改/etc/nsswitch.conf,仅dns使用方法。hosts: dns

场景一:

###################### curl #######################
time curl -k -w "$WRITE_OUT" https://www.google.com/
000     0.000   0.000           0.000           0.000
curl: (6) Could not resolve host: www.google.com; Unknown error

real    0m0.051s
user    0m0.004s
sys     0m0.002s
##################### nslookup ####################
time nslookup www.google.com
;; connection timed out; trying next origin
;; connection timed out; no servers could be reached

real    0m24.287s
user    0m0.005s
sys     0m0.014s
######################## dig ######################
time dig www.google.com

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7 <<>> www.google.com
;; global options: +cmd
;; connection timed out; no servers could be reached

real    0m18.041s
user    0m0.005s
sys     0m0.005s
Run Code Online (Sandbox Code Playgroud)

场景2:

time curl -k -w "$WRITE_OUT" https://www.google.com/
000     0.000   0.000           0.000           19.527
curl: (6) Could not resolve host: www.google.com; Unknown error

real    0m20.533s
user    0m0.003s
sys     0m0.004s

time nslookup www.google.com
;; connection timed out; trying next origin
;; connection timed out; no servers could be reached

real    0m20.009s
user    0m0.005s
sys     0m0.005s

time dig www.google.com
; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7 <<>> www.google.com
;; global options: +cmd
;; connection timed out; no servers could be reached

real    0m15.008s
user    0m0.005s
sys     0m0.003s
Run Code Online (Sandbox Code Playgroud)

场景3:

time curl -k -w "$WRITE_OUT" https://www.google.com/
000     0.000   0.000           0.000           4.512
curl: (6) Could not resolve host: www.google.com; Unknown error

real    0m5.518s
user    0m0.004s
sys     0m0.003s

time nslookup www.google.com
;; connection timed out; trying next origin
;; connection timed out; no servers could be reached

real    0m20.009s
user    0m0.005s
sys     0m0.005s

time dig www.google.com

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7 <<>> www.google.com
;; global options: +cmd
;; connection timed out; no servers could be reached

real    0m15.009s
user    0m0.005s
sys     0m0.005s
Run Code Online (Sandbox Code Playgroud)

dig有自己的超时机制,timeout(5s) * retries(3) = 15s。

小智 8

虽然这是一篇老帖子,但我想插话一下,因为它已经不止一次地出现在我面前,所以我想分享一下。

需要指出的一个区别是应用程序(即 nslookup 或 curl)用于 DNS 查找的内容,即libresolv.solibbind.so. 似乎 nslookup 专门做后者,所以也许这就是为什么它比curl 更早超时的原因。要确定您的系统上的情况,您应该运行

strace -o curl.out curl www.google.com
strace -o dig.out dig www.google.com

grep libresolv *.out
grep libbind *.out
Run Code Online (Sandbox Code Playgroud)

并进行比较。

尽管很神秘,strace 输出应该显示每个部分等待的时间以及正在执行工作的底层系统调用


Nei*_*icz 4

nslookup/etc/hosts等类似工具直接查询DNS,而curl则先检查本地查询DNS。所以这可能是解决当前问题的线索。

我读到 nslookup 已被弃用。你有权限挖掘吗?