diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua index d7d5da43..775b4490 100644 --- a/apisix/cli/ngx_tpl.lua +++ b/apisix/cli/ngx_tpl.lua @@ -77,7 +77,7 @@ stream { lua_shared_dict plugin-limit-conn-stream {* stream.lua_shared_dict["plugin-limit-conn-stream"] *}; lua_shared_dict etcd-cluster-health-check-stream {* stream.lua_shared_dict["etcd-cluster-health-check-stream"] *}; - resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} {% if dns_resolver_valid then %} valid={*dns_resolver_valid*}{% end %}; + resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} {% if dns_resolver_valid then %} valid={*dns_resolver_valid*}{% end %} ipv6={% if enable_ipv6 then %}on{% else %}off{% end %}; resolver_timeout {*resolver_timeout*}; {% if ssl.ssl_trusted_certificate ~= nil then %} @@ -254,7 +254,7 @@ http { lua_socket_log_errors off; - resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} {% if dns_resolver_valid then %} valid={*dns_resolver_valid*}{% end %}; + resolver {% for _, dns_addr in ipairs(dns_resolver or {}) do %} {*dns_addr*} {% end %} {% if dns_resolver_valid then %} valid={*dns_resolver_valid*}{% end %} ipv6={% if enable_ipv6 then %}on{% else %}off{% end %}; resolver_timeout {*resolver_timeout*}; lua_http10_buffering off; diff --git a/apisix/core/dns/client.lua b/apisix/core/dns/client.lua index a6dbfb37..7d60aeef 100644 --- a/apisix/core/dns/client.lua +++ b/apisix/core/dns/client.lua @@ -15,6 +15,7 @@ -- limitations under the License. -- local require = require +local config_local = require("apisix.core.config_local") local log = require("apisix.core.log") local json = require("apisix.core.json") local table = require("apisix.core.table") @@ -22,6 +23,7 @@ local insert_tab = table.insert local math_random = math.random local package_loaded = package.loaded local ipairs = ipairs +local table_remove = table.remove local setmetatable = setmetatable @@ -130,7 +132,22 @@ end function _M.new(opts) - opts.ipv6 = true + local local_conf = config_local.local_conf() + + if opts.enable_ipv6 == nil then + opts.enable_ipv6 = local_conf.apisix.enable_ipv6 + end + + -- ensure the resolver throws an error when ipv6 is disabled + if not opts.enable_ipv6 then + for i, v in ipairs(opts.order) do + if v == "AAAA" then + table_remove(opts.order, i) + break + end + end + end + opts.timeout = 2000 -- 2 sec opts.retrans = 5 -- 5 retransmissions on receive timeout diff --git a/t/cli/test_dns.sh b/t/cli/test_dns.sh index 62985eac..38a2e9d1 100755 --- a/t/cli/test_dns.sh +++ b/t/cli/test_dns.sh @@ -34,7 +34,7 @@ apisix: make init -if ! grep "resolver 127.0.0.1 \[::1\]:5353 valid=30;" conf/nginx.conf > /dev/null; then +if ! grep "resolver 127.0.0.1 \[::1\]:5353 valid=30 ipv6=on;" conf/nginx.conf > /dev/null; then echo "failed: dns_resolver_valid doesn't take effect" exit 1 fi @@ -52,7 +52,7 @@ apisix: make init -count=$(grep -c "resolver 127.0.0.1 \[::1\]:5353 valid=30;" conf/nginx.conf) +count=$(grep -c "resolver 127.0.0.1 \[::1\]:5353 valid=30 ipv6=on;" conf/nginx.conf) if [ "$count" -ne 2 ]; then echo "failed: dns_resolver_valid doesn't take effect" exit 1 @@ -73,10 +73,26 @@ apisix: make init -count=$(grep -c "resolver 127.0.0.1 \[::1\] \[::2\];" conf/nginx.conf) +count=$(grep -c "resolver 127.0.0.1 \[::1\] \[::2\] ipv6=on;" conf/nginx.conf) if [ "$count" -ne 2 ]; then echo "failed: can't handle IPv6 resolver w/o bracket" exit 1 fi echo "pass: handle IPv6 resolver w/o bracket" + +# ipv6 config test +echo ' +apisix: + enable_ipv6: false + dns_resolver: + - 127.0.0.1 + dns_resolver_valid: 30 +' > conf/config.yaml + +make init + +if ! grep "resolver 127.0.0.1 valid=30 ipv6=off;" conf/nginx.conf > /dev/null; then + echo "failed: ipv6 config doesn't take effect" + exit 1 +fi diff --git a/t/core/utils.t b/t/core/utils.t index 9b406103..477b275c 100644 --- a/t/core/utils.t +++ b/t/core/utils.t @@ -322,3 +322,51 @@ GET /t --- error_log error: failed to query the DNS server --- timeout: 10 + + + +=== TEST 10: test dns config with ipv6 enable +--- yaml_config +apisix: + enable_ipv6: true +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local domain = "ipv6.local" + local ip_info, err = core.utils.dns_parse(domain) + if not ip_info then + core.log.error("failed to parse domain: ", domain, ", error: ",err) + return + end + ngx.say("ip_info: ", require("toolkit.json").encode(ip_info)) + } + } +--- request +GET /t +--- response_body +ip_info: {"address":"[::1]","class":1,"name":"ipv6.local","ttl":315360000,"type":28} + + + +=== TEST 11: test dns config with ipv6 disable +--- yaml_config +apisix: + enable_ipv6: false +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local domain = "ipv6.local" + local ip_info, err = core.utils.dns_parse(domain) + if not ip_info then + core.log.error("failed to parse domain: ", domain, ", error: ",err) + return + end + ngx.say("ip_info: ", require("toolkit.json").encode(ip_info)) + } + } +--- request +GET /t +--- error_log +failed to parse domain: ipv6.local diff --git a/utils/set-dns.sh b/utils/set-dns.sh index 2c7689df..021278fb 100755 --- a/utils/set-dns.sh +++ b/utils/set-dns.sh @@ -21,6 +21,7 @@ set -ex # test a domain name is configured as upstream echo "127.0.0.1 test.com" | sudo tee -a /etc/hosts +echo "::1 ipv6.local" | sudo tee -a /etc/hosts # test certificate verification echo "127.0.0.1 admin.apisix.dev" | sudo tee -a /etc/hosts cat /etc/hosts # check GitHub Action's configuration