Nginx域名转发(反向代理)

Author Avatar
Reborn 8月 23, 2018
  • 在其它设备中阅读本文章

参考:

背景

在开发过程中,有时候我们会有一个这样的需求:访问m.XXX.com的时候,需要实际访问www.YYY.com/m,并且域名不能发生变化(这种也可称为镜像?)。

达成这个需求可以使用Nginx,有两种做法:

  • 第一种就是301跳转,使用rewrite来跳转域名,不过这样域名就会发生变化,与需求不符。
  • 第二种就是用proxy_pass跳转,只要指定跳转目的域名,就可以在访问的时候自动跳转访问目的域名,而且域名也不会发生变化。所以这里需要使用第二种方法。

配置文件示例

以下教程 域名以m.XXX.com为例,被镜像网站以www.YYY.com/m为例

然后访问你的域名看一看是否成功镜像,需要注意的一点是,如果被镜像的网站设置了防盗链,那么静态文件(js/css/图片)可能无法显示,这就没办法了。

参数解释

一般情况下只需要更改这几个参数。

server_name 你的域名;

sub_filter 欲被镜像的域名 你的域名;

proxy_set_header Referer http://欲被镜像的域名;

proxy_set_header Host 欲被镜像的域名;

proxy_pass http://欲被镜像的域名;

建立 Nginx 配置文件

首先
/etc/nginx/sites-available/建立一个m.XXX.com.conf配置文件,内容参考HTTP 示例HTTPS 示例

HTTP 示例

以下示例是以m.XXX.com镜像www.YYY.com/m为例。自行替换 其中的参数:

第二段是 屏蔽搜索引擎收录,比如镜像自己的网站,如果不屏蔽会导致 收录流失。

注意:不管你是镜像 www.baidu.com 还是 www.google.com.hk (不要直接使用 .com 会被谷歌自动根据VPS所在地区重定向的),他们两个目前都是强制重定向到 https ,这意味着如果你只配置了 http 反向代理,那么访问反向代理域名后会重定向到 https 的目标域名,所以你也必须配置 https 才行。

# 下面这段代码才是 HTTP 完整示例配置文件,注意使用时修改里面的默认域名等信息。
server {
        listen 80;
        server_name m.XXX.com;

        if ($http_user_agent ~* (baiduspider|360spider|haosouspider|googlebot|soso|bing|sogou|yahoo|sohu-search|yodao|YoudaoBot|robozilla|msnbot|MJ12bot|NHN|Twiceler)) {
          return  403;
        }

        location / {
          sub_filter www.YYY.com m.XXX.com;
          sub_filter_once off;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Referer http://www.YYY.com;
          proxy_set_header Host www.YYY.com;
          proxy_pass http://www.YYY.com/m;
          proxy_set_header Accept-Encoding "";
        }
}

HTTPS 示例

当你要镜像的网站不开放 HTTP 或者 强制HTTPS 的时候,你就需要加上 SSL 来转成 HTTPS 了。

假设SSL证书文件位置是:/root/ssl.crt

假设SSL密匙文件位置是:/root/ssl.key

第二段的 301 代码是,强制走HTTPS,如果不需要可以去掉。

第三段是 屏蔽搜索引擎收录,比如镜像自己的网站,如果不屏蔽会导致 收录流失。

同时下面这两个选项的记得把http://改成https://

proxy_set_header Referer https://www.YYY.com;
proxy_pass https://www.YYY.com/m;
# 下面这段代码才是 HTTPS 完整示例配置文件,注意使用时修改里面的默认域名等信息。
server
    {
        listen 80;
        listen 443 ssl;
        ssl on;
        ssl_certificate /root/ssl.crt;
        ssl_certificate_key /root/ssl.key;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout  10m;
        server_name m.XXX.com;
        add_header Strict-Transport-Security "max-age=31536000";

        if ( $scheme = http ){
            return 301 https://$server_name$request_uri;
        }

        if ($http_user_agent ~* (baiduspider|360spider|haosouspider|googlebot|soso|bing|sogou|yahoo|sohu-search|yodao|YoudaoBot|robozilla|msnbot|MJ12bot|NHN|Twiceler)) {
          return  403;
        }

        location / {
          sub_filter www.YYY.com m.XXX.com;
          sub_filter_once off;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header Referer http://www.YYY.com;
          proxy_set_header Host www.YYY.com;
          proxy_pass http://www.YYY.com/m;
          proxy_set_header Accept-Encoding "";
        }
}

注意事项

  1. 若是转发的地址含二级目录如:www.YYY.com/m,只需要把proxy_pass值修改为具体地址即可,若是不行则将proxy_set_header值也修改为具体地址。
  2. 若是你输入的地址中要有二级目录如m.XXX.com/tools/a,则location模块要改为:

     location /tools/a {
           // ...
       }