Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save staticfilestorage/4f562537bd1ab4657666cdda8a957e98 to your computer and use it in GitHub Desktop.

Select an option

Save staticfilestorage/4f562537bd1ab4657666cdda8a957e98 to your computer and use it in GitHub Desktop.
用nginx搭建全能反向代理
最近有一些需求于是试着用nginx搭建一个全能的反向代理。
关键词是“全能”和“反向代理”,所以我们分开一个一个说。
反向代理
server {
listen 0.0.0.0:80;
listen [::]:80;
server_name yyy.zzz.xxx
location / {
proxy_pass http://111.222.333.444;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这个是反向代理的标准写法,相信大家都很熟悉了。
server_name表示监听yyy.zzz.xxx这个域名
location /表示这个域名中所有的请求
proxy_pass 表示把请求转发到哪里
proxy_set_header Host $host表示用原来的域名请求
下面两行是HTTP扩展头,给HTTP代理服务器(正向/反向)用的,表示用户的真实IP地址。
万能
接下来我们改造一下这个代理实现“万能”的功能,也就是”泛域名“。
server_name
nginx在很多地方都可以用正则进行匹配,server_name也不例外
语法:
server_name ~regex(pres{2})?;
然后捕捉的变量会放在$1 $2 etc.
于是我们可以用
server_name ~^(.*)\.revp\.tk$;
来匹配所有后缀为revp.tk(reverse proxy.toolkit)的域名并把前面的段抓到$1去
例如:tydus.org.revp.tk会被匹配,$1为tydus.org
proxy_pass
既然上面$1都抓到了,那么径直pass过去就好了嘛~
resolver 8.8.8.8;
proxy_pass http://$1;
注意如果proxy_pass带变量带话,这里必须要显式指定resolver,否则会出现无法解析域名(502)的状况。
Host
proxy_set_header Host $1;
注意这里的Host就不能再写$host而必须要写$1。
为了这个问题我调试了15分钟,还用tcpdump抓了包最后才发现的。
为什么要这么写就留做课后题吧=。=
其余优化
proxy_http_version 1.1;
首先把http版本设到1.1,充分利用它的keep-alive和pipelining特性。(注意在nginx 1.1.4之前不支持proxy http 1.1特性)
然后我们会发现cookie的域名也要做相应的变化,nginx也为我们做了这个工作,只需要
proxy_cookie_domain $1 $host;
总结
把上面的步骤都组合起来,就是一个完整的nginx配置了
server {
listen 0.0.0.0:80;
listen [::]:80;
server_name ~^(.*)\.revp\.tk$;
location / {
resolver 8.8.8.8;
proxy_pass http://$1;
proxy_redirect off;
proxy_http_version 1.1;
proxy_cookie_domain $1 $host;
proxy_set_header Host $1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
最后,*.revp.tk已经上线(支持IPV4和IPV6),欢迎各位使用。
更新:实现了*.$$$.revp.tk($$$为端口号),可以代理http://*:$$$/非80端口的http服务
Tags: nginx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment