Nginx在实际场景中的妙用: 基础用法 && 解决跨域 && 访问Google

352 阅读2分钟

Nginx在实际场景中的妙用

首先,来了解下Nginx是干什么用的?

负载均衡

  • 将请求分摊到多个操作单元上进行执行
  • 负载均衡策略:
    • RR(默认): 顺序轮询访问
    • 权重:指定访问比例
    • ip_hash: 同一客户端访问同一服务
    • fair: 按后端服务器的响应时间来分配请求,响应时间短的优先分配。
    • url_hash:固定地址访问固定服务
upstream google{
    # 服务器上能访问到google的IP地址,可以通过命令:nslookup www.google.com 解析其IP获取
    server 108.177.125.199:443 weight=1 fail_timeout=10s;
    server 64.233.189.199:443 weight=1 fail_timeout=10s;
    server 172.217.24.68:443 weight=1 fail_timeout=10s;
    keepalive 16;
}

Http服务器

  • 部署静态资源服务器
  • 部署前端HTML代码
server {
        listen 80;
        server_name edu.seewo.com;

        location /res/ {
            root /home/www/res/
            index index.html
        }
}

# 访问地址:https://edu.seewo.com/res/head/1/default.png

反向代理

  • 反向代理:以代理服务器来接收请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给请求连接的客户端,客户端并不知道源服务器地址。
  • Nginx做的最多的一件事。
server {
        listen 80;
        server_name backend.fatwo.cn;

        location / {
            proxy_pass http://localhost:18880;
        }
}

正向代理

  • 为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
server {
        resolver 114.114.114.114 8.8.8.8
        resolver_timeout 5s;
        listen 88;

        location / {
            proxy_pass http://$host$request_uri;
        }
}

URL重写

server {
    rewrite 规则 定向路径 重写类型;
}
  • 规则:可以是字符串或者正则来表示想匹配的目标url
  • 定向路径:表示匹配到规则后要定向的路径,如果规则里有正则,则可以使用$index来表示正则里的捕获分组
  • 重写类型:
    • last :相当于Apache里德(L)标记,表示完成rewrite,浏览器地址栏URL地址不变
    • break;本条规则匹配完成后,终止匹配,不再匹配后面的规则,浏览器地址栏URL地址不变
    • redirect:返回302临时重定向,浏览器地址会显示跳转后的URL地址
    • permanent:返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
# 案例:
# 将静态资源访问的路由转发到后台服务,支持后台可配置。

server {
        listen 80;
        server_name edu.seewo.com;

        rewrite /res/App.config /api/v1/public/sign/no/appConfig last;
}

# 访问地址:http://edu.seewo.com/res/App.config

通过Nginx如何解决浏览器跨域?

背景

  • 浏览器的同源策略:两个页面的协议、端口、主机都相同则同源。
案例:
当前页面:http://frontend.fatwo.cn/ 访问以下资源的结果:
访问URL结果
frontend.fatwo.cn/apis?api=IN…允许
frontend.fatwo.cn/apis?api=IN…跨域:不同协议
backend.fatwo.cn/api/v1/info跨域:不同域名
frontend.fatwo.cn:81/apis?api=IN…跨域:不同端口
  • 同源策略目的:安全考虑。避免不必要的攻击。CSRF攻击就是利用它来实现。

如何解决:

不同资源通过Nginx配置成同源:

  • 前端-》访问同域Node层 -》转发到后台接口 同源
  • 前端-》访问nginx配置的同域接口 -》转发到后台接口 同源

通过Nginx配置前后端服务同域

upstream  frontend-web{
    server frontend.fatwo.cn weight=1 fail_timeout=20s;
    keepalive 16;
}
upstream  backend-server{
    server backend.fatwo.cn weight=1 fail_timeout=20s;
    keepalive 16;
}
server {
        listen 80;
        server_name  frontend.fatwo.cn;

        location / {
                proxy_pass http://frontend-web/;
                proxy_redirect      off;
                proxy_set_header    Cookie $http_cookie;
                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 /backend/ {
                proxy_pass http://backend-server/;
                proxy_redirect      off;
                proxy_set_header    Cookie $http_cookie;
                proxy_set_header    Host "backend.fatwo.cn";
                proxy_set_header    X-Real-IP $remote_addr;
                proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for; 
        }
}

被访问的资源配置允许跨域: CORS (跨域资源共享)

  • 前端-》访问后台支持JSONP方式的接口,输出回调js设置数据到回调函数,不推荐
  • 前端-》资源允许跨域(Nginx层、后台服务层),需要严谨处理

通过Nginx解决跨域的配置:

    add_header 'Access-Control-Allow-Origin' "http://frontend.fatwo.cn";
    add_header 'Access-Control-Allow-Credentials' "true";
    if ($request_method = "OPTIONS") {
        add_header 'Access-Control-Max-Age' 86400;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
        add_header 'Access-Control-Allow-Headers' 'reqid, nid, host, x-real-ip, x-forwarded-ip, event-type, event-id, accept, content-type';
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain, charset=utf-8';
        return 200;
    }

如何通过Nginx访问被墙的google?

需要做一些前期准备

准备内容原因
域名:search.fatwo.cn(可不备案),免费域名申请可上 www.freenom.com用于代理转发到:www.google.com
域名的SSL证书(腾讯云上面申请的免费SSL证书,1年期)谷歌需要用https协议来访问,可降低被墙风险。
一个香港服务器:47.244.200.85可正常访问谷歌的中转服务器
Nginx配置好反向代理将访问到search.fatwo.cn域名的请求反向代理到https://www.google…

相关Nginx配置如下:

# 通过nslookup获取到的谷歌服务列表
upstream google{
    # 服务器上能访问到google的IP地址,可以通过命令:nslookup www.google.com 解析其IP获取
    server 108.177.125.199:443 weight=1 fail_timeout=10s;
    server 64.233.189.199:443 weight=1 fail_timeout=10s;
    server 172.217.24.68:443 weight=1 fail_timeout=10s;
    keepalive 16;
}

server{
    listen 80;
    server_name search.fatwo.cn;
    listen       443 ssl;
    ssl on;
    ssl_certificate /etc/nginx/https/search.fatwo.cn/1_search.fatwo.cn_bundle.crt;
    ssl_certificate_key /etc/nginx/https/search.fatwo.cn/2_search.fatwo.cn.key;
    access_log  /home/logs/google.fatwo.cn.access.log  main;

    set $toDomain 'www.google.com';
    set $sourceDomain 'search.fatwo.cn';

    location / {
        proxy_redirect off;
        proxy_cookie_domain $toDomain $sourceDomain;
        proxy_pass https://google;
        proxy_connect_timeout 60s;
        proxy_read_timeout 5400s;
        proxy_send_timeout 5400s;

        proxy_set_header Host $toDomain;
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header Referer https://$toDomain;
        proxy_set_header Accept-Encoding "";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Accept-Language "zh-CN";

    }

    # 防止网络爬虫,另一个方法是网站根目录下创建Robots.txt
    #forbid spider
    if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot")
    {
        return 403;
    }
}