Nginx双向代理


以前做Nginx代理的时候都是单项的,要么反向,要么正向。但就是再不久前拿到一个双向代理的需求,需要即有反向代理又有正向代理。这里做个记录。

用三台机子模拟场景。简单说一下网络结构,拓扑简单的画了一下,如下图:

内网服务器IP:10.8.5.4,上面部署了tomcat并指定8989端口。nginx服务器有两块网卡,用于分别连接内网和外网,其中内网IP地址为:10.8.5.3,外网IP地址为:192.168.77.246。外网服务器IP:192.168.77.250,上面部署了两个tomcat并分别指定端口为8080和8989。

访问逻辑是内网服务器通过nginx正向代理访问外网服务器的8080和8989端口,外网服务器通过nginx反向代理访问内网服务器的8989端口。

为了方便以后的管理及维护,我不对主配置文件做修改,采用附加配置文件的方式来做,首先修改主配置文件指定附加配置文件路径。如下图:

进入这个目录创建两个配置文件,首先创建正向配置文件FWD-001.conf和FWD-002.conf,我这里要代理两个端口,为了以后管理方便我分了两个配置文件,因人而异也可以定义成一个,其中一个的配置文件内容如下:

server {
    resolver 127.0.0.1;
    listen 8080;
    #listen 443;
    proxy_intercept_errors on;
    error_page 403 404 500 502 503 504 /error-fwd-001.html;
    location / {
        #proxy_pass https://$host$request_uri;
        proxy_pass https://$host:8080$request_uri;
        #proxy_ssl_server_name on;
        #proxy_set_header Host $host;
        proxy_buffers 256 4k;
        #proxy_buffer_size 64k;
        #proxy_busy_buffers_size 128k;
        proxy_max_temp_file_size 0k;
        proxy_connect_timeout 30;
        #proxy_sand_timeout 60;
        proxy_read_timeout 60;
        #proxy_set_header Host $host:$server_port;
        #proxy_set_header X-Real-Ip $remote_addr;
        #proxy_set_header X-Forwarded-For $remote_addr;
        proxy_next_upstream error timeout invalid_header http_502;
    }

    location = /error-fwd-001.html {
        root /etc/nginx/html/;
    }
}

其中有些参数可以更具自己的需求加上或者注释。如果需要代理https,那么配置文件改写成如下内容:

server {
    resolver 127.0.0.1;
    #listen 8080;
    listen 443;
    proxy_intercept_errors on;
    error_page 403 404 500 502 503 504 /error-fwd-001.html;
    location / {
        proxy_pass https://$host$request_uri;
        #proxy_pass https://$host:8080$request_uri;
        proxy_ssl_server_name on;
        #proxy_set_header Host $host;
        proxy_buffers 256 4k;
        #proxy_buffer_size 64k;
        #proxy_busy_buffers_size 128k;
        proxy_max_temp_file_size 0k;
        proxy_connect_timeout 30;
        #proxy_sand_timeout 60;
        proxy_read_timeout 60;
        #proxy_set_header Host $host:$server_port;
        #proxy_set_header X-Real-Ip $remote_addr;
        #proxy_set_header X-Forwarded-For $remote_addr;
        proxy_next_upstream error timeout invalid_header http_502;
    }

    location = /error-fwd-001.html {
        root /etc/nginx/html/;
    }
}

需要特别注意的是如果是非标准端口80、443,需要在proxy_pass https://$host后面加上端口,否则会报502。

接下来写反向代理的配置文件RRD.conf,配置文件内容如下:

upstream RRD {
    ip_hash;
    server 10.8.5.4:8989;
}

server {
    server_name 192.168.77.246;
    listen 8989;
    proxy_intercept_errors on;
    error_page 403 404 500 502 503 504 /error-rrd.html;
    location ~ / {
        proxy_pass https://RRD;
        proxy_redirect off;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
        proxy_connect_timeout 60s;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For
        $proxy_add_x_forwarded_for;
    }

    location = /error-rrd.html {
        root /etc/nginx/html/;
    }
}

Nginx端配置完成,nginx -s reload重载配置。

====================分割线====================

正向代理客户端需要配置/etc/profile文件,在末尾加入如下内容:

export http_proxy='https://10.8.5.3:8080'
export http_proxy='https://10.8.5.3:8989'

需要注意引号里可以不加https://,不加同样可以代理,但是会导致sqlplus报错,错误信息如下:

Error 46 initializing SQL*Plus

HTTP proxy setting has incorrect value

SP2-1502: The HTTP proxy server specified by http_proxy is not accessible

正向代理客户端配置完成,重载profile文件。

source /etc/profile

====================分割线====================

在正向代理客户端尝试访问外网服务器的8080和8989,使用curl进行测试,结果如下图:

两个端口访问均返回200测试通过。

在外网端测试能否正常访问内网服务器的8989端口,同样使用curl命令,结果如下图:

返回200测试通过。

至此Nginx双向代理配置完成。