nslookup blog.csdn.net Can't resolve blog.csdn.net
轉載:https://blog.csdn.net/prog_6103/article/details/78569510
嵌入式開發中存在各種奇奇怪怪的問題,明明ping www.baidu.com可以ping通了,但是使用nslookup 卻始終報錯,后來經過參考這個博主文章解決了nslookup失敗的問題。
缺少庫
libdl.so?
libnss.so
詳細分析請看如下文章
busybox是自制簡易系統必備的工具集了,包含了coreutils等各種系統小工具。在自己編譯的內核上運行busybox就要靜態編譯它。以前一直遇到busybox靜態編譯后放在自制系統運行nslookup ping wget解析不了域名的問題,也一直懶,沒有去解決。這次又遇到了這個問題,于是花點時間把它解決吧。
busybox靜態編譯后的nslookup
下載了glibc-static后對busybox編譯:make menuconfig,勾選Static Link;make。其中的build log當然不會注意,樂呵呵使用busybox nslookup blog.csdn.net,輸出Can't resolve "blog.csdn.net"。這個問題困擾很久了,今天終于有時間來看一看究竟。
難道是因為系統網絡配置的不對?ping 172.16.65.1網關是通路。開始抓瞎亂操作,比如開busybox dnsd,編譯ip_relay將172.16.65.1:53映射到本機127.0.0.1:53;全都沒有效果。于是Google這個問題,基本都是在問docker的busybox。在編譯Busybox的Linux機器上運行busybox nslookup blog.csdn.net,竟然是work的!
下載strace源代碼,靜態編譯。先在編譯機上試運行strace busybox nslookup blog.csdn.net,把log看一看,它先讀了/etc/resolv.conf,又讀了/etc/nsswitch.conf,還有/etc/host.conf;照搬把這些文件全在目標機器上創建好,nslookup顯示server倒是隨著resolve.conf的nameserver改變而改變了,可是不管設置什么server,都不能解析域名,114.114.114.114也如此。
再回到strace的log,發現它一樣加載了很多庫,比如libdl.so?libnss.so。那busybox運行在目標機器上會做什么?隨意把靜態編譯的strace復制到目標機器,strace busybox nslookup blog.csdn.net,好了,問題來了:目標機器上一樣要加載libdl.so等庫,而且在目標機器上都是No such file的錯誤,所以最后輸出了不能解析域名。
網上搜索了libnss是什么樣的庫,給出的答案是設計就是動態庫,不建議靜態編譯。要靜態編譯,請先重新編譯glibc,把–enable-libnss-static放上。這就比較煩了,用busybox就是沖著它dependency少,glibc又是一堆依賴,關鍵是編譯出來占蠻大空間的。有沒有其他方案?
域名解析
因為編譯了node,就想看看有沒有純javascript的包支持域名解析?結果沒有,還發現了npm也要用getaddrinfo進行域名解析。這個函數是libnss里的一個API。能繞過它么?既然網絡連得通,那為什么不可以直接發包給dns服務器呢?于是下載了Wireshark抓包,網上找找DNS協議的說明。發現了:?
http://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/?
這篇用C代碼手動發DNS請求得到ip的文章。先用JavaScript寫了一遍,準備編譯到node里讓npm工作起來,發現node靜態編譯后運行npm會segment falut,暫時擺一邊。于是先還是解決busybox的域名解析。grep getaddrinfo,發現三個文件在用nslookup.c?xconnect.c?inet_common.c,其中inet_common.c用它解析ipv6,這個就暫時不管了。對于nslookup和xcoonect(ping?wget都調用這里),應該把系統的getaddrinfo函數覆蓋掉就好了吧,所以準備了一個getaddrinfo.h?把getaddrinfo和freeaddrinfo重寫一遍,用直接發送UDP包的形式。make編譯busybox,然后在目標機器上運行:busybox nslookup blog.csdn.net
DNS解析其實過程很簡單,就是發一個query請求到DNS服務器,然后服務器會返回一個解答包。這篇文章介紹的很具體:http://www.firewall.cx/networking-topics/protocols/domain-name-system-dns/161-protocols-dns-response.html
好了,編譯完成。順便把node那個fully-static編譯后的DNS問題也解決了吧 :)
Translation:
Busybox is a power tool set including coreutils; it is very useful for self compiled Linux distribution. For using it on a Linux kernel without glibc support, it is required static link to compile Busybox. One issue always occurring is that?nslookup?ping?wget?applets do not work for url whose host name is not ip after static link. This time my build is stuck again for the problem. And also this time, I decide to totally resolve it.
nslookup in static linked Busybox
Installing glibc static support bundles, it is easy to compile Busybox with?static link?option checked:?make menuconfig;?make. Actually there is some static link warning in build process and I noticed after resolve the problem. After compiling it is happy to run?busybox nslookup www.google.com, however the output is sad -?Can't resolve "www.google.com". What a bug!
Is there any problem on the system network configuration? Let me check.?ping 172.16.65.1?the gateway is available; meanwhile my target machine has ip at?172.16.65.101. I am lost in the sea and do trials and errors: run?busybox dnsd; compile?ip_relay?and map?127.0.0.1:53?to?172,16.65.1:53; etc. No luck at all. I also tried to Google the problem and no exact answer, most people reported busybox nslookup problem is for busybox running by docker in container. Wait! Let me try static linked Busybox on build machine:?busybox nslookup www.google.com, it works!!!
I believe the program trigger some thing in backend and connect to DNS server. I download and compile static linked (it is possible to move strace to my target machine conveniently in future)?strace?to look insight. Read the trace log and find that the program touched some files like?/etc/resolv.conf?/etc/nsswitch.conf?/etc/host.conf. I set up them on the target machine as the same on the build machine.?nslookup?changes DNS server when resolve.conf changes. Somehow it cannot resolve domain name even using?8.8.8.8.
Back to the strace log and I find there are many shared libraries loaded, for example?libdl.so?libnss.so. What Busybox do internally on the target machine? For static linked strace, it is easy to move it to the target machine and run:?strace busybox nslookup www.google.com. Good, hit the problem: there are many shared libraries needed to be loaded; however, they does not exist on the target machine so that the log shows many?No such file?error. Naturally it print out?Can't resolve "xxx".
Searching for libnss on Internet, I got the answer that it is designed to be a shared library set; it is not recommended to link statically. If really want, recompile glibc with?--enable-libnss-static. How terrible! Lazy people want to sleep. I do not want glibc. Any idea?
DNS resolver
Actually I compile NodeJS and link it fully statically and want to use pure JavaScript package to support DNS resolving. Nothing found and get another problem:?npm install?uses?getaddrinfo?to resolve domain name and the function is dynamically linked to?libnss?API. Let’s find a way to bypass the dynamic link. Then an idea occurs. All we can get network available, why not send DNS request to servers directly? To understand DNS process in network, I download and install?Wireshark?to sniff network traffic and read a nice introduction at:?
http://www.binarytides.com/dns-query-code-in-c-with-linux-sockets/?
It is an article with some C code to send DNS request to server for IP address directly. At first I would like to use the method to make node npm work. After writing and testing simple JavaScript DNS module, I find that?npm install?seems always?segment fault?after fully static link build. Forget it and focus on?Busybox.?grep getaddrinfo?and find that there are 3 files in?Busybox?source code:?nslookup.c?xconnect.c?(ping?wget),?inet_common.c. For?inet_common.c, it uses?getaddrinfo?to resolve?ipv6. I would not like to make things complex at beginning. Thus let me write new?getaddrinfo?and?freeaddrinfo?for?nslookup.c?and?xconnect.c?to make DNS resolving work:?getaddrinfo.h?make?to compile Busybox and run it on the target machine. Wow, it works finally! Below is a screenshot for?busybox nslookup blog.csdn.net
The process of DNS resolving is not duplicated: send a request to DNS server and it will return answers. If interested in, you can read more about it:?http://www.firewall.cx/networking-topics/protocols/domain-name-system-dns/161-protocols-dns-response.html
Cool, mission complete. Go to resolve NodeJS DNS resolving problem in fully static link build : ) It is also clear now.
總結
以上是生活随笔為你收集整理的nslookup blog.csdn.net Can't resolve blog.csdn.net的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 红蓝对抗——蓝军(CheckList)总
- 下一篇: 教育部计算机考研大纲,2021考研计算机