免费A级毛片无码专区网站-成人国产精品视频一区二区-啊 日出水了 用力乖乖在线-国产黑色丝袜在线观看下-天天操美女夜夜操美女-日韩网站在线观看中文字幕-AV高清hd片XXX国产-亚洲av中文字字幕乱码综合-搬开女人下面使劲插视频

netty系列之: 在netty中使用 tls 協(xié)議請求 DNS 服務器

目錄

  • 簡介
  • 支持DoT的DNS服務器
  • 搭建支持DoT的netty客戶端
  • TLS的客戶端請求
  • 總結
簡介在前面的文章中我們講過了如何在netty中構造客戶端分別使用tcp和udp協(xié)議向DNS服務器請求消息 。在請求的過程中并沒有進行消息的加密,所以這種請求是不安全的 。
那么有同學會問了,就是請求解析一個域名的IP地址而已,還需要安全通訊嗎?
事實上,不加密的DNS查詢消息是很危險的,如果你在訪問一個重要的網站時候,DNS查詢消息被監(jiān)聽或者篡改,有可能你收到的查詢返回IP地址并不是真實的地址,而是被篡改之后的地址,從而打開了釣魚網站或者其他惡意的網站,從而造成了不必要的損失 。
所以DNS查詢也是需要保證安全的 。
幸運的是在DNS的傳輸協(xié)議中特意指定了一種加密的傳輸協(xié)議叫做DNS-over-TLS,簡稱("DoT") 。
那么在netty中可以使用DoT來進行DNS服務查詢嗎?一起來看看吧 。
支持DoT的DNS服務器因為DNS中有很多傳輸協(xié)議規(guī)范,但并不是每個DNS服務器都支持所有的規(guī)范,所以我們在使用DoT之前需要找到一個能夠支持DoT協(xié)議的DNS服務器 。
這里我還是選擇使用阿里DNS服務器:
223.5.5.5之前使用TCP和UDP協(xié)議的時候查詢的DNS端口是53,如果換成了DoT,那么端口就需要變成853 。
搭建支持DoT的netty客戶端DoT的底層還是TCP協(xié)議,也就是說TLS over TCP,所以我們需要使用NioEventLoopGroup和NioSocketChannel來搭建netty客戶端,如下所示:
EventLoopGroup group = new NioEventLoopGroup();Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).handler(new DotChannelInitializer(sslContext, dnsServer, dnsPort));final Channel ch = b.connect(dnsServer, dnsPort).sync().channel();這里選擇的是NioEventLoopGroup和NioSocketChannel 。然后向Bootstrap中傳入自定義的DotChannelInitializer即可 。
DotChannelInitializer中包含了自定義的handler和netty自帶的handler 。
我們來看下DotChannelInitializer的定義和他的構造函數(shù):
class DotChannelInitializer extends ChannelInitializer<SocketChannel> {public DotChannelInitializer(SslContext sslContext, String dnsServer, int dnsPort) {this.sslContext = sslContext;this.dnsServer = dnsServer;this.dnsPort = dnsPort;}DotChannelInitializer需要三個參數(shù)分別是sslContext,dnsServer和dnsPort 。
這三個參數(shù)都是在sslContext中使用的:
protected void initChannel(SocketChannel ch) {ChannelPipeline p = ch.pipeline();p.addLast(sslContext.newHandler(ch.alloc(), dnsServer, dnsPort)).addLast(new TcpDnsQueryEncoder()).addLast(new TcpDnsResponseDecoder()).addLast(new DotChannelInboundHandler());}SslContext主要用來進行TLS配置,下面是SslContext的定義:
SslProvider provider =SslProvider.isAlpnSupported(SslProvider.OPENSSL)? SslProvider.OPENSSL : SslProvider.JDK;final SslContext sslContext = SslContextBuilder.forClient().sslProvider(provider).protocols("TLSv1.3", "TLSv1.2").build();因為SslProvider有很多種,可以選擇openssl,也可以選擇JDK自帶的 。
這里我們使用的openssl,要想提供openssl的支持,我們還需要提供openssl的依賴包如下:
<dependency><groupId>io.netty</groupId><artifactId>netty-tcnative</artifactId><version>2.0.51.Final</version></dependency><dependency><groupId>io.netty</groupId><artifactId>netty-tcnative-boringssl-static</artifactId><version>2.0.51.Final</version></dependency>有了provider之后,就可以調用SslContextBuilder.forClient方法來創(chuàng)建SslContext 。
這里我們指定SSL的protocol是"TLSv1.3"和"TLSv1.2" 。
然后再調用sslContext的newHandler方法就創(chuàng)建好了支持ssl的handler:

經驗總結擴展閱讀