一个数据包从你的电脑出发,然后达到目的地,比如google。中间到底经历了什么?我能不能看到它路过的路由器?traceroute可以做到。
traceroute原理简单说来,就是利用TTL(time to live,设置数据包最大生存时间,用来防止数据包在路由器间循环)。主机先给数据包设置一个TTL,然后这个数据包每经过一个路由器,路由器就把TTL减一。直到递减到零,这时,路由器会发送回来一个ICMP Time Exceeded,这个时候主机接收到之后,就知道相应的路由器IP了。
traceroute是linux自带的。详细用法见man。下面是最实用的命令。类似的工具还有tracepath,但是感觉traceroute更好。
1 2 3 4 | $ traceroute www.baidu.com $ traceroute google.com -U // Use UDP $ traceroute google.com -T // Use TCP SYN for probes # traceroute google.com -I -p53 // Use ICMP ECHO for probes,53端口提高通过率 |
只有这个功能,感觉不太好用,如果能知道ip的真实世界的地址就好了。比如中国上海这样的。正好网上出了个开源的GeoIP(IP与地理地址转换)。非常感谢作者。
然后胶水语言python就上台了。我就直接贴代码了,很好理解。注意这是不能直接运行的,需要下载相应的GeoIP,然后写个geoip来解析IP与地理地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #!/usr/bin/python import socket import geoip def sendPacket(icmp,udp,ttl,dest_name): port = 33434 recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) #接收icmp send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp) #udp发送数据包 send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl) send_socket.settimeout(3.0) recv_socket.settimeout(4.0) recv_socket.bind(("", port)) send_socket.sendto("", (dest_name, port)) curr_addr = None curr_name = None try: _, curr_addr = recv_socket.recvfrom(512) curr_addr = curr_addr[0] try: curr_name = socket.gethostbyaddr(curr_addr)[0] except socket.error: curr_name = curr_addr except socket.error: #有些路由器可能不会回复 print "%d\t%s\t%s" % (ttl,'*','*') return "unavaible" finally: send_socket.close() recv_socket.close() if curr_addr is not None: curr_host = "%s (%s)" % (curr_name, curr_addr) else: curr_host = "*" print "{:d}\t{:70s}".format(ttl, curr_host), print "%s"%(geoip.geoip(curr_addr)) #转换地址 return curr_addr def traceroute(dest_name): dest_addr = socket.gethostbyname(dest_name) max_hops = 50 icmp = socket.getprotobyname('icmp') udp = socket.getprotobyname('udp') ttl = 1 while True: curr_addr = sendPacket(icmp,udp,ttl,dest_name) ttl += 1 if curr_addr == dest_addr or ttl > max_hops: break if __name__ == "__main__": traceroute('blog.slinuxer.com') |
效果图:
链接:
您好,我开着赛风来 traceroute 一下谷歌,但是很奇怪,经过的节点如下:
1 10.0.2.2
2 * * * *
一路* * * * 到30
结果我啥都看不到,听说赛风用了 meek 之类的东西混淆流量,会不会是这个原因呢?
感谢!
赛风也没有听说过,我不太清楚,可能是因为超时了,你参考一下这http://serverfault.com/questions/334029/what-does-mean-when-traceroute
要翻墙最好自己国外搞个主机,30块钱,安全稳定。
谢谢,换了一下 traceroute -T 就行了。
我也有那本30天自制操作系统,不过半年来一直没怎么看,很厚。
对于我这样不是计算机专业的,估计要多一倍时间,60天,才能弄明白吧。
那本书有点古老,工具都有点旧,这里面的坑太多。主要在于自己写来实践,能更深刻的理解操作系统的原理。不是非计算机专业的话还是把功夫花在其他事情上比较好,比如折腾ArchLinux啥的会事半功倍。