Open aibangjuxin opened 5 months ago
为了确保 Kong Gateway 能获取客户端的出口 IP 地址,您需要确保在整个请求中转途经的每一层代理都正确转发这个IP地址。
在您提供的配置中,L7 Nginx 已经设置了 X-Real-IP 和 X-Forwarded-For 头信息来转发原始客户端IP。现在关键是确保L4 Nginx 能正确地将这些信息再次转发给 Kong Gateway。
L4 Nginx的配置需要确保它不会覆盖 X-Real-IP 和 X-Forwarded-For 头信息。这通常意味着在相关的 stream 或 server 配置块中要设置相关头信息的转发,不过要注意的是,在处理TCP/SSL流量时,代理不会直接访问到HTTP头信息。
如果您的L4 Nginx是按照四层(传输层)来转发SSL/TCP连接,而没有解包HTTP层。那么L4级别的Nginx将无法修改或添加任何HTTP头部信息。在这种情况下,您需要确保L7 Nginx直接与Kong Gateway通信,或者您的L4 Nginx需要能够解包TCP流以编辑HTTP请求(这将涉及到SSL的终止和创建新的SSL连接)。
一般而言,以下两点是确保Kong Gateway获取客户端出口IP地址的关键所在:
配置L4 Nginx以支持SSL透明代理(如果L4 Nginx是负责SSL的): 配置L4 Nginx以使其能够处理SSL透明代理或者SSL中继。这通常意味着安装具备此功能的Nginx模块,使其能够进行SSL解密和重新加密,并正确转发HTTP头信息。
确保Kong正确解析X-Forwarded-For
头部:
在Kong中,您可以配置其使用X-Forwarded-For
来获取原始客户端的客户端IP。在Kong配置中确保已经启用了real_ip_recursive
并设置了trusted_ips
,使Kong能相信来自于你的Nginx代理的头信息。以下是一个配置示例:
yaml real_ip_header: X-Forwarded-For; real_ip_recursive: on; trusted_ips: 0.0.0.0/0, ::/0; # 示例配置,这里需要添加真实的Nginx代理的IP地址。
确保L4 Nginx保留了从L7 Nginx传入的X-Forwarded-For
头部。如果需要在L4进行SSL处理,就要确保SSL覆盖过程中头部信息不得丢失。或者更简单的方法是跳过L4(如果没有必须的原因让它介入HTTP头的处理),直接从L7将流量传递到Kong Gateway。如果环境和配置允许,这将减少复杂性和可能出现的错误。在决定最佳做法之前,请细致审查您的安全和架构需求。
理解到你使用的是L4级别的Nginx,它只处理TCP/SSL连接,而不会解包HTTP层内容,所以L4 Nginx不能直接修改或添加HTTP头部信息。在这种情况下,要使Kong Gateway获取客户端的真实IP地址,必须通过Nginx的proxy_protocol
来传递原始客户端IP地址。这里是详细的配置过程:
L7 Nginx仍然负责处理HTTP请求,并将原始客户端IP传递到L4 Nginx。这部分配置不会修改:
http {
server {
listen 80;
location /apiname/v1 {
if ($host !~* aibangjuxin$ ) {
return 444;
}
if ($content_type ~ (multipart/form-data|text/plain)) {
return 405;
}
rewrite ^/apiname/v1(.*)$ $1 break;
proxy_pass https://10.10.15.1:8081;
proxy_set_header Host dev-api.cn.aibang;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
在L4 Nginx上启用proxy_protocol
,以便将客户端的原始IP地址传递给下游的Kong Gateway:
stream {
server {
listen 8081 proxy_protocol; # 启用 proxy_protocol
proxy_pass 192.168.0.5:8443; # 假设 Kong Gateway 运行在 192.168.0.5:8443
proxy_protocol on; # 启用 proxy_protocol 支持
}
}
Kong Gateway必须配置为接受并解析来自proxy_protocol
的信息,以便获取客户端的真实IP地址。Kong Gateway的配置需要以下步骤:
如果Kong使用的是Nginx作为前端,那么需要配置Nginx模板以启用proxy_protocol
:
server {
listen 8443 ssl proxy_protocol; # 启用 proxy_protocol
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
location / {
proxy_pass http://upstream_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr; # 使用 proxy_protocol_addr 获取真实的客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
确保Kong的配置文件接受并解析proxy_protocol
头文件:
nginx_http_real_ip_header: "proxy_protocol"
nginx_http_real_ip_recursive: "on"
trusted_ips:
- 0.0.0.0/0
以下是更新后的流程图,展示了从L7 Nginx到Kong Gateway的请求流动过程:
graph TD
A(Client) -->|HTTPS| B(Nginx_L7)
B(Nginx_L7) -->|proxy_pass + X-Forwarded-For| C(Nginx_L4)
C(Nginx_L4) -->|proxy_pass + proxy_protocol| D(Kong_GW)
D(Kong_GW) --> E(Upstream_Service)
subgraph Network
B
C
D
end
如果启用proxy_protocol
后遇到502错误,可能的原因及解决方法包括:
确认Kong Gateway的Nginx配置:
proxy_protocol
。检查Kong Gateway日志:
确保端口和协议匹配:
同步配置文件:
通过以上配置和故障排除步骤,可以确保Kong Gateway能够获取并使用客户端的真实IP地址。
在L4层Nginx中启用proxy_protocol
后,出现502错误并且报104: connection reset by peer while SSL handshaking to upstream
,通常是因为上游服务器没有正确配置为接收proxy_protocol
,或者配置不完全。让我们详细解释并正确配置这些步骤,确保proxy_protocol
在各层之间正确传递和解析。
首先,L7 Nginx负责处理HTTP请求并将其转发到L4 Nginx,同时传递原始客户端IP地址:
http {
server {
listen 80;
location /apiname/v1 {
if ($host !~* aibangjuxin$ ) {
return 444;
}
if ($content_type ~ (multipart/form-data|text/plain)) {
return 405;
}
rewrite ^/apiname/v1(.*)$ $1 break;
proxy_pass https://10.10.15.1:8081;
proxy_set_header Host dev-api.cn.aibang;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
L4 Nginx负责接收从L7 Nginx传来的请求,并使用proxy_protocol
将其转发到Kong Gateway:
stream {
server {
listen 8081 proxy_protocol;
proxy_pass 192.168.0.5:8443; # 假设 Kong Gateway 运行在 192.168.0.5:8443
proxy_protocol on;
}
}
确保Kong Gateway配置正确接收和解析proxy_protocol
头信息。假设Kong Gateway使用Nginx作为前端:
Kong 的 Nginx 模板配置:
在Kong的Nginx模板配置文件中,启用proxy_protocol
:
server {
listen 8443 ssl proxy_protocol; # 启用 proxy_protocol
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
location / {
proxy_pass http://upstream_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr; # 使用 proxy_protocol_addr 获取真实的客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Kong 配置文件:
确保在Kong的配置文件中设置了正确的头信息解析:
nginx_http_real_ip_header: "proxy_protocol"
nginx_http_real_ip_recursive: "on"
trusted_ips:
- 0.0.0.0/0
确认上游服务器配置:
确认Kong Gateway的Nginx配置正确接受proxy_protocol
。特别是listen
指令中的proxy_protocol
:
listen 8443 ssl proxy_protocol;
检查SSL配置:
确保SSL证书和私钥路径正确,并且SSL配置没有问题。
查看日志文件:
检查Nginx和Kong Gateway的错误日志,以获取更详细的错误信息。
协议和端口匹配:
确认所有层之间的协议和端口设置一致。
以下是更新后的流程图,展示从L7 Nginx到Kong Gateway的请求流动过程:
graph TD
A(Client) -->|HTTPS| B(Nginx_L7)
B(Nginx_L7) -->|proxy_pass + X-Forwarded-For| C(Nginx_L4)
C(Nginx_L4) -->|proxy_pass + proxy_protocol| D(Kong_GW)
D(Kong_GW) --> E(Upstream_Service)
subgraph Network
B
C
D
end
假设你有一个基本的设置,以下是各个部分的示例配置:
L7 Nginx:
http {
server {
listen 80;
location /apiname/v1 {
if ($host !~* aibangjuxin$ ) {
return 444;
}
if ($content_type ~ (multipart/form-data|text/plain)) {
return 405;
}
rewrite ^/apiname/v1(.*)$ $1 break;
proxy_pass https://10.10.15.1:8081;
proxy_set_header Host dev-api.cn.aibang;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
L4 Nginx:
stream {
server {
listen 8081 proxy_protocol;
proxy_pass 192.168.0.5:8443;
proxy_protocol on;
}
}
Kong Gateway:
server {
listen 8443 ssl proxy_protocol;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
location / {
proxy_pass http://upstream_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Kong 配置文件:
nginx_http_real_ip_header: "proxy_protocol"
nginx_http_real_ip_recursive: "on"
trusted_ips:
- 0.0.0.0/0
通过确保各层之间的proxy_protocol
配置正确,应该能够解决502错误并让Kong Gateway获取到客户端的真实IP地址。
要让 Kong Gateway 获取到客户端的真实 IP 地址,你需要在 Kong 的配置中指定获取客户端 IP 的方式。Kong 支持从不同的 HTTP 头中获取客户端 IP,包括
X-Forwarded-For
和X-Real-IP
。以下是一些建议:
在 Kong 的配置文件中,你可以指定从哪个 HTTP 头中获取客户端 IP。例如,如果你想从
X-Real-IP
头中获取 IP,可以这样配置:由于 Nginx L7 已经在
X-Real-IP
头中设置了客户端 IP,你可以让 Nginx L4 转发这个头部到 Kong Gateway。在 Nginx L4 的配置中添加:这样 Kong Gateway 就可以从
X-Real-IP
头中获取客户端真实 IP 了。如果你更倾向于使用
X-Forwarded-For
头,可以在 Nginx L4 中这样配置:然后在 Kong 中配置从
X-Forwarded-For
头获取 IP:通过上述配置,Kong Gateway 应该可以获取到客户端的真实出口 IP 地址了。记得在做任何更改后重新加载 Nginx 和 Kong 的配置。