记一次Nginx DNS缓存导致转发问题

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 记一次Nginx DNS缓存导致转发问题

前言

在家里搭建了一个GitLab 服务器,由于电信家庭宽带的公网 IP 是不固定的,且443端口是被封的,

所以买了阿里云作为中转,利用 Ngnix 作 TCP Proxy 结合 DDNS ,这样就能正常上自己的 Git 了。

但今天,我发现推代码怎么也推不上去,校对了密钥,服务器状态都没问题。最后上阿里云,重启了下 Nginx,发现可以了。

找了一圈原因,最后发现是 Nginx 转发缓存 DNS 解析导致的,下面就复现一下问题并找找为什么,以及解决方式。

复现问题

系统: CentOS 8.3.2011

Nginx : nginx/1.14.1

  1. 直接在默认配置中加上如下配置,其中本地的80端口跑的是 Nginx默认的服务:
stream {
    log_format basic '$remote_addr [$time_local] '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time "$upstream_addr"';
    access_log /var/logs/nginx/access2.log basic;
    server {
        listen 8080;
        proxy_pass test.razeen.cn:80;
    }
}

此时,test.razeen.cn并没有解析,直接启动nginx,会报错:

nignx: [emerg] host not found in upstream "test.razeen.cn" in /etc/nginx/nginx.conf:94

我添加解析。

image.png

再次启动,成功启动 nginx, 访问 8080 端口,页面成功展示,日志如下:

image.png

一切正常。

修改解析,解析到其他IP

image.png

600s后,无论再次访问,查看日志,还是转到了原来的 IP

image.png

重启 nginx, 再次访问,这是 IP 才变成后面修改的。

image.png

从这里可以看出,Nginx 在启动的时候就会去查询DNS记录,如果不存在解析,直接无法启动。 但,如果中间修改域名的 DNS解析,Nginx 中的解析并不会刷新。只有 reload or restart 后才会刷新。

那么实际是什么样的呢?

解析机制

直接去查找了一下相关的文章, 从这篇Using DNS for Service Discovery with NGINX and NGINX Plus 知道:

As NGINX starts up or reloads its configuration, it queries a DNS server to resolve backends.example.com. The DNS server returns the list of three backends discussed above, and NGINX uses the default Round Robin algorithm to load balance requests among them. NGINX chooses the DNS server from the OS configuration file /etc/resolv.conf.

This method is the least flexible way to do service discovery and has the following additional drawbacks:

  • If the domain name can’t be resolved, NGINX fails to start or reload its configuration.
  • NGINX caches the DNS records until the next restart or configuration reload, ignoring the records’ TTL values.
  • We can’t specify another load‑balancing algorithm, nor can we configure passive health checks or other features defined by parameters to the server directive, which we’ll describe in the next section.
  • Nginx 在启动/重载的时候回去解析转发的域名
  • 如果域名无法解析 Nginx 就无法启动
  • 只有下次重启/重载的时候才会重新去解析,启动后无视TTL

同时,如果能解析到多个 IP,还会有相应的负载均衡策略哦,后面可以再研究下这个。

这下就很明白了,原来坑就在这里,那么该怎么解决呢?

解决问题

在上面的文章中其实就给出了一种解决方案。

如下,可以指定 DNS 解析服务器并设置 DNS 刷新频率。

http {
    resolver 10.0.0.2 valid=10s;
    server {
        # resolver 10.0.0.2 valid=10s;  # 也可以写在这里
        location / {
            # resolver 10.0.0.2 valid=10s;   # 也可以写在这
            set $backend_servers backends.example.com;
            proxy_pass http://$backend_servers:8080;
        }
    }
}

上面,resolver就是 DNS 服务器的地址, validDNS 刷新的频率[1]。

但,上面这种写法只适合在 http proxy中,在stream proxy中并没有set关键字,如果这么写启动会直接报错。查阅一番后,如下写法是可行的:

stream {
    resolver 114.114.114.114 valid=10s;
    map $remote_addr $backend {
        default  test.razeen.cn;
    }
    server {
        listen 8080;
        # resolver 114.114.114.114 valid=10s;  # 也可以写在这里
        proxy_pass $backend:80;
    }
}

但经过验证,这个 validDNS 刷新频率还要取决于你resolver中使用的解析服务器。如果resolver不是无缓存的DNS服务器,解析生效就会受影响。

同时通过 官方文档 看到,在 stream proxyresolver 既可以写在 steam中,也可以写在server中:

| Syntax:  | **resolver** *address* ... [valid=*time*] [ipv6=on|off] [status_zone=*zone*]; | | -------- | -------------------------------------------------------------------------------- | | Default: | -                                                                                | | Context: | stream, server                                                               |

This directive appeared in version 1.11.3.

HTTP PRXOY, resolver可以写在http, server, location 中, set 可以写在serverlocation中。

同时上面这样写后,即使域名解析不到也不会导致 Nginx 启动/重启 失败。



目录
相关文章
|
3月前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
70 0
|
13天前
|
缓存 网络协议 安全
如何防止DNS缓存中毒(Ⅱ)
防止DNS缓存中毒的方法包括:减少DNS服务器与其它服务器的信任关系;限制DNS服务器上的服务;使用最新版DNS;加强用户安全教育,如识别可疑网站,仅访问HTTPS网站等。部署SSL证书并选择符合国际Webtrust标准的CA机构,可进一步提高安全性。
23 1
|
1月前
|
存储 缓存 监控
|
1月前
|
存储 缓存 负载均衡
Nginx代理缓存机制
【10月更文挑战第2天】
63 4
|
1月前
|
存储 缓存 NoSQL
Nginx缓存
Nginx缓存
27 2
|
13天前
|
存储 缓存 网络协议
如何防止DNS缓存中毒攻击(一)
DNS缓存中毒,即DNS欺骗,是一种通过利用DNS系统的漏洞,将用户流量从合法服务器导向虚假服务器的网络攻击。攻击者通过伪造DNS响应,使缓存服务器存储错误的IP地址,从而实现对合法URL的劫持。这不仅可能导致用户信息泄露,还可能使用户设备遭受恶意软件感染,对金融、医疗等关键领域造成严重影响。据统计,DNS攻击每年造成的平均损失高达223.6万美元,其中23%的攻击源自DNS缓存中毒。
37 0
|
2月前
|
存储 缓存 Java
在Spring Boot中使用缓存的技术解析
通过利用Spring Boot中的缓存支持,开发者可以轻松地实现高效和可扩展的缓存策略,进而提升应用的性能和用户体验。Spring Boot的声明式缓存抽象和对多种缓存技术的支持,使得集成和使用缓存变得前所未有的简单。无论是在开发新应用还是优化现有应用,合理地使用缓存都是提高性能的有效手段。
37 1
|
2月前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
65 8
|
1月前
|
应用服务中间件 测试技术 nginx
Nginx入门 -- 解析Nginx中的基本概念:Keepalive
Nginx入门 -- 解析Nginx中的基本概念:Keepalive
87 0
|
2月前
|
开发框架 安全 应用服务中间件
【文件上传绕过】——解析漏洞_IIS7.0 | IIS7.5 | Nginx的解析漏洞
【文件上传绕过】——解析漏洞_IIS7.0 | IIS7.5 | Nginx的解析漏洞
130 9

相关产品

  • 云解析DNS
  • 推荐镜像

    更多