南琴浪博客

Nginx 基础教程(二)反向代理

01/04/2018

这是Nginx 基础教程系列的第二篇文章。本文介绍 Nginx 作为反向代理的基本用法。

反向代理和源站的区别

首先有必要说明下:反向代理 和 源站 的区别

对于一个网站所包含的内容(数据)来说:如果你就是源站,网站的所有数据的第一手来源都是你,所有响应的数据都由你决定;而如果你的网站只是一个反向代理,那么你的网站的数据就来源于被你反代的那个网站,虽然你可以对反代来的这些数据进行更改后再作为响应返回给客户,但是网站数据的第一手来源不是你

以上所述区别,在 Nginx 配置文件上的体现,这里仅举出下列几个例子:

  • root 与 proxy_pass
  • add_header 与 proxy_set_header
  • buffer 与 proxy_buffer

配置项的组成

Nginx 作为反向代理时的配置项,可以含有以下的基本组成部分:

  • proxy_pass
  • proxy_redirect
  • proxy_set_header
  • proxy_hide_header
  • sub_filter
  • proxy_cache
  • proxy_buffer
  • 其它等等

其中,proxy_pass 是必选项,作用是指定你要反代的网站,值的含义是 scheme+host+port,例如 proxy_pass https://www.google.com:443;

proxy_redirect 可选项,指定是否允许对源站的 host 进行 rewrite,值为 on 或 off,例如 proxy_redirect off;

proxy_set_header 可选项,作用是对 http request header 进行修改后,发送给源站。

proxy_hide_header 可选项,作用是不将来自源站的指定的 header 返回给客户,即隐藏来自源站的 header。

sub_filter 可选项,替换源站数据中的指定字符串。

proxy_cache 可选项,对反代后返回的数据进行缓存。使用方法请看我的这篇文章:Nginx 启用 proxy_cache 缓存

proxy_buffer 可选项,对反代启用 buffer 区缓存。使用方法请看我的这篇文章:Nginx 启用 proxy_buffer 缓冲

基本配置

上文已提到,Nginx 作为反向代理时,只有一个必需项 – proxy_pass。所以,以反代 github 为例,最简单的站点配置就可以写成这样:

server {
    # 监听端口,其实可以随意
    listen  80;

    # 你的反代的域名
    server_name  你的反代的域名;

    # 记录访问日志
    access_log   /home/site/access.log;

    location / {
        proxy_pass  https://github.com;
    }
}

进阶配置

上文所述的基本配置,对于 Nginx 的配置来说的确已可行。但在实际使用过程中,这样只有一行 proxy_pass 的反代可能会遇到各种麻烦。所以这时就需要一些增强功能,那就是上文提到的可选项。

最常见的可选项就是 proxy_set_header 了。这里介绍它的用法。

上文已提到,proxy_set_header 的作用是对 http request header 进行修改后,发送给源站

在常见的网站访问中,HTTP 过程通常包括了 request header 和 response header 两部分的响应头。客户对网站发出访问请求时,会对网站发送 request header;而网站向客户返回网站内容时,会对客户发送 response header。那么,proxy_set_header 就是适用于前者的情况。

来举个例子:

proxy_set_header  Host "github.com";

当你访问一个 github 的反代网站时,你对这个网站发出的 request header 的 Host 的值就是你的这个反代站点的 host,你的 Nginx 反代会将这个值原封不动的发送给 github。而当我在 Nginx 上写入上述一行配置后,你的 Nginx 反代发送给 github 源站的值就不再是你的这个反代站点的 host 了,而是会更改为我指定的 github.com 这个值。这样做的好处就在于能避免源站因为 request header Host 的值不是源站的 host 而将你判定为异常流量这种问题的发生。

那么,根据以上所述,我可以写一个加入了 proxy_set_header 部分后的 github 反代:

server {
    # 监听端口,其实可以随意
    listen  80;

    # 你的反代的域名
    server_name  你的反代的域名;

    # 记录访问日志
    access_log   /home/site/access.log;

    location / {
        # 指定我要反代的网站是 github
        proxy_pass  https://github.com;

        # 修改 request header Host 的值
        proxy_set_header  Host          "www.google.com";

        # 修改 request header Referer 的值
        proxy_set_header  Referer       https://www.google.com;

        # 修改 request header remote_addr 的值
        proxy_set_header  X-Real-IP     $remote_addr;

        # 修改 request header user_agent 的值
        proxy_set_header  User-Agent    $http_user_agent;
    }
}

关于反向代理更完全的配置,我之前写过 Nginx 反代谷歌的系列教程,结合 这篇文章 一起阅读后,就能对 Nginx 的反代有一个基本的掌握了。