背景:

在多租户系统实现中,如下图,由于租户的服务器IP是固定的,租户服务器直接访问管理台Nginx,其IP在Nginx是可视的,可以通过 \$remote_addr 直接取到,当然如果已经配置了 \$host 也可根据 \$host 的值判断请求来自于哪个租户服务器,实现动态设置租户号。

Nginx $proxy_add_x_forwarded_for 实现多租户判断_服务器

 

实施中,出于安全考虑,在租户服务器和管理台服务中添加一层中转服务(Nginx),但是这样的话,租户服务器的IP对于管理台Nginx就不是可见的了,管理台Nginx读取到的   \$remote_addr 值为中转Nginx的IP,Nginx中 \$proxy_add_x_forwarded_for 可以实现Nginx间的值传递,所以对其进行部分修改。

测试环境请求流转如下:

租户A(36.0.15.16)请求——>中转nginx所在服务器(36.10.8.44)——>管理台nginx所在服务器(36.10.10.118)——>后台服务

 Nginx $proxy_add_x_forwarded_for 实现多租户判断_赋值_02

步骤:

中转服务器(36.10.8.44)添加如下配置,赋值客户端ip

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://36.10.10.118:9015;
}

2. 管理台(36.10.10.118)添加如下配置,根据客户端ip进行设置租户号

server {
                listen       9015;
                server_name localhost;
                client_max_body_size 30M;
                #set $tenantId "815";
                if ($http_x_forwarded_for = "36.0.15.16") {
                        set $tenantId "815";
                }
               access_log /oscf/log/gateway-web-access.log;
               error_log /oscf/log/gateway-web-error.log;

        location ^~ /api/v4/ {
                    proxy_http_version 1.1;
                    proxy_set_header  Connection "";
                    #limit_req zone=mylimit burst=30 nodelay;
                    #limit_req_status 598;
                    proxy_next_upstream http_404 http_500 http_502 http_503 http_504  error timeout invalid_header;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_pass http://zeus.admin.web/;
                    proxy_set_header tenant-id $tenantId;
                    proxy_buffer_size 64k;
                    proxy_buffers 4 256k;
                    proxy_busy_buffers_size 512k;
                    proxy_connect_timeout 75;
                    proxy_send_timeout 12000;
                    proxy_read_timeout 12000;
        }
}

3. 36.0.15.16服务器模拟访问

Nginx $proxy_add_x_forwarded_for 实现多租户判断_客户端_03

4.多租户判断

后续增加其他租户,在管理台nginx进行判断设置即可,方法如下:

server {
                listen       9015;
                server_name localhost;
                client_max_body_size 30M;
                if ($http_x_forwarded_for = "36.0.15.16") {
                        set $tenantId "815";
                }

                if ($http_x_forwarded_for = "36.0.15.17") {
                        set $tenantId "816";
                }

               access_log /oscf/log/gateway-web-access.log;
               error_log /oscf/log/gateway-web-error.log;

        location ^~ /api/v4/ {
                    proxy_http_version 1.1;
                    proxy_set_header  Connection "";
                    #limit_req zone=mylimit burst=30 nodelay;
                    #limit_req_status 598;
                    proxy_next_upstream http_404 http_500 http_502 http_503 http_504  error timeout invalid_header;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_pass http://zeus.admin.web/;
                    proxy_set_header tenant-id $tenantId;
                    proxy_buffer_size 64k;
                    proxy_buffers 4 256k;
                    proxy_busy_buffers_size 512k;
                    proxy_connect_timeout 75;
                    proxy_send_timeout 12000;
                    proxy_read_timeout 12000;

        }