diff --git a/.requirements b/.requirements index bbfa42c49801..6c393209ff55 100644 --- a/.requirements +++ b/.requirements @@ -17,4 +17,4 @@ APISIX_PACKAGE_NAME=apisix -APISIX_RUNTIME=1.2.0 +APISIX_RUNTIME=1.2.1 diff --git a/Makefile b/Makefile index 4c0ed68febbf..21a2389633b3 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ ENV_TAR ?= tar ENV_INSTALL ?= install ENV_RM ?= rm -vf ENV_DOCKER ?= docker -ENV_DOCKER_COMPOSE ?= docker-compose --project-directory $(CURDIR) -p $(project_name) -f $(project_compose_ci) +ENV_DOCKER_COMPOSE ?= docker compose --project-directory $(CURDIR) -p $(project_name) -f $(project_compose_ci) ENV_NGINX ?= $(ENV_NGINX_EXEC) -p $(CURDIR) -c $(CURDIR)/conf/nginx.conf ENV_NGINX_EXEC := $(shell command -v openresty 2>/dev/null || command -v nginx 2>/dev/null) ENV_OPENSSL_PREFIX ?= /usr/local/openresty/openssl3 @@ -251,7 +251,6 @@ install: runtime $(ENV_INSTALL) -d /usr/local/apisix/conf/cert $(ENV_INSTALL) conf/mime.types /usr/local/apisix/conf/mime.types $(ENV_INSTALL) conf/config.yaml /usr/local/apisix/conf/config.yaml - $(ENV_INSTALL) conf/config-default.yaml /usr/local/apisix/conf/config-default.yaml $(ENV_INSTALL) conf/debug.yaml /usr/local/apisix/conf/debug.yaml $(ENV_INSTALL) conf/cert/* /usr/local/apisix/conf/cert/ diff --git a/apisix/admin/resource.lua b/apisix/admin/resource.lua index b03f1b069ea6..2a87716027e1 100644 --- a/apisix/admin/resource.lua +++ b/apisix/admin/resource.lua @@ -254,6 +254,8 @@ function _M:put(id, conf, sub_path, args) if not ok then return 503, {error_msg = err} end + else + conf.id = id end local ttl = nil diff --git a/apisix/cli/config.lua b/apisix/cli/config.lua new file mode 100644 index 000000000000..94843621a74b --- /dev/null +++ b/apisix/cli/config.lua @@ -0,0 +1,364 @@ +-- +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- + +local table_conact = table.concat + +local _M = { + apisix = { + node_listen = { 9080 }, + enable_admin = true, + enable_dev_mode = false, + enable_reuseport = true, + show_upstream_status_in_response_header = false, + enable_ipv6 = true, + enable_http2 = true, + enable_server_tokens = true, + extra_lua_path = "", + extra_lua_cpath = "", + proxy_cache = { + cache_ttl = "10s", + zones = { + { + name = "disk_cache_one", + memory_size = "50m", + disk_size = "1G", + disk_path = "/tmp/disk_cache_one", + cache_levels = "1:2" + }, + { + name = "memory_cache", + memory_size = "50m" + } + } + }, + delete_uri_tail_slash = false, + normalize_uri_like_servlet = false, + router = { + http = "radixtree_host_uri", + ssl = "radixtree_sni" + }, + proxy_mode = "http", + resolver_timeout = 5, + enable_resolv_search_opt = true, + ssl = { + enable = true, + listen = { { + port = 9443, + enable_http3 = false + } }, + ssl_protocols = "TLSv1.2 TLSv1.3", + ssl_ciphers = table_conact({ + "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256", + "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", + "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", + "DHE-RSA-AES128-GCM-SHA256", "DHE-RSA-AES256-GCM-SHA384", + }, ":"), + ssl_session_tickets = false + }, + enable_control = true, + disable_sync_configuration_during_start = false, + data_encryption = { + enable_encrypt_fields = true, + keyring = { "qeddd145sfvddff3", "edd1c9f0985e76a2" } + }, + events = { + module = "lua-resty-events" + } + }, + nginx_config = { + error_log = "logs/error.log", + error_log_level = "warn", + worker_processes = "auto", + enable_cpu_affinity = false, + worker_rlimit_nofile = 20480, + worker_shutdown_timeout = "240s", + max_pending_timers = 16384, + max_running_timers = 4096, + event = { + worker_connections = 10620 + }, + meta = { + lua_shared_dict = { + ["prometheus-metrics"] = "15m" + } + }, + stream = { + enable_access_log = false, + access_log = "logs/access_stream.log", + -- luacheck: push max code line length 300 + access_log_format = "$remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time", + -- luacheck: pop + access_log_format_escape = "default", + lua_shared_dict = { + ["etcd-cluster-health-check-stream"] = "10m", + ["lrucache-lock-stream"] = "10m", + ["plugin-limit-conn-stream"] = "10m", + ["worker-events-stream"] = "10m", + ["tars-stream"] = "1m" + } + }, + main_configuration_snippet = "", + http_configuration_snippet = "", + http_server_configuration_snippet = "", + http_server_location_configuration_snippet = "", + http_admin_configuration_snippet = "", + http_end_configuration_snippet = "", + stream_configuration_snippet = "", + http = { + enable_access_log = true, + access_log = "logs/access.log", + access_log_buffer = 16384, + -- luacheck: push max code line length 300 + access_log_format = + '$remote_addr - $remote_user [$time_local] $http_host "$request" $status $body_bytes_sent $request_time "$http_referer" "$http_user_agent" $upstream_addr $upstream_status $upstream_response_time "$upstream_scheme://$upstream_host$upstream_uri"', + -- luacheck: pop + access_log_format_escape = "default", + keepalive_timeout = "60s", + client_header_timeout = "60s", + client_body_timeout = "60s", + client_max_body_size = 0, + send_timeout = "10s", + underscores_in_headers = "on", + real_ip_header = "X-Real-IP", + real_ip_recursive = "off", + real_ip_from = { "127.0.0.1", "unix:" }, + proxy_ssl_server_name = true, + upstream = { + keepalive = 320, + keepalive_requests = 1000, + keepalive_timeout = "60s" + }, + charset = "utf-8", + variables_hash_max_size = 2048, + lua_shared_dict = { + ["internal-status"] = "10m", + ["plugin-limit-req"] = "10m", + ["plugin-limit-count"] = "10m", + ["prometheus-metrics"] = "10m", + ["plugin-limit-conn"] = "10m", + ["upstream-healthcheck"] = "10m", + ["worker-events"] = "10m", + ["lrucache-lock"] = "10m", + ["balancer-ewma"] = "10m", + ["balancer-ewma-locks"] = "10m", + ["balancer-ewma-last-touched-at"] = "10m", + ["plugin-limit-req-redis-cluster-slot-lock"] = "1m", + ["plugin-limit-count-redis-cluster-slot-lock"] = "1m", + ["plugin-limit-conn-redis-cluster-slot-lock"] = "1m", + tracing_buffer = "10m", + ["plugin-api-breaker"] = "10m", + ["etcd-cluster-health-check"] = "10m", + discovery = "1m", + jwks = "1m", + introspection = "10m", + ["access-tokens"] = "1m", + ["ext-plugin"] = "1m", + tars = "1m", + ["cas-auth"] = "10m", + ["ocsp-stapling"] = "10m" + } + } + }, + graphql = { + max_size = 1048576 + }, + plugins = { + "real-ip", + "ai", + "client-control", + "proxy-control", + "request-id", + "zipkin", + "ext-plugin-pre-req", + "fault-injection", + "mocking", + "serverless-pre-function", + "cors", + "ip-restriction", + "ua-restriction", + "referer-restriction", + "csrf", + "uri-blocker", + "request-validation", + "chaitin-waf", + "multi-auth", + "openid-connect", + "cas-auth", + "authz-casbin", + "authz-casdoor", + "wolf-rbac", + "ldap-auth", + "hmac-auth", + "basic-auth", + "jwt-auth", + "jwe-decrypt", + "key-auth", + "consumer-restriction", + "forward-auth", + "opa", + "authz-keycloak", + "proxy-cache", + "body-transformer", + "proxy-mirror", + "proxy-rewrite", + "workflow", + "api-breaker", + "limit-conn", + "limit-count", + "limit-req", + "gzip", + "server-info", + "traffic-split", + "redirect", + "response-rewrite", + "degraphql", + "kafka-proxy", + "grpc-transcode", + "grpc-web", + "http-dubbo", + "public-api", + "prometheus", + "datadog", + "loki-logger", + "elasticsearch-logger", + "echo", + "loggly", + "http-logger", + "splunk-hec-logging", + "skywalking-logger", + "google-cloud-logging", + "sls-logger", + "tcp-logger", + "kafka-logger", + "rocketmq-logger", + "syslog", + "udp-logger", + "file-logger", + "clickhouse-logger", + "tencent-cloud-cls", + "inspect", + "example-plugin", + "aws-lambda", + "azure-functions", + "openwhisk", + "openfunction", + "serverless-post-function", + "ext-plugin-post-req", + "ext-plugin-post-resp", + }, + stream_plugins = { "ip-restriction", "limit-conn", "mqtt-proxy", "syslog" }, + plugin_attr = { + ["log-rotate"] = { + timeout = 10000, + interval = 3600, + max_kept = 168, + max_size = -1, + enable_compression = false + }, + skywalking = { + service_name = "APISIX", + service_instance_name = "APISIX Instance Name", + endpoint_addr = "http://127.0.0.1:12800", + report_interval = 3 + }, + opentelemetry = { + trace_id_source = "x-request-id", + resource = { + ["service.name"] = "APISIX" + }, + collector = { + address = "127.0.0.1:4318", + request_timeout = 3, + request_headers = { + Authorization = "token" + } + }, + batch_span_processor = { + drop_on_queue_full = false, + max_queue_size = 1024, + batch_timeout = 2, + inactive_timeout = 1, + max_export_batch_size = tonumber(os.getenv("OTEL_BSP_MAX_EXPORT_BATCH_SIZE")) or 16 + }, + set_ngx_var = false + }, + prometheus = { + export_uri = "/apisix/prometheus/metrics", + metric_prefix = "apisix_", + enable_export_server = true, + export_addr = { + ip = "127.0.0.1", + port = 9091 + } + }, + ["server-info"] = { + report_ttl = 60 + }, + ["dubbo-proxy"] = { + upstream_multiplex_count = 32 + }, + ["proxy-mirror"] = { + timeout = { + connect = "60s", + read = "60s", + send = "60s" + } + }, + inspect = { + delay = 3, + hooks_file = "/usr/local/apisix/plugin_inspect_hooks.lua" + }, + zipkin = { + set_ngx_var = false + } + }, + deployment = { + role = "traditional", + role_traditional = { + config_provider = "etcd" + }, + admin = { + admin_key_required = true, + admin_key = { + { + name = "admin", + key = "", + role = "admin" + } + }, + enable_admin_cors = true, + allow_admin = { "127.0.0.0/24" }, + admin_listen = { + ip = "0.0.0.0", + port = 9180 + }, + admin_api_version = "v3" + }, + etcd = { + host = { "http://127.0.0.1:2379" }, + prefix = "/apisix", + timeout = 30, + watch_timeout = 50, + startup_retry = 2, + tls = { + verify = true + } + } + } +} + +return _M diff --git a/apisix/cli/file.lua b/apisix/cli/file.lua index c01736d16180..86cdd7b8566b 100644 --- a/apisix/cli/file.lua +++ b/apisix/cli/file.lua @@ -18,6 +18,7 @@ local yaml = require("lyaml") local profile = require("apisix.core.profile") local util = require("apisix.cli.util") +local default_conf = require("apisix.cli.config") local dkjson = require("dkjson") local pairs = pairs @@ -228,18 +229,7 @@ function _M.read_yaml_conf(apisix_home) profile.apisix_home = apisix_home .. "/" end - local local_conf_path = profile:yaml_path("config-default") - local default_conf_yaml, err = util.read_file(local_conf_path) - if not default_conf_yaml then - return nil, err - end - - local default_conf = yaml.load(default_conf_yaml) - if not default_conf then - return nil, "invalid config-default.yaml file" - end - - local_conf_path = profile:customized_yaml_path() + local local_conf_path = profile:customized_yaml_path() if not local_conf_path then local_conf_path = profile:yaml_path("config") end diff --git a/apisix/core/config_etcd.lua b/apisix/core/config_etcd.lua index 90f9b6f16b8c..6e06a368f25d 100644 --- a/apisix/core/config_etcd.lua +++ b/apisix/core/config_etcd.lua @@ -671,13 +671,13 @@ local function sync_data(self) log.error("failed to check item data of [", self.key, "] err:", err, " ,val: ", json.encode(res.value)) end + end - if data_valid and self.checker then - data_valid, err = self.checker(res.value) - if not data_valid then - log.error("failed to check item data of [", self.key, - "] err:", err, " ,val: ", json.delay_encode(res.value)) - end + if data_valid and res.value and self.checker then + data_valid, err = self.checker(res.value) + if not data_valid then + log.error("failed to check item data of [", self.key, + "] err:", err, " ,val: ", json.delay_encode(res.value)) end end diff --git a/apisix/core/grpc.lua b/apisix/core/grpc.lua deleted file mode 100644 index 9cf7d747a667..000000000000 --- a/apisix/core/grpc.lua +++ /dev/null @@ -1,27 +0,0 @@ --- --- Licensed to the Apache Software Foundation (ASF) under one or more --- contributor license agreements. See the NOTICE file distributed with --- this work for additional information regarding copyright ownership. --- The ASF licenses this file to You under the Apache License, Version 2.0 --- (the "License"); you may not use this file except in compliance with --- the License. You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- -local pcall = pcall - -local ok, mod = pcall(require, "resty.grpc") -if not ok then - -- vanilla OpenResty doesn't have grpc-client-nginx-module - return nil -end - --- Reimport the `resty.grpc` as `core.grpc`. For the doc of the gRPC API, --- see https://github.com/api7/grpc-client-nginx-module -return mod diff --git a/apisix/core/utils.lua b/apisix/core/utils.lua index adca3d856d8c..cfea756542bd 100644 --- a/apisix/core/utils.lua +++ b/apisix/core/utils.lua @@ -36,6 +36,8 @@ local str_byte = string.byte local tonumber = tonumber local tostring = tostring local re_gsub = ngx.re.gsub +local re_match = ngx.re.match +local re_gmatch = ngx.re.gmatch local type = type local io_popen = io.popen local C = ffi.C @@ -43,6 +45,7 @@ local ffi_string = ffi.string local get_string_buf = base.get_string_buf local exiting = ngx.worker.exiting local ngx_sleep = ngx.sleep +local ipairs = ipairs local hostname local dns_resolvers @@ -378,4 +381,85 @@ end _M.resolve_var_with_captures = resolve_var_with_captures +-- if `str` is a string containing period `some_plugin.some_field.nested_field` +-- return the table that contains `nested_field` in its root level +-- else return the original table `conf` +local function get_root_conf(str, conf, field) + -- if the string contains periods, get the splits in `it` iterator + local it, _ = re_gmatch(str, [[([^\.]+)]]) + if not it then + return conf, field + end + + -- add the splits into a table + local matches = {} + while true do + local m, _ = it() + if not m then + break + end + table.insert(matches, m[0]) + end + + -- get to the table that holds the last field + local num_of_matches = #matches + for i = 1, num_of_matches - 1 , 1 do + conf = conf[matches[i]] + end + + -- return the table and the last field + return conf, matches[num_of_matches] +end + + +local function find_and_log(field, plugin_name, value) + local match, err = re_match(value, "^https") + if not match and not err then + log.warn("Using ", plugin_name, " " , field, " with no TLS is a security risk") + end +end + + +function _M.check_https(fields, conf, plugin_name) + for _, field in ipairs(fields) do + + local new_conf, new_field = get_root_conf(field, conf) + if not new_conf then + return + end + + local value = new_conf[new_field] + if not value then + return + end + + if type(value) == "table" then + for _, v in ipairs(value) do + find_and_log(field, plugin_name, v) + end + else + find_and_log(field, plugin_name, value) + end + end +end + + +function _M.check_tls_bool(fields, conf, plugin_name) + for i, field in ipairs(fields) do + + local new_conf, new_field = get_root_conf(field, conf) + if not new_conf then + return + end + + local value = new_conf[new_field] + + if value ~= true and value ~= nil then + log.warn("Keeping ", field, " disabled in ", + plugin_name, " configuration is a security risk") + end + end +end + + return _M diff --git a/apisix/init.lua b/apisix/init.lua index 0391ddd62787..103a8c1d7584 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -113,13 +113,6 @@ function _M.http_init_worker() -- for testing only core.log.info("random test in [1, 10000]: ", math.random(1, 10000)) - -- Because go's scheduler doesn't work after fork, we have to load the gRPC module - -- in each worker. - core.grpc = require("apisix.core.grpc") - if type(core.grpc) ~= "table" then - core.grpc = nil - end - require("apisix.events").init_worker() local discovery = require("apisix.discovery.init").discovery diff --git a/apisix/plugin.lua b/apisix/plugin.lua index cabcda176535..3d3c4b39be60 100644 --- a/apisix/plugin.lua +++ b/apisix/plugin.lua @@ -1041,7 +1041,7 @@ check_plugin_metadata = function(item) local ok, err = check_single_plugin_schema(item.id, item, core.schema.TYPE_METADATA, true) if ok and enable_gde() then - decrypt_conf(item.name, item, core.schema.TYPE_METADATA) + decrypt_conf(item.id, item, core.schema.TYPE_METADATA) end return ok, err diff --git a/apisix/plugins/authz-casdoor.lua b/apisix/plugins/authz-casdoor.lua index 4ed1c92b924e..c496ab6b1b45 100644 --- a/apisix/plugins/authz-casdoor.lua +++ b/apisix/plugins/authz-casdoor.lua @@ -85,6 +85,8 @@ end function _M.check_schema(conf) + local check = {"endpoint_addr", "callback_url"} + core.utils.check_https(check, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/authz-keycloak.lua b/apisix/plugins/authz-keycloak.lua index 587628f74bd4..34a0533326f9 100644 --- a/apisix/plugins/authz-keycloak.lua +++ b/apisix/plugins/authz-keycloak.lua @@ -114,6 +114,11 @@ local _M = { function _M.check_schema(conf) + local check = {"discovery", "token_endpoint", "resource_registration_endpoint", + "access_denied_redirect_uri"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"ssl_verify"}, conf, plugin_name) + return core.schema.check(schema, conf) end diff --git a/apisix/plugins/cas-auth.lua b/apisix/plugins/cas-auth.lua index 2a3e5049c446..d949636f5c75 100644 --- a/apisix/plugins/cas-auth.lua +++ b/apisix/plugins/cas-auth.lua @@ -49,6 +49,8 @@ local _M = { } function _M.check_schema(conf) + local check = {"idp_uri"} + core.utils.check_https(check, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/clickhouse-logger.lua b/apisix/plugins/clickhouse-logger.lua index b2e656797362..793a8d462ec9 100644 --- a/apisix/plugins/clickhouse-logger.lua +++ b/apisix/plugins/clickhouse-logger.lua @@ -89,6 +89,10 @@ function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_METADATA then return core.schema.check(metadata_schema, conf) end + local check = {"endpoint_addrs"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"ssl_verify"}, conf, plugin_name) + return core.schema.check(schema, conf) end diff --git a/apisix/plugins/elasticsearch-logger.lua b/apisix/plugins/elasticsearch-logger.lua index 38bc884ed53c..2b126c434b3e 100644 --- a/apisix/plugins/elasticsearch-logger.lua +++ b/apisix/plugins/elasticsearch-logger.lua @@ -124,6 +124,10 @@ function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_METADATA then return core.schema.check(metadata_schema, conf) end + local check = {"endpoint_addrs"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"ssl_verify"}, conf, plugin_name) + return core.schema.check(schema, conf) end diff --git a/apisix/plugins/error-log-logger.lua b/apisix/plugins/error-log-logger.lua index 5d5c5d2a9f8b..88eca65ca04e 100644 --- a/apisix/plugins/error-log-logger.lua +++ b/apisix/plugins/error-log-logger.lua @@ -187,6 +187,11 @@ function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_METADATA then return core.schema.check(metadata_schema, conf) end + + local check = {"skywalking.endpoint_addr", "clickhouse.endpoint_addr"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"tcp.tls"}, conf, plugin_name) + return core.schema.check(schema, conf) end diff --git a/apisix/plugins/forward-auth.lua b/apisix/plugins/forward-auth.lua index 95f04994c6b7..c7559324667d 100644 --- a/apisix/plugins/forward-auth.lua +++ b/apisix/plugins/forward-auth.lua @@ -78,6 +78,10 @@ local _M = { function _M.check_schema(conf) + local check = {"uri"} + core.utils.check_https(check, conf, _M.name) + core.utils.check_tls_bool({"ssl_verify"}, conf, _M.name) + return core.schema.check(schema, conf) end diff --git a/apisix/plugins/grpc-transcode.lua b/apisix/plugins/grpc-transcode.lua index a89008d39790..625018fb71fc 100644 --- a/apisix/plugins/grpc-transcode.lua +++ b/apisix/plugins/grpc-transcode.lua @@ -27,11 +27,11 @@ local plugin_name = "grpc-transcode" local pb_option_def = { { description = "enum as result", type = "string", - enum = {"int64_as_number", "int64_as_string", "int64_as_hexstring"}, + enum = {"enum_as_name", "enum_as_value"}, }, { description = "int64 as result", type = "string", - enum = {"enum_as_name", "enum_as_value"}, + enum = {"int64_as_number", "int64_as_string", "int64_as_hexstring"}, }, { description ="default values option", type = "string", diff --git a/apisix/plugins/http-logger.lua b/apisix/plugins/http-logger.lua index 9da5373d371e..44f84acc907d 100644 --- a/apisix/plugins/http-logger.lua +++ b/apisix/plugins/http-logger.lua @@ -82,6 +82,10 @@ function _M.check_schema(conf, schema_type) return core.schema.check(metadata_schema, conf) end + local check = {"uri"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"ssl_verify"}, conf, plugin_name) + local ok, err = core.schema.check(schema, conf) if not ok then return nil, err diff --git a/apisix/plugins/ldap-auth.lua b/apisix/plugins/ldap-auth.lua index 11f205c6b8f5..592d2d5fff9b 100644 --- a/apisix/plugins/ldap-auth.lua +++ b/apisix/plugins/ldap-auth.lua @@ -59,6 +59,7 @@ function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_CONSUMER then ok, err = core.schema.check(consumer_schema, conf) else + core.utils.check_tls_bool({"use_tls", "tls_verify"}, conf, plugin_name) ok, err = core.schema.check(schema, conf) end diff --git a/apisix/plugins/loki-logger.lua b/apisix/plugins/loki-logger.lua index e4c834e30e9a..59cb4da820e3 100644 --- a/apisix/plugins/loki-logger.lua +++ b/apisix/plugins/loki-logger.lua @@ -125,6 +125,10 @@ function _M.check_schema(conf, schema_type) return core.schema.check(metadata_schema, conf) end + local check = {"endpoint_addrs"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"ssl_verify"}, conf, plugin_name) + local ok, err = core.schema.check(schema, conf) if not ok then return nil, err diff --git a/apisix/plugins/opa.lua b/apisix/plugins/opa.lua index 24bdb5be1a46..0475529f0c17 100644 --- a/apisix/plugins/opa.lua +++ b/apisix/plugins/opa.lua @@ -65,6 +65,9 @@ local _M = { function _M.check_schema(conf) + local check = {"host"} + core.utils.check_https(check, conf, _M.name) + core.utils.check_tls_bool({"ssl_verify"}, conf, _M.name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua index db8d01bfbb8d..c4388abbfc6c 100644 --- a/apisix/plugins/openid-connect.lua +++ b/apisix/plugins/openid-connect.lua @@ -305,6 +305,11 @@ function _M.check_schema(conf) } end + local check = {"discovery", "introspection_endpoint", "redirect_uri", + "post_logout_redirect_uri", "proxy_opts.http_proxy", "proxy_opts.https_proxy"} + core.utils.check_https(check, conf, plugin_name) + core.utils.check_tls_bool({"ssl_verify"}, conf, plugin_name) + local ok, err = core.schema.check(schema, conf) if not ok then return false, err diff --git a/apisix/plugins/opentelemetry.lua b/apisix/plugins/opentelemetry.lua index aac18897c0b1..60f05fc17ac6 100644 --- a/apisix/plugins/opentelemetry.lua +++ b/apisix/plugins/opentelemetry.lua @@ -219,6 +219,8 @@ function _M.init() hostname = core.utils.gethostname() plugin_info = plugin.plugin_attr(plugin_name) or {} + local check = {"collector.address"} + core.utils.check_https(check, plugin_info, plugin_name) local ok, err = core.schema.check(attr_schema, plugin_info) if not ok then core.log.error("failed to check the plugin_attr[", plugin_name, "]", diff --git a/apisix/plugins/openwhisk.lua b/apisix/plugins/openwhisk.lua index 718513adcb2f..f1399254c0aa 100644 --- a/apisix/plugins/openwhisk.lua +++ b/apisix/plugins/openwhisk.lua @@ -63,6 +63,10 @@ local _M = { function _M.check_schema(conf) + local check = {"api_host"} + core.utils.check_https(check, conf, _M.name) + core.utils.check_tls_bool({"ssl_verify"}, conf, _M.name) + local ok, err = core.schema.check(schema, conf) if not ok then return false, err diff --git a/apisix/plugins/rocketmq-logger.lua b/apisix/plugins/rocketmq-logger.lua index 3cefa7fbbea3..2f0cd5b4ba59 100644 --- a/apisix/plugins/rocketmq-logger.lua +++ b/apisix/plugins/rocketmq-logger.lua @@ -99,6 +99,7 @@ function _M.check_schema(conf, schema_type) if not ok then return nil, err end + core.utils.check_tls_bool({"use_tls"}, conf, plugin_name) return log_util.check_log_schema(conf) end diff --git a/apisix/plugins/skywalking-logger.lua b/apisix/plugins/skywalking-logger.lua index 94ba65534a4c..8a7e309cdabb 100644 --- a/apisix/plugins/skywalking-logger.lua +++ b/apisix/plugins/skywalking-logger.lua @@ -82,6 +82,8 @@ function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_METADATA then return core.schema.check(metadata_schema, conf) end + local check = {"endpoint_addr"} + core.utils.check_https(check, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/skywalking.lua b/apisix/plugins/skywalking.lua index de170487e0f9..2ef435bcce4a 100644 --- a/apisix/plugins/skywalking.lua +++ b/apisix/plugins/skywalking.lua @@ -71,6 +71,8 @@ local _M = { function _M.check_schema(conf) + local check = {"endpoint_addr"} + core.utils.check_https(check, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/sls-logger.lua b/apisix/plugins/sls-logger.lua index 114a209690e5..819f0841bfb2 100644 --- a/apisix/plugins/sls-logger.lua +++ b/apisix/plugins/sls-logger.lua @@ -61,15 +61,28 @@ local schema = { required = {"host", "port", "project", "logstore", "access_key_id", "access_key_secret"} } +local metadata_schema = { + type = "object", + properties = { + log_format = { + type = "object" + } + }, +} + local _M = { version = 0.1, priority = 406, name = plugin_name, schema = batch_processor_manager:wrap_schema(schema), + metadata_schema = metadata_schema, } -function _M.check_schema(conf) - return core.schema.check(schema, conf) +function _M.check_schema(conf,schema_type) + if schema_type == core.schema.TYPE_METADATA then + return core.schema.check(metadata_schema, conf) + end + return core.schema.check(schema, conf) end local function send_tcp_data(route_conf, log_message) diff --git a/apisix/plugins/syslog.lua b/apisix/plugins/syslog.lua index fa160feeb45d..1f35395305f4 100644 --- a/apisix/plugins/syslog.lua +++ b/apisix/plugins/syslog.lua @@ -80,6 +80,7 @@ function _M.check_schema(conf, schema_type) if schema_type == core.schema.TYPE_METADATA then return core.schema.check(metadata_schema, conf) end + core.utils.check_tls_bool({"tls"}, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/tcp-logger.lua b/apisix/plugins/tcp-logger.lua index e95ba9339e95..7482fe515dee 100644 --- a/apisix/plugins/tcp-logger.lua +++ b/apisix/plugins/tcp-logger.lua @@ -76,6 +76,7 @@ function _M.check_schema(conf, schema_type) return core.schema.check(metadata_schema, conf) end + core.utils.check_tls_bool({"tls"}, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/plugins/wolf-rbac.lua b/apisix/plugins/wolf-rbac.lua index 154fde41a4ad..22a90c2f5f90 100644 --- a/apisix/plugins/wolf-rbac.lua +++ b/apisix/plugins/wolf-rbac.lua @@ -141,6 +141,8 @@ end function _M.check_schema(conf) + local check = {"server"} + core.utils.check_https(check, conf, plugin_name) core.log.info("input conf: ", core.json.delay_encode(conf)) local ok, err = core.schema.check(schema, conf) diff --git a/apisix/plugins/zipkin.lua b/apisix/plugins/zipkin.lua index 0b9efa8f2732..dc814f1bc534 100644 --- a/apisix/plugins/zipkin.lua +++ b/apisix/plugins/zipkin.lua @@ -70,6 +70,8 @@ local _M = { function _M.check_schema(conf) + local check = {"endpoint"} + core.utils.check_https(check, conf, plugin_name) return core.schema.check(schema, conf) end diff --git a/apisix/ssl.lua b/apisix/ssl.lua index ad820822c06e..412c9b86bc90 100644 --- a/apisix/ssl.lua +++ b/apisix/ssl.lua @@ -29,6 +29,7 @@ local str_byte = string.byte local assert = assert local type = type local ipairs = ipairs +local ngx_sub = ngx.re.sub ffi.cdef[[ unsigned long ERR_peek_error(void); @@ -66,6 +67,7 @@ function _M.server_name(clienthello) end end + sni = ngx_sub(sni, "\\.$", "", "jo") sni = str_lower(sni) return sni end diff --git a/apisix/ssl/router/radixtree_sni.lua b/apisix/ssl/router/radixtree_sni.lua index aab6aafe8819..caa69194e8a2 100644 --- a/apisix/ssl/router/radixtree_sni.lua +++ b/apisix/ssl/router/radixtree_sni.lua @@ -285,9 +285,11 @@ local function ssl_filter(ssl) end if ssl.value.sni then + ssl.value.sni = ngx.re.sub(ssl.value.sni, "\\.$", "", "jo") ssl.value.sni = str_lower(ssl.value.sni) elseif ssl.value.snis then for i, v in ipairs(ssl.value.snis) do + v = ngx.re.sub(v, "\\.$", "", "jo") ssl.value.snis[i] = str_lower(v) end end diff --git a/ci/init-last-test-service.sh b/ci/init-last-test-service.sh index 5c3feeec7bcc..694349056f55 100755 --- a/ci/init-last-test-service.sh +++ b/ci/init-last-test-service.sh @@ -22,14 +22,14 @@ before() { } after() { - docker exec -i apache-apisix_kafka-server1_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 1 --topic test2 - docker exec -i apache-apisix_kafka-server1_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 3 --topic test3 - docker exec -i apache-apisix_kafka-server2_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server2:2181 --replication-factor 1 --partitions 1 --topic test4 - docker exec -i apache-apisix_kafka-server1_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 1 --topic test-consumer + docker exec -i apache-apisix-kafka-server1-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 1 --topic test2 + docker exec -i apache-apisix-kafka-server1-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 3 --topic test3 + docker exec -i apache-apisix-kafka-server2-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server2:2181 --replication-factor 1 --partitions 1 --topic test4 + docker exec -i apache-apisix-kafka-server1-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 1 --topic test-consumer # create messages for test-consumer for i in `seq 30` do - docker exec -i apache-apisix_kafka-server1_1 bash -c "echo "testmsg$i" | /opt/bitnami/kafka/bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --topic test-consumer" + docker exec -i apache-apisix-kafka-server1-1 bash -c "echo "testmsg$i" | /opt/bitnami/kafka/bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 --topic test-consumer" echo "Produces messages to the test-consumer topic, msg: testmsg$i" done echo "Kafka service initialization completed" diff --git a/ci/init-plugin-test-service.sh b/ci/init-plugin-test-service.sh index aa0ccf19021a..400465bf1627 100755 --- a/ci/init-plugin-test-service.sh +++ b/ci/init-plugin-test-service.sh @@ -17,9 +17,9 @@ # after() { - docker exec -i apache-apisix_kafka-server1_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 1 --topic test2 - docker exec -i apache-apisix_kafka-server1_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 3 --topic test3 - docker exec -i apache-apisix_kafka-server2_1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server2:2181 --replication-factor 1 --partitions 1 --topic test4 + docker exec -i apache-apisix-kafka-server1-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 1 --topic test2 + docker exec -i apache-apisix-kafka-server1-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server1:2181 --replication-factor 1 --partitions 3 --topic test3 + docker exec -i apache-apisix-kafka-server2-1 /opt/bitnami/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper-server2:2181 --replication-factor 1 --partitions 1 --topic test4 # prepare openwhisk env docker pull openwhisk/action-nodejs-v14:1.20.0 diff --git a/conf/config-default.yaml b/conf/config.yaml.example old mode 100755 new mode 100644 similarity index 99% rename from conf/config-default.yaml rename to conf/config.yaml.example index 225f41dbb116..5a490a4bb4b3 --- a/conf/config-default.yaml +++ b/conf/config.yaml.example @@ -647,10 +647,10 @@ deployment: # Deployment configurations name: admin # admin: write access to configurations. key: '' # Set API key for the admin of Admin API. role: admin - - - name: viewer # viewer: read-only to configurations. - key: 4054f7cf07e344346cd3f287985e76a2 # Set API key for the viewer of Admin API. - role: viewer + # - + # name: viewer # viewer: read-only to configurations. + # key: 4054f7cf07e344346cd3f287985e76a2 # Set API key for the viewer of Admin API. + # role: viewer enable_admin_cors: true # Enable Admin API CORS response header `Access-Control-Allow-Origin`. allow_admin: # Limit Admin API access by IP addresses. diff --git a/docs/en/latest/plugins/basic-auth.md b/docs/en/latest/plugins/basic-auth.md index 5073cff95cc5..a25df3a2196d 100644 --- a/docs/en/latest/plugins/basic-auth.md +++ b/docs/en/latest/plugins/basic-auth.md @@ -136,7 +136,7 @@ HTTP/1.1 401 Unauthorized ## Delete Plugin -To remove the `jwt-auth` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. +To remove the `basic-auth` Plugin, you can delete the corresponding JSON configuration from the Plugin configuration. APISIX will automatically reload and you do not have to restart for this to take effect. ```shell curl http://127.0.0.1:9180/apisix/admin/routes/1 -H "X-API-KEY: $admin_key" -X PUT -d ' diff --git a/docs/en/latest/plugins/body-transformer.md b/docs/en/latest/plugins/body-transformer.md index 15df4dbc456d..dc1b78632746 100644 --- a/docs/en/latest/plugins/body-transformer.md +++ b/docs/en/latest/plugins/body-transformer.md @@ -138,6 +138,7 @@ curl http://127.0.0.1:9180/apisix/admin/routes/test_ws \ "plugins": { "body-transformer": { "request": { + "template_is_base64": true, "template": "'"$(base64 -w0 /path/to/my_template_file)"'" } } diff --git a/docs/en/latest/plugins/opentelemetry.md b/docs/en/latest/plugins/opentelemetry.md index 9a0ed137350a..09a17a82da07 100644 --- a/docs/en/latest/plugins/opentelemetry.md +++ b/docs/en/latest/plugins/opentelemetry.md @@ -74,7 +74,7 @@ For instance, a possible scenario occurs when the plugin attribute `trace_id_sou ::: -You can configure these as shown below: +You can configure these as shown below in your configuration file (`conf/config.yaml`): ```yaml title="conf/config.yaml" plugin_attr: @@ -105,7 +105,7 @@ The following nginx variables are set by OpenTelemetry: How to use variables? you have to add it to your configuration file (`conf/config.yaml`): -```yaml title="./conf/config.yaml" +```yaml title="conf/config.yaml" http: enable_access_log: true access_log: "/dev/stdout" diff --git a/docs/en/latest/plugins/prometheus.md b/docs/en/latest/plugins/prometheus.md index 2db3e1a84044..01301c284e97 100644 --- a/docs/en/latest/plugins/prometheus.md +++ b/docs/en/latest/plugins/prometheus.md @@ -96,9 +96,9 @@ plugin_attr: - 505 ``` -## API +## Metrics endpoint -This Plugin will add the API endpoint `/apisix/prometheus/metrics` or your custom export URI for exposing the metrics. +This Plugin will add the metrics endpoint `/apisix/prometheus/metrics` or your custom export URI for exposing the metrics. These metrics are exposed by a separate Prometheus server address. By default, the address is `127.0.0.1:9091`. You can change it in your configuration file (`conf/config.yaml`): diff --git a/docs/zh/latest/plugins/forward-auth.md b/docs/zh/latest/plugins/forward-auth.md index c5aa64241acc..a030a6f8faf0 100644 --- a/docs/zh/latest/plugins/forward-auth.md +++ b/docs/zh/latest/plugins/forward-auth.md @@ -48,7 +48,7 @@ description: 本文介绍了关于 Apache APISIX `forward-auth` 插件的基本 | keepalive_timeout | integer | 否 | 60000ms | [1000, ...]ms | 长连接超时时间。 | | keepalive_pool | integer | 否 | 5 | [1, ...]ms | 长连接池大小。 | | allow_degradation | boolean | 否 | false | | 当设置为 `true` 时,允许在身份验证服务器不可用时跳过身份验证。 | -| status_on_error | boolean | 否 | 403 | [200,...,599] | 设置授权服务出现网络错误时返回给客户端的 HTTP 状态。默认状态为“403”。 | +| status_on_error | integer | 否 | 403 | [200,...,599] | 设置授权服务出现网络错误时返回给客户端的 HTTP 状态。默认状态为“403”。 | ## 数据定义 diff --git a/t/APISIX.pm b/t/APISIX.pm index 698326b4a8b2..50f7cfaecab6 100644 --- a/t/APISIX.pm +++ b/t/APISIX.pm @@ -79,11 +79,14 @@ if ($custom_dns_server) { my $events_module = $ENV{TEST_EVENTS_MODULE} // "lua-resty-events"; -my $default_yaml_config = read_file("conf/config-default.yaml"); -# enable example-plugin as some tests require it -$default_yaml_config =~ s/#- example-plugin/- example-plugin/; -$default_yaml_config =~ s/enable_export_server: true/enable_export_server: false/; -$default_yaml_config =~ s/module: lua-resty-events/module: $events_module/; +my $test_default_config = <<_EOC_; + -- read the default configuration, modify it, and the Lua package + -- cache will persist it for loading by other entrypoints + -- it is used to replace the test::nginx implementation + local default_config = require("apisix.cli.config") + default_config.plugin_attr.prometheus.enable_export_server = false + default_config.apisix.events.module = "$events_module" +_EOC_ my $user_yaml_config = read_file("conf/config.yaml"); my $ssl_crt = read_file("t/certs/apisix.crt"); @@ -429,6 +432,7 @@ _EOC_ $stream_config .= <<_EOC_; init_by_lua_block { + $test_default_config $stream_init_by_lua_block $stream_extra_init_by_lua } @@ -621,6 +625,7 @@ _EOC_ $dubbo_upstream init_by_lua_block { + $test_default_config $init_by_lua_block } @@ -912,8 +917,6 @@ _EOC_ $user_files .= <<_EOC_; >>> ../conf/$debug_file $user_debug_config ->>> ../conf/config-default.yaml -$default_yaml_config >>> ../conf/$config_file $yaml_config >>> ../conf/cert/apisix.crt diff --git a/t/admin/plugin-metadata.t b/t/admin/plugin-metadata.t index ac97907f4fe6..e78ee00e8cc0 100644 --- a/t/admin/plugin-metadata.t +++ b/t/admin/plugin-metadata.t @@ -274,7 +274,7 @@ qr/\{"error_msg":"invalid configuration: property \\"ikey\\" is required"\}/ } } --- response_body -{"key":"/apisix/plugin_metadata/example-plugin","value":{"ikey":1,"skey":"val"}} +{"key":"/apisix/plugin_metadata/example-plugin","value":{"id":"example-plugin","ikey":1,"skey":"val"}} --- request GET /t @@ -305,7 +305,7 @@ GET /t } } --- response_body -{"key":"/apisix/plugin_metadata/example-plugin","value":{"ikey":1,"skey":"val"}} +{"key":"/apisix/plugin_metadata/example-plugin","value":{"id":"example-plugin","ikey":1,"skey":"val"}} --- request GET /t diff --git a/t/admin/plugins-reload.t b/t/admin/plugins-reload.t index df891279d36b..336723146ce6 100644 --- a/t/admin/plugins-reload.t +++ b/t/admin/plugins-reload.t @@ -45,7 +45,7 @@ location /t { ngx.status = code ngx.say(org_body) - ngx.sleep(0.2) + ngx.sleep(1) } } --- request @@ -70,7 +70,7 @@ location /t { content_by_lua_block { local core = require "apisix.core" local config_util = require("apisix.core.config_util") - ngx.sleep(0.5) -- make sure the sync happened when admin starts is already finished + ngx.sleep(1) -- make sure the sync happened when admin starts is already finished local before_reload = true local plugins_conf, err @@ -88,7 +88,7 @@ location /t { error("failed to create etcd instance for fetching /plugins : " .. err) end - ngx.sleep(0.5) + ngx.sleep(1) local data = [[ deployment: diff --git a/t/certs/test-dot.crt b/t/certs/test-dot.crt new file mode 100644 index 000000000000..a9dfd3326221 --- /dev/null +++ b/t/certs/test-dot.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+zCCAeOgAwIBAgIUWUtIDbrU8QF90OXlMKyClPRNRcgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGUk9PVENBMCAXDTI0MDcxNzE2MDcyM1oYDzIxMjQwNjIz +MTYwNzIzWjAYMRYwFAYDVQQDDA13d3cudGVzdC5jb20uMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEApkX5NgwwEC/brmrUAfxSMGMaYOzjx+3BlCC23sLR +0uQ1+KMXt/Pd2QJVqREjEAiwXCMuHbB0qWD5985SfsjeRJJ8rc8CzJfcb7QESKfK +GdLaD8LsyAAg+Rxm0QyVFGrLJ82sjbEimLGCkLMpYsePxEDEifKPp3Z9bRUFT0zm +xcUEXojw5pzjrjIvfqVenWNP716s7bSdOFoc4RBlAdEI3pFUasLF9Lovz7BJLvtY +aoqgCNfb78C6zreDLswET5/338AVf9yPYc5HOthmygxkYTniK47/fOW64RQKXQ2X +EtBiIzN6dSXfTCXSpvow5XIR02rLoxsVEEwM9ODgUAJg6QIDAQABo0IwQDAdBgNV +HQ4EFgQUAHYNW6/hFM+Bqd2KNBXbLgJLaxcwHwYDVR0jBBgwFoAUjwSzlti+ag+f +BzoRa0wZbMaGh10wDQYJKoZIhvcNAQELBQADggEBAA1HfiDtHZV8sxJjasnNSM9f +6XTRCjT+DcABXm7k/Dmb8q5rpyqYwkUfadgAbmPx6T/dC4z7LblkcTkwD7azpkNE +fXY3Hx4qxSVSbSOHWnaSOX/8BRiPbSQNWGyTGh9AK/Vp/VJU2cDPqFbjQKHFq3ZI +w3GnRDerdA8vm5qzJ5/9wMF2ZsmnMiV3zX0Xisbzx/dponz6ktfygE3bk8Pb4wKt +D0EjbnLIXwyHv1czJrcRq0Y8irWaTY97vdff/J2aO9582zFNx6AnsU3+6fGsDyrO +ss+ggKDLK+aOBKroTNb3TgdPyPOgobUwLByFdKT/zTtWbkqyYMZzBme2SD4TWok= +-----END CERTIFICATE----- diff --git a/t/certs/test-dot.key b/t/certs/test-dot.key new file mode 100644 index 000000000000..5ed8aba21b13 --- /dev/null +++ b/t/certs/test-dot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCmRfk2DDAQL9uu +atQB/FIwYxpg7OPH7cGUILbewtHS5DX4oxe3893ZAlWpESMQCLBcIy4dsHSpYPn3 +zlJ+yN5EknytzwLMl9xvtARIp8oZ0toPwuzIACD5HGbRDJUUassnzayNsSKYsYKQ +sylix4/EQMSJ8o+ndn1tFQVPTObFxQReiPDmnOOuMi9+pV6dY0/vXqzttJ04Whzh +EGUB0QjekVRqwsX0ui/PsEku+1hqiqAI19vvwLrOt4MuzARPn/ffwBV/3I9hzkc6 +2GbKDGRhOeIrjv985brhFApdDZcS0GIjM3p1Jd9MJdKm+jDlchHTasujGxUQTAz0 +4OBQAmDpAgMBAAECggEAD84ctm8h5fYApDOWJ8Kp9tzCwgYekE94vEmATIw5CPqF +qVbqbyNUmhdTWGzvN+vVhMqYzHxsmHmmBTDU7WWPYDYK+TQRbGx+iRUz54qghsQg +04j4PDor6DYTjWlMZfqRSV0u+vCErP5JnpLTOyckUrfD3ueCUX0tRsBN5wf0s0WD +7AiUIdVBesQwIuIin3MyhGFtQC0PNta3NdSBVbnUA69OL3QNxPoai5LACrAf1hkf +wPD/y6y2CswdER+j+obPChjTcnJFjRCkqqO+66QZWmMmVxq4ymCQg9IOgLRWtfhI +6Ts5RxVn12kEuPULk9oHHOjC+MVh3BmWFLb58G/gwQKBgQDUCSd/2uswTVlTYpw6 +XO3iVyoZVeo/BIiOm/kjmqmr5U/D7ZO27ElKBTe9CDQ4WB5PuisCy0/SnsJJsPpf +pWif2v0mVs3T9K7J1M1yQU2iMs+Z2stzLGe5AASImYpw9091v57A/1jI4VUoodOr +7sMo+9ROqx6dTG/tJgUa+VZaKQKBgQDIv8CZHv4LqvQEQrGoTcKOxQP47nsbfEPW +B0GQscykvRTWxlTfFdfFM4VG2ApERZDwjPFU84n4dH8J7P14iy2ty70krzHWNfjY +y52CXUb295HsdcQ0bP8wztuvM/Jfh1mKKynmezvAZlTSb+GMAAMrReuG2Ga1/gp1 +5daCd4IowQKBgG//md6eCybLZIh4CN+HIJwywGj7iazZvyvc1T9qPX8vs+9g+Wpg +6uFvWh6+S58LZI9mXbuvGq288BEuq0GERHxTlu3+YeA4WW8AubhFKDWpsyCogliG +tw7wJHTm7Up4R3+BxOBawFHzPCEnQYCKsIlgY6deGeCqdGCGeaHi3CrpAoGAdWam +xSW53qr4j/FNIqdvK72OaCtX9agDqAyQTIWer40gvcY5ZknI6TwLKnY38ttYO0XB +8TOIMbQ3g1+EkNWcPjKTh/upQqRHxsm1cMMKOG5qeYYZ26sOxsWC9oCDs1hdhg9e +LrtNI2T1IChsGEr9j3YRmse9sZtDFNX4UE6B4UECgYEAsuRRQK0tgvcsQxkX/bZb +VTKqI4ezGRLXuavBe42xWOBLFzEujGvbZMbxzD4F4H1dfVVor3ItAEoybC37jtHI +uEWLAQtZtNyDCOiq4UuwbmtIqtoJz556QUrwO0KdPPjg/jyZTxs5jdKRMk9bsfmR +80vnuQpr0CZe8EgHiMoysrs= +-----END PRIVATE KEY----- diff --git a/t/cli/test_etcd_healthcheck.sh b/t/cli/test_etcd_healthcheck.sh index e756653c1cca..41efb16b0e7b 100755 --- a/t/cli/test_etcd_healthcheck.sh +++ b/t/cli/test_etcd_healthcheck.sh @@ -43,7 +43,7 @@ deployment: timeout: 2 ' > conf/config.yaml -docker-compose -f ./t/cli/docker-compose-etcd-cluster.yaml up -d +docker compose -f ./t/cli/docker-compose-etcd-cluster.yaml up -d # case 1: Check apisix not got effected when one etcd node disconnected make init && make run @@ -142,4 +142,4 @@ else fi # stop etcd docker container -docker-compose -f ./t/cli/docker-compose-etcd-cluster.yaml down +docker compose -f ./t/cli/docker-compose-etcd-cluster.yaml down diff --git a/t/cli/test_validate_config.sh b/t/cli/test_validate_config.sh index 0379b986c5b2..0f8a09a43c2d 100755 --- a/t/cli/test_validate_config.sh +++ b/t/cli/test_validate_config.sh @@ -99,26 +99,6 @@ make stop echo "passed: allow configuring address in stream_proxy" -sed -i 's/^ \(node_listen:\)/ #\1/g' conf/config-default.yaml -sed -i 's/^ \(- 9080\)/ #\1/g' conf/config-default.yaml -sed -i 's/^ # \(node_listen: 9080\)/ \1/g' conf/config-default.yaml - -echo ' -apisix: - node_listen: - - 9080 - - 9081 -' > conf/config.yaml - -out=$(make init 2>&1 || true) -if ! echo "$out"; then - echo "failed: allow configuring node_listen as a number in the default config" - exit 1 -fi -git checkout conf/config-default.yaml - -echo "passed: allow configuring node_listen as a number in the default config" - # apisix test git checkout conf/config.yaml diff --git a/t/core/etcd-mtls.t b/t/core/etcd-mtls.t index 3300aae42639..3ff25715f2ec 100644 --- a/t/core/etcd-mtls.t +++ b/t/core/etcd-mtls.t @@ -82,12 +82,8 @@ deployment: } --- request GET /t ---- grep_error_log eval -qr/init_by_lua:\d+: \S+/ ---- grep_error_log_out -init_by_lua:12: ab -init_by_lua:19: 200 -init_by_lua:26: 404 +--- error_log eval +qr/init_by_lua:\d+: ab/ and qr/init_by_lua:\d+: 200/ and qr/init_by_lua:\d+: 404/ @@ -136,12 +132,8 @@ deployment: ngx.say("ok") } --- stream_enable ---- grep_error_log eval -qr/init_by_lua:\d+: \S+/ ---- grep_error_log_out -init_by_lua:12: ab -init_by_lua:19: 200 -init_by_lua:26: 404 +--- error_log eval +qr/init_by_lua:\d+: ab/ and qr/init_by_lua:\d+: 200/ and qr/init_by_lua:\d+: 404/ @@ -286,5 +278,5 @@ deployment: } --- request GET /t ---- error_log -init_by_lua:11: ab +--- error_log eval +qr/init_by_lua:\d+: ab/ diff --git a/t/core/grpc-openresty.t b/t/core/grpc-openresty.t deleted file mode 100644 index 85d0a4369392..000000000000 --- a/t/core/grpc-openresty.t +++ /dev/null @@ -1,50 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use t::APISIX; - -my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx'; -my $version = eval { `$nginx_binary -V 2>&1` }; - -if ($version =~ m/\/apisix-nginx-module/) { - plan(skip_all => "for vanilla OpenResty only"); -} else { - plan('no_plan'); -} - -add_block_preprocessor(sub { - my ($block) = @_; - - if (!$block->request) { - $block->set_value("request", "GET /t"); - } -}); - -run_tests; - -__DATA__ - -=== TEST 1: ensure the core.grpc is nil under vanilla OpenResty ---- config - location /t { - content_by_lua_block { - local core = require "apisix.core" - local gcli = core.grpc - ngx.say(gcli) - } - } ---- response_body -nil diff --git a/t/core/grpc.t b/t/core/grpc.t deleted file mode 100644 index bd52d9e13409..000000000000 --- a/t/core/grpc.t +++ /dev/null @@ -1,173 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -use t::APISIX; - -my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx'; -my $version = eval { `$nginx_binary -V 2>&1` }; - -if ($version !~ m/\/apisix-nginx-module/) { - plan(skip_all => "apisix-nginx-module not installed"); -} else { - plan('no_plan'); -} - -add_block_preprocessor(sub { - my ($block) = @_; - - if (!$block->request) { - $block->set_value("request", "GET /t"); - } -}); - -run_tests; - -__DATA__ - -=== TEST 1: unary ---- config - location /t { - content_by_lua_block { - local core = require "apisix.core" - local gcli = core.grpc - assert(gcli.load("t/grpc_server_example/proto/helloworld.proto")) - local conn = assert(gcli.connect("127.0.0.1:10051")) - local res, err = conn:call("helloworld.Greeter", "SayHello", { - name = "apisix" }) - conn:close() - if not res then - ngx.status = 503 - ngx.say(err) - return - end - ngx.say(res.message) - } - } ---- response_body -Hello apisix - - - -=== TEST 2: server stream ---- config - location /t { - content_by_lua_block { - local core = require "apisix.core" - local gcli = core.grpc - assert(gcli.load("t/grpc_server_example/proto/helloworld.proto")) - local conn = assert(gcli.connect("127.0.0.1:10051")) - local st, err = conn:new_server_stream("helloworld.Greeter", - "SayHelloServerStream", { name = "apisix" }) - if not st then - ngx.status = 503 - ngx.say(err) - return - end - - for i = 1, 5 do - local res, err = st:recv() - if not res then - ngx.status = 503 - ngx.say(err) - return - end - ngx.say(res.message) - end - } - } ---- response_body eval -"Hello apisix\n" x 5 - - - -=== TEST 3: client stream ---- config - location /t { - content_by_lua_block { - local core = require "apisix.core" - local gcli = core.grpc - assert(gcli.load("t/grpc_server_example/proto/helloworld.proto")) - local conn = assert(gcli.connect("127.0.0.1:10051")) - local st, err = conn:new_client_stream("helloworld.Greeter", - "SayHelloClientStream", { name = "apisix" }) - if not st then - ngx.status = 503 - ngx.say(err) - return - end - - for i = 1, 3 do - local ok, err = st:send({ name = "apisix" }) - if not ok then - ngx.status = 503 - ngx.say(err) - return - end - end - - local res, err = st:recv_close() - if not res then - ngx.status = 503 - ngx.say(err) - return - end - ngx.say(res.message) - } - } ---- response_body -Hello apisix!Hello apisix!Hello apisix!Hello apisix! - - - -=== TEST 4: bidirectional stream ---- config - location /t { - content_by_lua_block { - local core = require "apisix.core" - local gcli = core.grpc - assert(gcli.load("t/grpc_server_example/proto/helloworld.proto")) - local conn = assert(gcli.connect("127.0.0.1:10051")) - local st, err = conn:new_bidirectional_stream("helloworld.Greeter", - "SayHelloBidirectionalStream", { name = "apisix" }) - if not st then - ngx.status = 503 - ngx.say(err) - return - end - - for i = 1, 3 do - local ok, err = st:send({ name = "apisix" }) - if not ok then - ngx.status = 503 - ngx.say(err) - return - end - end - - assert(st:close_send()) - for i = 1, 5 do - local res, err = st:recv() - if not res then - ngx.status = 503 - ngx.say(err) - return - end - ngx.say(res.message) - end - } - } ---- response_body eval -"Hello apisix\n" x 4 . "stream ended\n" diff --git a/t/plugin/error-log-logger-clickhouse.t b/t/plugin/error-log-logger-clickhouse.t index 6846f6ef1d24..91ef60b187d5 100644 --- a/t/plugin/error-log-logger-clickhouse.t +++ b/t/plugin/error-log-logger-clickhouse.t @@ -98,7 +98,7 @@ done --- error_log this is a warning message for test2 clickhouse body: INSERT INTO t FORMAT JSONEachRow -clickhouse headers: x-clickhouse-key:dpwomMlEsHH2L7wSUi6YiQ== +clickhouse headers: x-clickhouse-key:a clickhouse headers: x-clickhouse-user:default clickhouse headers: x-clickhouse-database:default --- wait: 3 @@ -133,7 +133,7 @@ clickhouse headers: x-clickhouse-database:default --- error_log this is a warning message for test3 clickhouse body: INSERT INTO t FORMAT JSONEachRow -clickhouse headers: x-clickhouse-key:dpwomMlEsHH2L7wSUi6YiQ== +clickhouse headers: x-clickhouse-key:a clickhouse headers: x-clickhouse-user:default clickhouse headers: x-clickhouse-database:default --- wait: 5 diff --git a/t/plugin/grpc-transcode3.t b/t/plugin/grpc-transcode3.t index 0a8ddf54ded6..93a3d626766d 100644 --- a/t/plugin/grpc-transcode3.t +++ b/t/plugin/grpc-transcode3.t @@ -576,3 +576,46 @@ location /t { } --- response_body passed + + + +=== TEST 14: pb_option - check the matchings between enum and category +--- config + location /t { + content_by_lua_block { + local ngx_re_match = ngx.re.match + local plugin = require("apisix.plugins.grpc-transcode") + + local pb_option_def = plugin.schema.properties.pb_option.items.anyOf + + local patterns = { + [[^enum_as_.+$]], + [[^int64_as_.+$]], + [[^.+_default_.+$]], + [[^.+_hooks$]], + } + + local function check_pb_option_enum_category() + for i, category in ipairs(pb_option_def) do + for _, enum in ipairs(category.enum) do + if not ngx_re_match(enum, patterns[i], "jo") then + return ([[mismatch between enum("%s") and category("%s")]]):format( + enum, category.description) + end + end + end + end + + local err = check_pb_option_enum_category() + if err then + ngx.say(err) + return + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done diff --git a/t/plugin/security-warning.t b/t/plugin/security-warning.t new file mode 100644 index 000000000000..f2d2e3ea6375 --- /dev/null +++ b/t/plugin/security-warning.t @@ -0,0 +1,570 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use t::APISIX 'no_plan'; + +repeat_each(1); +no_long_string(); +no_root_location(); +add_block_preprocessor(sub { + my ($block) = @_; + + if (!defined $block->request) { + $block->set_value("request", "GET /t"); + } + +}); +run_tests(); + +__DATA__ + +=== TEST 1: authz-casdoor no https +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.authz-casdoor") + local fake_uri = "http://127.0.0.1:" .. ngx.var.server_port + local callback_url = "http://127.0.0.1:" .. ngx.var.server_port .. + "/anything/callback" + local conf = { + callback_url = callback_url, + endpoint_addr = fake_uri, + client_id = "7ceb9b7fda4a9061ec1c", + client_secret = "3416238e1edf915eac08b8fe345b2b95cdba7e04" + } + local ok, err = plugin.check_schema(conf) + if not ok then + ngx.say(err) + end + ngx.say("done") + + } + } +--- response_body +done +--- error_log +Using authz-casdoor endpoint_addr with no TLS is a security risk +Using authz-casdoor callback_url with no TLS is a security risk + + + +=== TEST 2: authz-casdoor with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.authz-casdoor") + local fake_uri = "https://127.0.0.1:" .. ngx.var.server_port + local callback_url = "https://127.0.0.1:" .. ngx.var.server_port .. + "/anything/callback" + local conf = { + callback_url = callback_url, + endpoint_addr = fake_uri, + client_id = "7ceb9b7fda4a9061ec1c", + client_secret = "3416238e1edf915eac08b8fe345b2b95cdba7e04" + } + local ok, err = plugin.check_schema(conf) + if not ok then + ngx.say(err) + end + ngx.say("done") + + } + } +--- response_body +done +--- no_error_log +Using authz-casdoor endpoint_addr with no TLS is a security risk +Using authz-casdoor callback_url with no TLS is a security risk + + + +=== TEST 3: authz keycloak with no TLS +--- config + location /t { + content_by_lua_block { + local check = {"discovery", "token_endpoint", "resource_registration_endpoint", "access_denied_redirect_uri"} + local plugin = require("apisix.plugins.authz-keycloak") + local ok, err = plugin.check_schema({ + client_id = "foo", + discovery = "http://host.domain/realms/foo/protocol/openid-connect/token", + token_endpoint = "http://token_endpoint.domain", + resource_registration_endpoint = "http://resource_registration_endpoint.domain", + access_denied_redirect_uri = "http://access_denied_redirect_uri.domain" + }) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- error_log +Using authz-keycloak discovery with no TLS is a security risk +Using authz-keycloak token_endpoint with no TLS is a security risk +Using authz-keycloak resource_registration_endpoint with no TLS is a security +Using authz-keycloak access_denied_redirect_uri with no TLS is a security risk + + + +=== TEST 4: authz keycloak with TLS +--- config + location /t { + content_by_lua_block { + local check = {"discovery", "token_endpoint", "resource_registration_endpoint", "access_denied_redirect_uri"} + local plugin = require("apisix.plugins.authz-keycloak") + local ok, err = plugin.check_schema({ + client_id = "foo", + discovery = "https://host.domain/realms/foo/protocol/openid-connect/token", + token_endpoint = "https://token_endpoint.domain", + resource_registration_endpoint = "https://resource_registration_endpoint.domain", + access_denied_redirect_uri = "https://access_denied_redirect_uri.domain" + }) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- no_error_log +Using authz-keycloak discovery with no TLS is a security risk +Using authz-keycloak token_endpoint with no TLS is a security risk +Using authz-keycloak resource_registration_endpoint with no TLS is a security +Using authz-keycloak access_denied_redirect_uri with no TLS is a security risk + + + +=== TEST 5: cas auth with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.cas-auth") + local ok, err = plugin.check_schema({ + idp_uri = "http://a.com", + cas_callback_uri = "/a/b", + logout_uri = "/c/d" + }) + + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +passed +--- error_log +risk + + + +=== TEST 6: cas auth with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.cas-auth") + local ok, err = plugin.check_schema({ + idp_uri = "https://a.com", + cas_callback_uri = "/a/b", + logout_uri = "/c/d" + }) + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +passed +--- no_error_log +risk + + + +=== TEST 7: clickhouse logger with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.clickhouse-logger") + local ok, err = plugin.check_schema({ + timeout = 3, + retry_delay = 1, + batch_max_size = 500, + user = "default", + password = "a", + database = "default", + logtable = "t", + endpoint_addrs = { + "http://127.0.0.1:1980/clickhouse_logger_server", + "http://127.0.0.2:1980/clickhouse_logger_server", + }, + max_retry_count = 1, + name = "clickhouse logger", + ssl_verify = false + }) + + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +passed +--- error_log +Using clickhouse-logger endpoint_addrs with no TLS is a security risk + + + +=== TEST 8: clickhouse logger with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.clickhouse-logger") + local ok, err = plugin.check_schema({ + timeout = 3, + retry_delay = 1, + batch_max_size = 500, + user = "default", + password = "a", + database = "default", + logtable = "t", + endpoint_addrs = { + "https://127.0.0.1:1980/clickhouse_logger_server", + "https://127.0.0.2:1980/clickhouse_logger_server", + }, + max_retry_count = 1, + name = "clickhouse logger", + ssl_verify = false + }) + + if not ok then + ngx.say(err) + else + ngx.say("passed") + end + } + } +--- response_body +passed +--- no_error_log +Using clickhouse-logger endpoint_addrs with no TLS is a security risk + + + +=== TEST 9: elastic search logger with no TLS +--- config + location /t { + content_by_lua_block { + local ok, err + local plugin = require("apisix.plugins.elasticsearch-logger") + ok, err = plugin.check_schema({ + endpoint_addrs = { + "http://127.0.0.1:9200" + }, + field = { + index = "services" + } + }) + if err then + ngx.say(err) + else + ngx.say("passed") + end + + } + } +--- response_body_like +passed +--- error_log +Using elasticsearch-logger endpoint_addrs with no TLS is a security risk + + + +=== TEST 10: elastic search logger with TLS +--- config + location /t { + content_by_lua_block { + local ok, err + local plugin = require("apisix.plugins.elasticsearch-logger") + ok, err = plugin.check_schema({ + endpoint_addrs = { + "https://127.0.0.1:9200" + }, + field = { + index = "services" + } + }) + if err then + ngx.say(err) + else + ngx.say("passed") + end + + } + } +--- response_body_like +passed +--- no_error_log +Using elasticsearch-logger endpoint_addrs with no TLS is a security risk + + + +=== TEST 11: error log logger with tcp.tls = false +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.error-log-logger") + local ok, err = plugin.check_schema({ + tcp = { + host = "host.com", + port = "99", + tls = false, + }, + skywalking = { + endpoint_addr = "http://a.bcd" + }, + clickhouse = { + endpoint_addr = "http://some.com", + user = "user", + password = "secret", + database = "yes", + logtable = "some" + }, + }) + ngx.say(ok and "done" or err) + + } + } +--- request +GET /t +--- response_body +done +--- error_log +Using error-log-logger skywalking.endpoint_addr with no TLS is a security risk +Using error-log-logger clickhouse.endpoint_addr with no TLS is a security risk +Keeping tcp.tls disabled in error-log-logger configuration is a security risk + + + +=== TEST 12: error log logger with tcp.tls = true +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.error-log-logger") + local ok, err = plugin.check_schema({ + tcp = { + host = "host.com", + port = "99", + tls = true, + }, + skywalking = { + endpoint_addr = "https://a.bcd" + }, + clickhouse = { + endpoint_addr = "https://some.com", + user = "user", + password = "secret", + database = "yes", + logtable = "some" + }, + }) + ngx.say(ok and "done" or err) + + } + } +--- request +GET /t +--- response_body +done +--- no_error_log +Using error-log-logger skywalking.endpoint_addr with no TLS is a security risk +Using error-log-logger clickhouse.endpoint_addr with no TLS is a security risk +Keeping tcp.tls disabled in error-log-logger configuration is a security risk + + + +=== TEST 13: forward auth with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.forward-auth") + + local ok, err = plugin.check_schema({uri = "http://127.0.0.1:8199"}) + ngx.say(ok and "done" or err) + + } + } +--- response_body +done +--- error_log +Using forward-auth uri with no TLS is a security risk +Using forward-auth uri with no TLS is a security risk + + + +=== TEST 14: forward auth with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.forward-auth") + + local ok, err = plugin.check_schema({uri = "https://127.0.0.1:8199"}) + ngx.say(ok and "done" or err) + + } + } +--- response_body +done +--- no_error_log +Using forward-auth uri with no TLS is a security risk + + + +=== TEST 15: http-logger with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.http-logger") + local ok, err = plugin.check_schema({uri = "http://127.0.0.1"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +Using http-logger uri with no TLS is a security risk + + + +=== TEST 16: http-logger with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.http-logger") + local ok, err = plugin.check_schema({uri = "https://127.0.0.1"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- no_error_log +Using http-logger uri with no TLS is a security risk + + + +=== TEST 17: ldap auth with no TLS +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local plugin = require("apisix.plugins.ldap-auth") + local ok, err = plugin.check_schema( + { + base_dn = "123", + ldap_uri = "127.0.0.1:1389", + tls_verify = false, + use_tls = false + }) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +Keeping tls_verify disabled in ldap-auth configuration is a security risk +Keeping use_tls disabled in ldap-auth configuration is a security risk + + + +=== TEST 18: ldap auth with TLS +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local plugin = require("apisix.plugins.ldap-auth") + local ok, err = plugin.check_schema({base_dn = "123", ldap_uri = "127.0.0.1:1389", use_tls = true}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- no_error_log +Using LDAP auth with TLS disabled is a security risk + + + +=== TEST 19: loki-logger with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.loki-logger") + + local ok, err = plugin.check_schema({endpoint_addrs = {"http://127.0.0.1:8199"}}) + ngx.say(ok and "done" or err) + } + } +--- response_body +done +--- error_log +Using loki-logger endpoint_addrs with no TLS is a security risk +Using loki-logger endpoint_addrs with no TLS is a security risk +Using loki-logger endpoint_addrs with no TLS is a security risk + + + +=== TEST 20: loki logger with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.loki-logger") + + local ok, err = plugin.check_schema({endpoint_addrs = {"https://127.0.0.1:8199"}}) + ngx.say(ok and "done" or err) + } + } +--- response_body +done +--- no_error_log +Using loki-logger endpoint_addrs with no TLS is a security risk diff --git a/t/plugin/security-warning2.t b/t/plugin/security-warning2.t new file mode 100644 index 000000000000..acfd4664965a --- /dev/null +++ b/t/plugin/security-warning2.t @@ -0,0 +1,629 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +use t::APISIX 'no_plan'; + +repeat_each(1); +no_long_string(); +no_root_location(); +add_block_preprocessor(sub { + my ($block) = @_; + + if (!defined $block->request) { + $block->set_value("request", "GET /t"); + } +}); +run_tests(); + +__DATA__ + +=== TEST 1: opa with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.opa") + local ok, err = plugin.check_schema({host = "http://127.0.0.1:8181", policy = "example/allow"}) + ngx.say(ok and "done" or err) + } + } +--- response_body +done +--- error_log +Using opa host with no TLS is a security risk + + + +=== TEST 2: opa with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.opa") + local ok, err = plugin.check_schema({host = "https://127.0.0.1:8181", policy = "example/allow"}) + ngx.say(ok and "done" or err) + } + } +--- response_body +done +--- no_error_log +Using opa host with no TLS is a security risk + + + +=== TEST 3: openid-connect with no TLS +--- config + location /t { + content_by_lua_block { + + local plugin = require("apisix.plugins.openid-connect") + local ok, err = plugin.check_schema({ + client_id = "a", + client_secret = "b", + discovery = "http://a.com", + introspection_endpoint = "http://b.com", + redirect_uri = "http://c.com", + post_logout_redirect_uri = "http://d.com", + proxy_opts = { + http_proxy = "http://e.com" + } + }) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +Using openid-connect discovery with no TLS is a security risk +Using openid-connect introspection_endpoint with no TLS is a security risk +Using openid-connect redirect_uri with no TLS is a security risk +Using openid-connect post_logout_redirect_uri with no TLS is a security risk +Using openid-connect proxy_opts.http_proxy with no TLS is a security risk + + + +=== TEST 4: openid-connect with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.openid-connect") + + local ok, err = plugin.check_schema({ + client_id = "a", + client_secret = "b", + discovery = "https://a.com", + introspection_endpoint = "https://b.com", + redirect_uri = "https://c.com", + post_logout_redirect_uri = "https://d.com", + proxy_opts = { + http_proxy = "https://e.com" + } + }) + + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- no_error_log +Using openid-connect discovery with no TLS is a security risk +Using openid-connect introspection_endpoint with no TLS is a security risk +Using openid-connect redirect_uri with no TLS is a security risk +Using openid-connect post_logout_redirect_uri with no TLS is a security risk +Using openid-connect proxy_opts.http_proxy with no TLS is a security risk + + + +=== TEST 5: opentelemetry with no TLS +--- extra_yaml_config +plugins: + - opentelemetry +plugin_attr: + opentelemetry: + trace_id_source: x-request-id + batch_span_processor: + max_export_batch_size: 1 + inactive_timeout: 0.5 + collector: + address: http://127.0.0.1:4318 + request_timeout: 3 + request_headers: + foo: bar +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "opentelemetry": { + "sampler": { + "name": "always_on" + } + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/opentracing" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- error_log +Using opentelemetry collector.address with no TLS is a security risk + + + +=== TEST 6: opentelemetery with TLS +--- extra_yaml_config +plugins: + - opentelemetry +plugin_attr: + opentelemetry: + trace_id_source: x-request-id + batch_span_processor: + max_export_batch_size: 1 + inactive_timeout: 0.5 + collector: + address: https://127.0.0.1:4318 + request_timeout: 3 + request_headers: + foo: bar +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "opentelemetry": { + "sampler": { + "name": "always_on" + } + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/opentracing" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- no_error_log +Using opentelemetry collector.address with no TLS is a security risk + + + +=== TEST 7: openwhisk with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.openwhisk") + local ok, err = plugin.check_schema({ + api_host = "http://127.0.0.1:3233", + service_token = "test:test", + namespace = "test", + action = "test" + }) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +Using openwhisk api_host with no TLS is a security risk + + + +=== TEST 8: openwhisk with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.openwhisk") + local ok, err = plugin.check_schema({api_host = "https://127.0.0.1:3233", service_token = "test:test", namespace = "test", action = "test"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- no_error_log +Using openwhisk api_host with no TLS is a security risk + + + +=== TEST 9: rocketmq with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.rocketmq-logger") + local ok, err = plugin.check_schema({ + topic = "test", + key = "key1", + nameserver_list = { + "127.0.0.1:3" + }, + use_tls = false + }) + if not ok then + ngx.say(err) + end + ngx.say("done") + } + } +--- response_body +done +--- error_log +Keeping use_tls disabled in rocketmq-logger configuration is a security risk + + + +=== TEST 10: rocketmq with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.rocketmq-logger") + local ok, err = plugin.check_schema({ + topic = "test", + key = "key1", + nameserver_list = { + "127.0.0.1:3" + }, + use_tls = true + }) + if not ok then + ngx.say(err) + end + ngx.say("done") + } + } +--- response_body +done +--- no_error_log +Keeping use_tls disabled in rocketmq-logger configuration is a security risk + + + +=== TEST 11: skywalking-logger with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.skywalking-logger") + local ok, err = plugin.check_schema({endpoint_addr = "http://127.0.0.1"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- error_log +Using skywalking-logger endpoint_addr with no TLS is a security risk + + + +=== TEST 12: skywalking-logger with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.skywalking-logger") + local ok, err = plugin.check_schema({endpoint_addr = "https://127.0.0.1"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- response_body +done +--- no_error_log +Using skywalking-logger endpoint_addr with no TLS is a security risk + + + +=== TEST 13: skywalking with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.skywalking") + local ok, err = plugin.check_schema({endpoint_addr = "http://127.0.0.1:12800"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- error_log +Using skywalking endpoint_addr with no TLS is a security risk + + + +=== TEST 14: skywalking with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.skywalking") + local ok, err = plugin.check_schema({endpoint_addr = "https://127.0.0.1:12800"}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- no_error_log +Using skywalking endpoint_addr with no TLS is a security risk + + + +=== TEST 15: syslog with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.syslog") + local ok, err = plugin.check_schema({ + host = "127.0.0.1", + port = 5140, + tls = false + }) + if not ok then + ngx.say(err) + end + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- error_log +Keeping tls disabled in syslog configuration is a security risk + + + +=== TEST 16: syslog with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.syslog") + local ok, err = plugin.check_schema({ + host = "127.0.0.1", + port = 5140, + tls = true + }) + if not ok then + ngx.say(err) + end + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- no_error_log +Keeping tls disabled in syslog configuration is a security risk + + + +=== TEST 17: tcp-logger with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.tcp-logger") + local ok, err = plugin.check_schema({host = "127.0.0.1", port = 3000, tls = false}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- error_log +Keeping tls disabled in tcp-logger configuration is a security risk + + + +=== TEST 18: tcp-logger with TLS +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "tcp-logger": { + "host": "127.0.0.1", + "port": 3000, + "tls": true + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +Keeping tls disabled in tcp-logger configuration is a security risk + + + +=== TEST 19: wolf-rbac with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.wolf-rbac") + local conf = { + server = "http://127.0.0.1:12180" + } + + local ok, err = plugin.check_schema(conf) + if not ok then + ngx.say(err) + end + + ngx.say(require("toolkit.json").encode(conf)) + } + } +--- response_body_like eval +qr/\{"appid":"unset","header_prefix":"X-","server":"http:\/\/127\.0\.0\.1:12180"\}/ +--- error_log +Using wolf-rbac server with no TLS is a security risk + + + +=== TEST 20: wolf-rbac with TLS +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/consumers', + ngx.HTTP_PUT, + [[{ + "username": "wolf_rbac_unit_test", + "plugins": { + "wolf-rbac": { + "appid": "wolf-rbac-app", + "server": "https://127.0.0.1:1982" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed +--- no_error_log +Using wolf-rbac server with no TLS is a security risk + + + +=== TEST 21: zipkin with no TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.zipkin") + local ok, err = plugin.check_schema({endpoint = 'http://127.0.0.1', sample_ratio = 0.001}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- error_log +Using zipkin endpoint with no TLS is a security risk + + + +=== TEST 22: zipkin with TLS +--- config + location /t { + content_by_lua_block { + local plugin = require("apisix.plugins.zipkin") + local ok, err = plugin.check_schema({endpoint = 'https://127.0.0.1', sample_ratio = 0.001}) + if not ok then + ngx.say(err) + end + + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- no_error_log +Using zipkin endpoint with no TLS is a security risk diff --git a/t/plugin/sls-logger.t b/t/plugin/sls-logger.t index af6ae667c34f..45dd3f8964d7 100644 --- a/t/plugin/sls-logger.t +++ b/t/plugin/sls-logger.t @@ -472,3 +472,60 @@ hello world } --- error_log "body":"hello world\n" + + + +=== TEST 16: set incorrect plugin metadata, should have error log +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local key = "/plugin_metadata/sls-logger" + local val = { + id = "sls-logger", + log_format = "bad plugin metadata" + } + local _, err = core.etcd.set(key, val) + if err then + ngx.say(err) + return + end + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- error_log +sync_data(): failed to check item data of [/apisix/plugin_metadata] +failed to check the configuration of plugin sls-logger + + + +=== TEST 17: set correct plugin metadata, should no error log +--- config + location /t { + content_by_lua_block { + local core = require("apisix.core") + local key = "/plugin_metadata/sls-logger" + local val = { + id = "sls-logger", + log_format = { + host = "$host", + client_ip = "$remote_addr" + } + } + local _, err = core.etcd.set(key, val) + if err then + ngx.say(err) + return + end + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done +--- no_error_log diff --git a/t/router/radixtree-sni3.t b/t/router/radixtree-sni3.t new file mode 100644 index 000000000000..ff18bda7f7d3 --- /dev/null +++ b/t/router/radixtree-sni3.t @@ -0,0 +1,283 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use t::APISIX 'no_plan'; + +log_level('debug'); +no_root_location(); + +BEGIN { + $ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); +} + +add_block_preprocessor(sub { + my ($block) = @_; + + if (!$block->request) { + $block->set_value("request", "GET /t"); + } + +}); + + +run_tests; + +__DATA__ + +=== TEST 1: set sni with trailing period +--- config +location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + + local ssl_cert = t.read_file("t/certs/test2.crt") + local ssl_key = t.read_file("t/certs/test2.key") + local data = {cert = ssl_cert, key = ssl_key, sni = "*.test.com"} + + local code, body = t.test('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + core.json.encode(data) + ) + + ngx.status = code + ngx.say(body) + } +} +--- request +GET /t +--- response_body +passed +--- error_code: 201 + + + +=== TEST 2: match against sni with no trailing period +--- config +listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + +location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local sess, err = sock:sslhandshake(nil, "a.test.com.", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + ngx.say("ssl handshake: ", sess ~= nil) + end -- do + -- collectgarbage() + } +} +--- request +GET /t +--- response_body +ssl handshake: true + + + +=== TEST 3: set snis with trailing period +--- config +location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + + local ssl_cert = t.read_file("t/certs/test2.crt") + local ssl_key = t.read_file("t/certs/test2.key") + local data = {cert = ssl_cert, key = ssl_key, snis = {"test2.com", "a.com"}} + + local code, body = t.test('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + core.json.encode(data) + ) + + ngx.status = code + ngx.say(body) + } +} +--- request +GET /t +--- response_body +passed + + + +=== TEST 4: match against sni with no trailing period +--- config +listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + +location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local sess, err = sock:sslhandshake(nil, "test2.com.", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + ngx.say("ssl handshake: ", sess ~= nil) + end -- do + -- collectgarbage() + } +} +--- request +GET /t +--- response_body +ssl handshake: true + + + +=== TEST 5: set ssl(sni: www.test.com.) +--- config +location /t { + content_by_lua_block { + local core = require("apisix.core") + local t = require("lib.test_admin") + local ssl_cert = t.read_file("t/certs/test-dot.crt") + local ssl_key = t.read_file("t/certs/test-dot.key") + local data = {cert = ssl_cert, key = ssl_key, sni = "www.test.com."} + local code, body = t.test('/apisix/admin/ssls/1', + ngx.HTTP_PUT, + core.json.encode(data), + [[{ + "value": { + "sni": "www.test.com." + }, + "key": "/apisix/ssls/1" + }]] + ) + ngx.status = code + ngx.say(body) + } +} +--- request +GET /t +--- response_body +passed + + + +=== TEST 6: set route(id: 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + + +=== TEST 7: client request +--- config +listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; +location /t { + content_by_lua_block { + -- etcd sync + ngx.sleep(0.2) + do + local sock = ngx.socket.tcp() + sock:settimeout(2000) + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + ngx.say("connected: ", ok) + local sess, err = sock:sslhandshake(nil, "www.test.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + ngx.say("ssl handshake: ", sess ~= nil) + local req = "GET /hello HTTP/1.0\r\nHost: www.test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + ngx.say("sent http request: ", bytes, " bytes.") + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + ngx.say("received: ", line) + end + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } +} +--- request +GET /t +--- response_body eval +qr{connected: 1 +ssl handshake: true +sent http request: 62 bytes. +received: HTTP/1.1 200 OK +received: Content-Type: text/plain +received: Content-Length: 12 +received: Connection: close +received: Server: APISIX/\d\.\d+(\.\d+)? +received: \nreceived: hello world +close: 1 nil} +--- error_log +server name: "www.test.com" +--- no_error_log +[error] +[alert] diff --git a/utils/check-lua-code-style.sh b/utils/check-lua-code-style.sh index 59fe473e4250..5296e75812b9 100755 --- a/utils/check-lua-code-style.sh +++ b/utils/check-lua-code-style.sh @@ -21,7 +21,7 @@ set -ex luacheck -q apisix t/lib -find apisix -name '*.lua' ! -wholename 'apisix/cli/ngx_tpl.lua' -exec ./utils/lj-releng {} + > \ +find apisix -name '*.lua' ! -wholename 'apisix/cli/ngx_tpl.lua' ! -wholename 'apisix/cli/config.lua' -exec ./utils/lj-releng {} + > \ /tmp/check.log 2>&1 || (cat /tmp/check.log && exit 1) grep -E "ERROR.*.lua:" /tmp/check.log > /tmp/error.log || true