这是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 的反代有一个基本的掌握了。