moonming commented on code in PR #12551: URL: https://github.com/apache/apisix/pull/12551#discussion_r2323819477
########## apisix/init.lua: ########## @@ -599,6 +587,53 @@ function _M.handle_upstream(api_ctx, route, enable_websocket) end +local function handle_x_forwarded_headers(api_ctx) + local addr_is_trusted = trusted_addresses_util.is_trusted(api_ctx.var.realip_remote_addr) + + if not addr_is_trusted then + -- store the original x-forwarded-* headers for later process Review Comment: where is the `later process`? ########## apisix/utils/trusted-addresses.lua: ########## @@ -0,0 +1,79 @@ +-- +-- 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 require = require +local core = require("apisix.core") +local next = next +local ipairs = ipairs + +local trusted_addresses_matcher + +local _M = {} + + +local function validate_trusted_addresses(trusted_addresses) + for _, cidr in ipairs(trusted_addresses) do + if not core.ip.validate_cidr_or_ip(cidr) then + core.log.error("Invalid IP/CIDR '", cidr, "' exists in trusted_addresses") Review Comment: test case ########## apisix/utils/trusted-addresses.lua: ########## @@ -0,0 +1,79 @@ +-- +-- 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 require = require +local core = require("apisix.core") +local next = next +local ipairs = ipairs + +local trusted_addresses_matcher + +local _M = {} + + +local function validate_trusted_addresses(trusted_addresses) + for _, cidr in ipairs(trusted_addresses) do + if not core.ip.validate_cidr_or_ip(cidr) then + core.log.error("Invalid IP/CIDR '", cidr, "' exists in trusted_addresses") + return false + end + end + return true +end + + +function _M.init_worker() + local local_conf = core.config.local_conf() + local trusted_addresses = core.table.try_read_attr(local_conf, "apisix", "trusted_addresses") + + if not trusted_addresses then + return + end + + if not core.table.isarray(trusted_addresses) then + core.log.error("trusted_addresses '", trusted_addresses, Review Comment: test case ########## apisix/utils/trusted-addresses.lua: ########## @@ -0,0 +1,79 @@ +-- +-- 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 require = require +local core = require("apisix.core") +local next = next +local ipairs = ipairs + +local trusted_addresses_matcher + +local _M = {} + + +local function validate_trusted_addresses(trusted_addresses) + for _, cidr in ipairs(trusted_addresses) do + if not core.ip.validate_cidr_or_ip(cidr) then + core.log.error("Invalid IP/CIDR '", cidr, "' exists in trusted_addresses") + return false + end + end + return true +end + + +function _M.init_worker() + local local_conf = core.config.local_conf() + local trusted_addresses = core.table.try_read_attr(local_conf, "apisix", "trusted_addresses") + + if not trusted_addresses then Review Comment: ditto ########## docs/en/latest/plugins/chaitin-waf.md: ########## @@ -70,6 +70,10 @@ The response headers are listed below: | config.keepalive_timeout | integer | false | 60000 | Idle connection timeout, in milliseconds. | | config.real_client_ip | boolean | false | true | Specifies whether to use the `X-Forwarded-For` as the client IP (if present). If `false`, uses the direct client IP from the connection. | +:::note +Only `X-Forwarded-*` headers sent from addresses in the `apisix.trusted_addresses` configuration (supports IP and CIDR) will be trusted and passed to plugins or upstream. If `apisix.trusted_addresses` is not configured or the IP is not within the configured address range, all `X-Forwarded-*` headers will be discarded. Review Comment: discarded or overwrite? ########## apisix/utils/trusted-addresses.lua: ########## @@ -0,0 +1,79 @@ +-- +-- 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 require = require +local core = require("apisix.core") +local next = next +local ipairs = ipairs + +local trusted_addresses_matcher + +local _M = {} + + +local function validate_trusted_addresses(trusted_addresses) + for _, cidr in ipairs(trusted_addresses) do + if not core.ip.validate_cidr_or_ip(cidr) then + core.log.error("Invalid IP/CIDR '", cidr, "' exists in trusted_addresses") + return false + end + end + return true +end + + +function _M.init_worker() + local local_conf = core.config.local_conf() + local trusted_addresses = core.table.try_read_attr(local_conf, "apisix", "trusted_addresses") + + if not trusted_addresses then + return + end + + if not core.table.isarray(trusted_addresses) then + core.log.error("trusted_addresses '", trusted_addresses, + "' is not an array, please check your configuration") + return + end + + if not next(trusted_addresses) then + core.log.info("trusted_addresses is an empty array") + return + end + + if not validate_trusted_addresses(trusted_addresses) then + return + end + + local matcher, err = core.ip.create_ip_matcher(trusted_addresses) + if not matcher then + core.log.error("failed to create ip matcher for trusted_addresses: ", err) + return + end + + trusted_addresses_matcher = matcher +end + + +function _M.is_trusted(address) + if not trusted_addresses_matcher then + core.log.info("trusted_addresses_matcher is not initialized") Review Comment: ditto ########## apisix/utils/trusted-addresses.lua: ########## @@ -0,0 +1,79 @@ +-- +-- 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 require = require +local core = require("apisix.core") +local next = next +local ipairs = ipairs + +local trusted_addresses_matcher + +local _M = {} + + +local function validate_trusted_addresses(trusted_addresses) + for _, cidr in ipairs(trusted_addresses) do + if not core.ip.validate_cidr_or_ip(cidr) then + core.log.error("Invalid IP/CIDR '", cidr, "' exists in trusted_addresses") + return false + end + end + return true +end + + +function _M.init_worker() + local local_conf = core.config.local_conf() + local trusted_addresses = core.table.try_read_attr(local_conf, "apisix", "trusted_addresses") + + if not trusted_addresses then + return + end + + if not core.table.isarray(trusted_addresses) then + core.log.error("trusted_addresses '", trusted_addresses, + "' is not an array, please check your configuration") + return + end + + if not next(trusted_addresses) then + core.log.info("trusted_addresses is an empty array") + return + end + + if not validate_trusted_addresses(trusted_addresses) then + return + end + + local matcher, err = core.ip.create_ip_matcher(trusted_addresses) + if not matcher then + core.log.error("failed to create ip matcher for trusted_addresses: ", err) Review Comment: ditto ########## conf/config.yaml.example: ########## @@ -141,6 +141,10 @@ apisix: # or (standalone mode) the config isn't loaded yet either via file or Admin API. # disable_upstream_healthcheck: false # A global switch for healthcheck. Defaults to false. # When set to true, it overrides all upstream healthcheck configurations and globally disabling healthchecks. +# trusted_addresses: # When configured, APISIX will trust the `X-Forwarded-*` Headers +# - 127.0.0.1 # passed in requests from the IP/CIDR in the list. +# - 172.18.0.0/16 # CAUTION: When not configured, APISIX will remove `X-Forwarded-*` headers Review Comment: override or remove? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
