请求流程如下
用户请求 -> nginx -> kong 网关
需求如下 想通过 kong 网关 ip-restriction 插件 限制部分用户的真实 ip 访问接口
遇到的问题
1 、kong 网关这边获取到的 X-real-ip 一直都是 nginx 节点的 ip ,导致 ip-restriction 插件失效
nginx 部分配置
location / { proxy_pass http://a.kong.com/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }
kong 网关配置
server { server_name kong; listen 0.0.0.0:8000; error_page 400 404 408 411 412 413 414 417 494 /kong_error_handler; error_page 500 502 503 504 /kong_error_handler; access_log logs/access.log main; error_log logs/error.log notice; client_body_buffer_size 8k; real_ip_header X-Real-IP; real_ip_recursive off; set_real_ip_from 0.0.0.0/0; set_real_ip_from ::/0; include nginx-x-header.conf; location / { default_type ''; set $ctx_ref ''; set $upstream_host ''; set $upstream_upgrade ''; set $upstream_connection ''; set $upstream_scheme ''; set $upstream_uri ''; set $upstream_x_forwarded_for ''; set $upstream_x_forwarded_proto ''; set $upstream_x_forwarded_host ''; set $upstream_x_forwarded_port ''; rewrite_by_lua_block { Kong.rewrite() } access_by_lua_block { Kong.access() } proxy_http_version 1.1; proxy_set_header Host $upstream_host; proxy_set_header Upgrade $upstream_upgrade; proxy_set_header Connection $upstream_connection; proxy_set_header X-Forwarded-For $upstream_x_forwarded_for; proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto; proxy_set_header X-Forwarded-Host $upstream_x_forwarded_host; proxy_set_header X-Forwarded-Port $upstream_x_forwarded_port; proxy_set_header X-Real-IP $remote_addr; proxy_pass_header Server; proxy_pass_header Date; proxy_ssl_name $upstream_host; proxy_pass $upstream_scheme://kong_upstream$upstream_uri; header_filter_by_lua_block { Kong.header_filter() } body_filter_by_lua_block { Kong.body_filter() } log_by_lua_block { Kong.log() } } location = /kong_error_handler { internal; uninitialized_variable_warn off; content_by_lua_block { Kong.handle_error() } header_filter_by_lua_block { Kong.header_filter() } body_filter_by_lua_block { Kong.body_filter() } log_by_lua_block { Kong.log() } } }
看了下 ip-restriction 插件的源代码如下
function IpRestrictionHandler:access(conf) IpRestrictionHandler.super.access(self) local block = false local binary_remote_addr = ngx.var.binary_remote_addr if not binary_remote_addr then return responses.send_HTTP_FORBIDDEN("Cannot identify the client IP address, unix domain sockets are not supported.") end if conf.blacklist and #conf.blacklist > 0 then block = iputils.binip_in_cidrs(binary_remote_addr, cidr_cache(conf.blacklist)) end if conf.whitelist and #conf.whitelist > 0 then block = not iputils.binip_in_cidrs(binary_remote_addr, cidr_cache(conf.whitelist)) end if block then return responses.send_HTTP_FORBIDDEN("Your IP address is not allowed") end end
代码中 最后是通过 ngx.var.binary_remote_addr 这个参数来比较的,所以最终只需要这个变量的值要设置为 用户真实 ip 即可
最终做了以下调整实现
修改或验证点 .kong_env real_ip_recursive = off real_ip_header = X-Real-IP 修改 nginx-kong.conf # 添加所有 Nginx 代理服务器的 IP set_real_ip_from 192.168.1.10/32; # Nginx 服务器 1 set_real_ip_from 192.168.1.11/32; # Nginx 服务器 2 set_real_ip_from 192.168.1.12/32; # Nginx 服务器 3 # 如果 Nginx 服务器在一个网段,也可以用 CIDR 表示 set_real_ip_from 192.168.1.0/24; # 整个网段 kong的配置文件也要加上对应 # kong.conf trusted_ips = 192.168.1.10,192.168.1.11,192.168.1.12 # 或者使用网段 trusted_ips = 192.168.1.0/24 nginx 配置需要修改 对应的 location 配置需要修改 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; 最后就是 kong 插件 需要配置为全局模式
1 swq1227 267 天前 将 nginx 的 IP 添加到 kong 的 trusted_ips 中就可以获取到了 可以参考 kong gateway 的配置 https://docs.konghq.com/gateway/latest/reference/configuration/#trusted_ips |
2 5261 OP @swq1227 感谢回复,我在 kong 的配置中加了 set_real_ip_from 0.0.0.0/0; set_real_ip_from ::/0; 甚至在 kong.conf 中 加了 trusted_ips = 0.0.0.0/0,::/0 没效果 我配置后 重新执行 /usr/local/openresty/nginx/sbin/nginx -p /data/servers/kong -c nginx.conf 貌似没生效 |
3 qingzhijiusheng 267 天前 我觉得这个问题问 Claude ,你可以很快解决。 |
![]() | 5 defunct9 267 天前 开 ssh ,让我上去看看 |
![]() | 6 zpf124 267 天前 kong 网关我没用过,但我看配置和 nginx 很像。那我猜问题应该是你 kong 里的 proxy 的配置问题。 ``` // ... // 注意看这里, 你 Kong 的配置文件 这里在转发到你的负载均衡之前又一次将 X-Real-Ip 的 header 重新赋值了 // 而这里 对于 Kong 而言,访问它的 客户端就是 nginx , 所以 $remote_addr 自然就又改回 nginx 的 ip 了 proxy_set_header X-Real-IP $remote_addr; proxy_pass $upstream_scheme://kong_upstream$upstream_uri; ``` |
8 5261 OP 2025-1-21 更新 在 .kong_env 的 kong 配置文件中加入 trusted_ips 配置后,现在 X-Real-IP 是可以获取到真实的 ip 了 但奇怪的时候 kong 的 ip-restriction 插件依然是失效的,我真要懵逼了 |
9 NamelessRain 266 天前 开 ssh ,让我上去看看 |