范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

JavaNetty框架自建DNS代理服务器教程

  前言
  DNS协议作为着互联网客户端-服务器通信模式得第一关,在当下每天都有成千上亿上网记录产生得当今社会,其重要性自然不可言喻。在国内比较有名得DNS服务器有电信得114.114.114.114、阿里云得223.5.5.5,DNSPod得119.29.29.29,配置一个好的DNS服务器可以缩短请求响应时间、降低DNS劫持概率,提升上网体验。
  上面这些都是互联网公用DNS服务器,本文博主教大家使用 Java Netty 自建DNS代理服务器,目前网上对于使用Netty自建DNS服务器得教程良莠不齐,大多没有代理步骤,达不到博主想要得代理效果,因而创建此文。一、自建DNS代理服务器有哪些优势域名控制:对于特定域名可以自由控制访问权限(屏蔽对特定网站访问)域名记录:记录局域网内各个主机得域名访问(记录员工上网记录)配置内网域名:通过自建DNS服务器可以配置内网域名,节约成本DNS负载均衡:通过自建DNS服务器可以轻松实现对于访问域名得负载均衡配置...二、自建DNS代理服务器代码添加域名黑名单文件,resources 文件夹下添加 black_list.txt 文件google.com. facebook.com.
  初始化 BLACK_LIST_DOMAINprivate static final List BLACK_LIST_DOMAIN = new ArrayList<>();     static {         String s;         try (InputStream is = DnsServer.class.getClassLoader().getResourceAsStream("black_list.txt");              BufferedReader br = new BufferedReader(new InputStreamReader(is))) {             while (StrUtil.isNotBlank(s = br.readLine())) {                 BLACK_LIST_DOMAIN.add(s);             }         } catch (Exception e) {             log.error(e.getMessage(), e);         }     }
  2.使用 UDP 协议绑定本机53端口,并初始化 ProxyUdp DNS请求代理对象@Slf4j public final class DnsServer {     private static final List BLACK_LIST_DOMAIN = new ArrayList<>();     static {        ...     }      public static void main(String[] args) throws Exception {         ProxyUdp proxyUdp = new ProxyUdp();         proxyUdp.init();         final int[] num = {0};         final NioEventLoopGroup group = new NioEventLoopGroup();         Bootstrap bootstrap = new Bootstrap();         bootstrap.group(group).channel(NioDatagramChannel.class)                 .handler(new ChannelInitializer() {                     @Override                     protected void initChannel(NioDatagramChannel nioDatagramChannel) {                         nioDatagramChannel.pipeline().addLast(...);                     }                 }).option(ChannelOption.SO_BROADCAST, true);          int port = 53;         ChannelFuture future = bootstrap.bind(port).addListener(future1 -> {             log.info("server listening port:{}", port);         });          future.channel().closeFuture().addListener(future1 -> {             if (future.isSuccess()) {                 log.info(future.channel().toString());             }         });     } }
  3.给 nioDatagramChannel.pipeline() 添加 ChannelHandlernioDatagramChannel.pipeline().addLast(new DatagramDnsQueryDecoder());                         nioDatagramChannel.pipeline().addLast(new SimpleChannelInboundHandler() {                             @Override                             protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery msg) {                                 try {                                     DefaultDnsQuestion dnsQuestion = msg.recordAt(DnsSection.QUESTION);                                     String name = dnsQuestion.name();                                     log.info(name + ++num[0]);                                     Channel channel = ctx.channel();                                     int id = msg.id();                                     channel.attr(AttributeKey.valueOf(String.valueOf(id))).set(msg);                                     if (BLACK_LIST_DOMAIN.contains(name)) {                                         DnsQuestion question = msg.recordAt(DnsSection.QUESTION);                                         DatagramDnsResponse dnsResponse = getDatagramDnsResponse(msg, id, question);                                         channel.writeAndFlush(dnsResponse);                                         return;                                     }                                     proxyUdp.send(name, msg.id(), channel);                                 } catch (Exception e) {                                     log.error(e.getMessage(), e);                                 }                             }                              private DatagramDnsResponse getDatagramDnsResponse(DatagramDnsQuery msg, int id, DnsQuestion question) {                                 DatagramDnsResponse dnsResponse = new DatagramDnsResponse(msg.recipient(), msg.sender(), id);                                 dnsResponse.addRecord(DnsSection.QUESTION, question);                                 DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(                                         question.name(),                                         DnsRecordType.A, 600, Unpooled.wrappedBuffer(new byte[]{(byte) 192, (byte) 168, 1, 1}));                                 dnsResponse.addRecord(DnsSection.ANSWER, queryAnswer);                                 return dnsResponse;                             }                              @Override                             public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {                                 log.error(e.getMessage(), e);                             }                         });                         nioDatagramChannel.pipeline().addLast(new DatagramDnsResponseEncoder());
  在 new SimpleChannelInboundHandler() 中 解析客户端DNS查询报文, 获取访问域名信息,如果访问域名在黑名单中,则通过 getDatagramDnsResponse() 直接返回 192.168.1.1 的DNS响应报文,反之则通过 proxyUdp 对象转发DNS查询。
  4.ProxyUdp 作为DNS查询代理类会通过 send(String domain, int id, Channel serverChannel) 方法传入DnsServer类收到的访问域名、DNS事务ID、serverChannel。随后包装访问域名请求DNS服务器114.114.114.114,最后通过 new SimpleChannelInboundHandler() 将收到的DNS响应报文通过上一步传入得 serverChannel 输出到客户端。@Slf4j class ProxyUdp {     private Channel serverChannel;     private Channel proxyChannel;      public void init() throws InterruptedException {         EventLoopGroup proxyGroup = new NioEventLoopGroup();         Bootstrap b = new Bootstrap();         b.group(proxyGroup)                 .channel(NioDatagramChannel.class)                 .handler(new ChannelInitializer() {                     @Override                     protected void initChannel(DatagramChannel ch) {                         ChannelPipeline p = ch.pipeline();                         p.addLast(new DatagramDnsQueryEncoder())                                 .addLast(new DatagramDnsResponseDecoder())                                 .addLast(new SimpleChannelInboundHandler() {                                     @Override                                     public void channelActive(ChannelHandlerContext ctx) {                                         log.info(ctx.channel().toString());                                     }                                      @Override                                     protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsResponse msg) {                                         DatagramDnsQuery dnsQuery = localChannel.attr(AttributeKey.valueOf(String.valueOf(msg.id()))).get();                                         DnsQuestion question = msg.recordAt(DnsSection.QUESTION);                                         DatagramDnsResponse dnsResponse = new DatagramDnsResponse(dnsQuery.recipient(), dnsQuery.sender(), msg.id());                                         dnsResponse.addRecord(DnsSection.QUESTION, question);                                          for (int i = 0, count = msg.count(DnsSection.ANSWER); i < count; i++) {                                             DnsRecord record = msg.recordAt(DnsSection.ANSWER, i);                                             if (record.type() == DnsRecordType.A) {                                                 // just print the IP after query                                                 DnsRawRecord raw = (DnsRawRecord) record;                                                 DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(                                                         question.name(),                                                         DnsRecordType.A, 600, Unpooled.wrappedBuffer(ByteBufUtil.getBytes(raw.content())));                                                 dnsResponse.addRecord(DnsSection.ANSWER, queryAnswer);                                             }                                         }                                          serverChannel.writeAndFlush(dnsResponse);                                     }                                      @Override                                     public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {                                         log.error(e.getMessage(), e);                                     }                                 });                      }                 });         proxyChannel = b.bind(0).sync().addListener(future1 -> {             log.info("绑定成功");         }).channel();     }      public void send(String domain, int id, Channel serverChannel) {         this.serverChannel = serverChannel;         DnsQuery query = new DatagramDnsQuery(null, new InetSocketAddress("114.114.114.114", 53), id).setRecord(                 DnsSection.QUESTION,                 new DefaultDnsQuestion(domain, DnsRecordType.A));         this.proxyChannel.writeAndFlush(query);     } }
  5.自建DNS服务器全部代码@Slf4j public final class DnsServer {     private static final List BLACK_LIST_DOMAIN = new ArrayList<>();     static {         String s;         try (InputStream is = DnsServer.class.getClassLoader().getResourceAsStream("black_list.txt");              BufferedReader br = new BufferedReader(new InputStreamReader(is))) {             while (StrUtil.isNotBlank(s = br.readLine())) {                 BLACK_LIST_DOMAIN.add(s);             }         } catch (Exception e) {             log.error(e.getMessage(), e);         }     }      public static void main(String[] args) throws Exception {         ProxyUdp proxyUdp = new ProxyUdp();         proxyUdp.init();         final int[] num = {0};         final NioEventLoopGroup group = new NioEventLoopGroup();         Bootstrap bootstrap = new Bootstrap();         bootstrap.group(group).channel(NioDatagramChannel.class)                 .handler(new ChannelInitializer() {                     @Override                     protected void initChannel(NioDatagramChannel nioDatagramChannel) {                         nioDatagramChannel.pipeline().addLast(new DatagramDnsQueryDecoder());                         nioDatagramChannel.pipeline().addLast(new SimpleChannelInboundHandler() {                              @Override                             protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsQuery msg) {                                 try {                                     DefaultDnsQuestion dnsQuestion = msg.recordAt(DnsSection.QUESTION);                                     String name = dnsQuestion.name();                                     log.info(name + ++num[0]);                                     Channel channel = ctx.channel();                                     int id = msg.id();                                     channel.attr(AttributeKey.valueOf(String.valueOf(id))).set(msg);                                     if (BLACK_LIST_DOMAIN.contains(name)) {                                         DnsQuestion question = msg.recordAt(DnsSection.QUESTION);                                         DatagramDnsResponse dnsResponse = getDatagramDnsResponse(msg, id, question);                                         channel.writeAndFlush(dnsResponse);                                         return;                                     }                                     proxyUdp.send(name, msg.id(), channel);                                 } catch (Exception e) {                                     log.error(e.getMessage(), e);                                 }                             }                              private DatagramDnsResponse getDatagramDnsResponse(DatagramDnsQuery msg, int id, DnsQuestion question) {                                 DatagramDnsResponse dnsResponse = new DatagramDnsResponse(msg.recipient(), msg.sender(), id);                                 dnsResponse.addRecord(DnsSection.QUESTION, question);                                  // just print the IP after query                                 DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(                                         question.name(),                                         DnsRecordType.A, 600, Unpooled.wrappedBuffer(new byte[]{(byte) 192, (byte) 168, 1, 1}));                                 dnsResponse.addRecord(DnsSection.ANSWER, queryAnswer);                                 return dnsResponse;                             }                              @Override                             public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {                                 log.error(e.getMessage(), e);                             }                         });                         nioDatagramChannel.pipeline().addLast(new DatagramDnsResponseEncoder());                      }                 }).option(ChannelOption.SO_BROADCAST, true);          int port = 553;         ChannelFuture future = bootstrap.bind(port).addListener(future1 -> {             log.info("server listening port:{}", port);         });          future.channel().closeFuture().addListener(future1 -> {             if (future.isSuccess()) {                 log.info(future.channel().toString());             }         });     } }  @Slf4j class ProxyUdp {     private Channel localChannel;     private Channel proxyChannel;      public void init() throws InterruptedException {         EventLoopGroup proxyGroup = new NioEventLoopGroup();         Bootstrap b = new Bootstrap();         b.group(proxyGroup)                 .channel(NioDatagramChannel.class)                 .handler(new ChannelInitializer() {                     @Override                     protected void initChannel(DatagramChannel ch) {                         ChannelPipeline p = ch.pipeline();                         p.addLast(new DatagramDnsQueryEncoder())                                 .addLast(new DatagramDnsResponseDecoder())                                 .addLast(new SimpleChannelInboundHandler() {                                     @Override                                     public void channelActive(ChannelHandlerContext ctx) {                                         log.info(ctx.channel().toString());                                     }                                      @Override                                     protected void channelRead0(ChannelHandlerContext ctx, DatagramDnsResponse msg) {                                         DatagramDnsQuery dnsQuery = localChannel.attr(AttributeKey.valueOf(String.valueOf(msg.id()))).get();                                         DnsQuestion question = msg.recordAt(DnsSection.QUESTION);                                         DatagramDnsResponse dnsResponse = new DatagramDnsResponse(dnsQuery.recipient(), dnsQuery.sender(), msg.id());                                         dnsResponse.addRecord(DnsSection.QUESTION, question);                                          for (int i = 0, count = msg.count(DnsSection.ANSWER); i < count; i++) {                                             DnsRecord record = msg.recordAt(DnsSection.ANSWER, i);                                             if (record.type() == DnsRecordType.A) {                                                 // just print the IP after query                                                 DnsRawRecord raw = (DnsRawRecord) record;                                                 DefaultDnsRawRecord queryAnswer = new DefaultDnsRawRecord(                                                         question.name(),                                                         DnsRecordType.A, 600, Unpooled.wrappedBuffer(ByteBufUtil.getBytes(raw.content())));                                                 dnsResponse.addRecord(DnsSection.ANSWER, queryAnswer);                                             }                                         }                                          localChannel.writeAndFlush(dnsResponse);                                     }                                      @Override                                     public void exceptionCaught(ChannelHandlerContext ctx, Throwable e) {                                         log.error(e.getMessage(), e);                                     }                                 });                      }                 });         proxyChannel = b.bind(0).sync().addListener(future1 -> {             log.info("绑定成功");         }).channel();     }      public void send(String domain, int id, Channel localChannel) {         this.localChannel = localChannel;         DnsQuery query = new DatagramDnsQuery(null, new InetSocketAddress("114.114.114.114", 53), id).setRecord(                 DnsSection.QUESTION,                 new DefaultDnsQuestion(domain, DnsRecordType.A));         this.proxyChannel.writeAndFlush(query);     } }三、本地测试
  1.修改本机DNS设置(win11),修改首选、备选DNS地址为127.0.0.1
  2.打开命令行工具,执行DNS缓存清除命令 ipconfig/flushdns
  自此就可以打开浏览器访问常用网站,看是否能正常访问,来验证自建的DNS服务器效果了

冬天,少吃雪梨多吃这3样!简单一煮,香甜营养,大人孩子都爱喝冬天,少吃雪梨多吃这3样!简单一煮,香甜营养,大人孩子都爱喝。冬天最常见的症状就是咳嗽发烧,随着全国新冠的放开,最近大多数的人已经中招,几乎所有的人都已经出现了发烧咳嗽。发烧后吃过专治各种平庸,冬天袖子戏法上演了冬天穿衣有时缺少一些亮点,万万没想到需要在袖子上集中体现,或许袖子的时髦在今年还在延续。袖套毛衣前有短袖针织衫,后有袖套毛衣,总有一些看不懂的单品成为新宠,也架不住日久见真香。现在效力于英超的葡萄牙球员身价B席80M欧居首,费利克斯50M欧切尔西官方宣布,以租借的形式签下葡萄牙前锋费利克斯。德国转会市场盘点了目前效力于英超的葡萄牙球员的身价排行,其中曼城中场贝尔纳多席尔瓦位居榜首,他的身价为8000万欧元。排行详情(曝湖人周五将试训考辛斯!留给布朗的时间仅剩4天三战0分太糗头条创作挑战赛北京时间1月13日凌晨,雅虎体育记者克里斯海恩斯报道,洛杉矶湖人队将在当地时间周五试训德马库斯考辛斯。随后各大媒体都转发了这一消息,在联盟开启签约自由球员后,湖人已经琼斯凌晨三点连续发文,有些最重要的秘密直到季后赛才会披露Idontsleepmuch。Ihavealotinmymind。Ithinkaboutbasketballalot。IthinkaboutmyfutureintheCBAalot高居中国航天员总飞行时长前6!神十三与神十四乘组个个都很会飞北京时间2022年6月5日1044,搭载陈冬刘洋蔡旭哲3名航天员的神舟十四号载人飞船由长征二号F遥十四运载火箭发射升空,前往近地空间执行中国空间站的建造任务,飞船于当年12月4日2孕40周,宝宝没有要出来的迹象,该怎么办?怀孕40周宝宝没有要出来的迹象,这很正常。据统计,大约有15的孕妈妈会在4042周分娩。虽然比例不是很高吧,但是也没有必要太过于紧张和焦虑。有什么办法能让宝宝早点出来呢?方法按摩乳孩子还小背诵大量古诗文,很多是机械记忆反复强化的结果,八九成不解其义。有益吗?可行吗?从四岁半开始教秦小小背诗。最长的一篇是背了荀子的劝学篇,从开始一直背到了目不能两视而明,耳不能两听而聪。很少给她解释诗文的意思,即使解释,也只是描述个大概。我身边90的人都在反对我滑稽界历史上,陶醉娟有哪些故事?陶醉娟老师,有名滑稽演员滑稽名家有名滑稽表演艺术家周益伦的妈妈老艺术家滑稽界摘得白玉兰的第一人。在舞台上这是一个并不陌生的身影,在影视剧中她频频亮相,从青年演到中年又演到老年,无数李霄鹏被金钟夫接替,你认为有可能吗?我懂足球,我来管,或许还可以踢赢几场。我只看上场时谁最拼。也是网上的道听途说,客人觉得可能性不大,李小鹏尽管率队打了两轮全败,尤其是大年初一成功输给越南,让范大将军曾经的预言应验,2月3日,全场处于劣势的女足,为什么能够战胜世界冠军日本女足?说实话,我们确实要面对现实的是我们女足姑娘的硬实力确实比日韩要差一点点。球迷们也没想国足的水平能一夜之间达到世界的顶峰。但只要我们敢拼敢打,不能输了了中国人的志气。昨天的比赛让我想
NASA宇航员尼科尔曼在太空行走期间完成ampampquot太空自拍ampampquot美国宇航局宇航员和远征68号飞行工程师尼科尔曼在6小时41分钟的太空行走中,将镜头对准自己,并在头盔遮阳板上拍了一张太空自拍。她和来自日本宇宙航空研究开发机构(JAXA)的太空行走杂知识带你走进多彩的显示器世界Hi大家好,我是少年闰土的杂货铺酷从今天开始给大家做一个杂知识的分享,才疏学浅,有不妥和谬误的地方希望大家多多指出,多多关注,讨论谢谢前言大家日常生活中接触过很多显示器手机电视平板众包美团外卖兼职到底行不行?头条创作挑战赛美团众包送餐还有希望吗?跑过美团的都知道,现在美团外卖的骑手已经饱和了,甚至于说已经溢出来了,但是还在不断招人,走的没有来的多。美团还在不断发展壮大中,下面我们来分析PS下载和常见PS安装错误代码与解决方法2023下载PS2023,是一款由AdobeSystems开发和发行的图像处理软件。ps有很多功能,在图像文字视频等各方面都有涉及。Ps主要处理以像素所构成的数字图像。其众多的编修与绘图工具,连接不上无线AP的信号怎么办?使用无线终端连接无线AP信号时,如果能够搜索到无线信号,但是连接不上,请参考以下步骤排查问题1。确认无线名称和密码如果您连接别人的无线信号或者输入错误的无线密码,则会连不上信号。请狂飙中等离子电视有什么好?多年来业界流传着这样一句话外行买液晶,内行买等离子。其原因在于等离子电视除了在动态清晰度方面表现优异,在视觉舒适度色彩还原度对比度可视角度等方面的性能也较好。等离子电视的画面表现在一批小灵通引发的惨案,狂飙中都出现了哪些数码产品?前言电视剧狂飙近日迎来了大结局,本剧剧情跌宕起伏引人入胜,剧情时间线长达20年,将剧中人物形象塑造的淋漓尽致,由张译饰演的警官安欣与张颂文饰演的高启强斗智斗勇,展开了惊心动魄的战斗原装进口七座丰田海狮,全新曲屏智能电视,你确定不来看看Hallo,大家好,我是大耳朵图图!2023年新年伊始,给大家带来一款超大空间的蓝牌C照七座MPV车型它就是今天的主角进口丰田海狮七座版。对于这款车型相信大家应该不陌生了哈,今天这NAS下搭建超实用的文件快递柜FileCodeBox封面前言这个也是最近发现的新项目,原理和快递柜一摸一样,你可以将文件或者文字上传,上传后输入取件码,告诉别人后可以让另外一个人凭借取件码来取文件。可以是说文件的驿站了,今天便介绍一音频视频自动播放解决方案1音频视频自动播放解决方案1。1使用背景公司项目需要用到音频自动播放的功能,首先想到的就是autoplay属性。想让内容自动播放的最简单方法是将autoplay属性添加到元素,并将优步将苹果CarPlay集成到其面向司机的应用中IT之家2月11日消息,优步现宣布对其应用程序进行重大更新。简单来说就是,优步面向司机的App很快集成苹果AppleCarPlay,从而使得司机可以用iPhone连接到汽车。目前,