多台图片服务器下 nginx 自动匹配图片

需求:有图片服务器,A、B、C、D,由于某种原因,读取图片时,不知道图片在哪台机器上。所以用 nginx 来判断图片在哪台机器上。

upstream test.com {
    server t2.com:80;
    server t3.com:80;
    server t4.com:80;
}
server {
    listen       80;
    server_name  test.com;
    root /var/www/test.com;
    access_log  logs/test.log  main;

    location / {
        try_files $uri @proxy;
    }
    location @proxy {
        proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
        proxy_pass http://test.com;
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

参考资料

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream

Nginx 安装 Lua 支持

Nginx 支持 Lua 需要安装 lua-nginx-module 模块,一般常用有 2 种方法:

  • 编译 Nginx 的时候带上 lua-nginx-module 模块一起编译

  • 使用 OpenResty: Nginx + 一些模块,默认启用了 Lua 支持

OpenResty is just an enhanced version of Nginx by means of addon modules anyway. You can take advantage of all the exisitng goodies in the Nginx world.

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。

OpenResty

OpenResty 的安装很方便,Mac 里使用 brew 安装,对于一些常见的 Linux 发行版本,OpenResty® 提供 官方预编译包,CentOS 使用 yum,Ubuntu 使用 apt-get,具体请参考 https://openresty.org/cn/installation.html,以下以 Mac 和 CentOS 7 中安装 OpenResty 为例。

Mac 使用 OpenResty

  • 终端执行 brew install homebrew/nginx/openresty 把 OpenResty 安装到 /usr/local/Cellar/openresty

  • 终端执行 openresty -V 可以从输出信息中发现 Nginx 的配置文件为 /usr/local/etc/openresty/nginx.conf

  • 启动 Nginx,2 种启动方式都可以

    • sudo openresty (openresty 其实就是 nginx 的软连接)

    • sudo nginx (把 /usr/local/Cellar/openresty/1.11.2.5/nginx/sbin 添加到 PATH 里,注意不同版本时的路径不同)

    • 查看是否启动了 nginx: ps -ef | grep nginx

  • 测试是否支持 Lua

1、/usr/local/etc/openresty/nginx.conf 中添加

location /lua {
    default_type 'text/html';
    content_by_lua 'ngx.say("hello world");';
}

2、nginx -t 测试配置没问题,然后 nginx -s reload 重新加载配置 (nginx -s stop 关闭 Nginx)

3、curl http://localhost/lua 输出 hello world 则说明 Nginx 支持 Lua

CentOS 7 使用 OpenResty

  • 终端执行下面 3 条命令把 OpenResty 安装到 /usr/local/openresty
sudo yum install yum-utils
sudo yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
sudo yum install openresty
  • Nginx 的配置文件位于 /usr/local/openresty/nginx/conf/nginx.conf (openresty -V 中没有指定)

  • 启动 Nginx,2 种启动方式都可以

    • sudo openresty

    • sudo nginx

    • 查看是否启动了 nginx: ps -ef | grep nginx

  • 测试是否支持 Lua: 参考上面的方法

编译 Nginx + Lua

编译 Nginx 需要先准备好下面的这些工具,如果不确定是否已安装,可以在编译的时候根据出现的错误提示再进行安装

  • yum install -y gcc g++ gcc-c++

  • yum -y install zlib zlib-devel openssl openssl–devel pcre pcre-devel

Nginx 支持 Lua 需要依赖 LuaJIT-2.0.4.tar.gz,ngx_devel_kit,lua-nginx-module,下面介绍具体的编译过程 (都下载到 /root 目录)

1、下载安装 LuaJIT-2.0.4.tar.gz

wget -c http://luajit.org/download/LuaJIT-2.0.4.tar.gz
tar xzvf LuaJIT-2.0.4.tar.gz
cd LuaJIT-2.0.4
make install PREFIX=/usr/local/luajit
# 添加环境变量
export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0

2、下载解压 ngx_devel_kit

wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz
tar -xzvf v0.3.0.tar.gz

3、下载解压 lua-nginx-module

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.8.tar.gz
tar -xzvf v0.10.8.tar.gz

4、下载安装 nginx-1.10.3.tar.gz

wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -xzvf nginx-1.10.3.tar.gz
cd nginx-1.10.3
# 注意ngx_devel_kit和lua-nginx-module 以实际解压路径为准
./configure --add-module=/root/ngx_devel_kit-0.3.0 --add-module=/root/lua-nginx-module-0.10.8
make -j2
make install

5、支持 Nginx 被安装到了 /usr/local/nginx,配置文件为 /usr/local/nginx/conf/nginx.conf

6、验证

  • 将 nginx 做成命令: ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

  • /usr/local/nginx/conf/nginx.conf 中添加 Lua 测试代码

location /lua {
    default_type 'text/html';
    content_by_lua 'ngx.say("hello world");';
}
  • 启动 Nginx: sudo nginx

  • curl http://localhost/lua 输出 hello world 则说明 Nginx 支持 Lua

Nginx 验证 Token

为了提高效率,常把 Nginx 作为静态文件服务器,把视频文件,JS,CSS 等放到 Nginx 上。例如我们要开发一个视频网站,免费视频不需要访问权限验证,收费视频就需要对用户的权限进行验证,验证通过了才能够继续访问,Nginx 可以借助 Lua 来实现访问验证,用户信息使用 token 表示

  • 计算 token: md5(appId+appKey)

  • 请求的链接从应用服务器上动态获取,请求参数带上 appId 和 token: http://localhost/private/tih.mp4?appId=app_1&token=1409dc951714a8226032e0b0fb60bdb0

  • Nginx 接收到请求的时候,根据 appId 找到 appKey,然后 token2 = ngx.md5(appId+appKey),token2 和请求中的 token 比较,如果相等则验证通过放行访问,否则禁止访问

Nginx 简单的验证代码如下:

location ~ /private/.+.mp4$ {
    root html;
    access_by_lua '
        -- 应用的 ID 和 key,和应用服务器上的一致
        local appIdKeys = {["app_1"] = "key_1", ["app_2"] = "key_2"};
        local args   = ngx.req.get_uri_args();
        local appId  = args["appId"];
        local appKey = appIdKeys[appId];
        local token1 = args["token"]; -- 参数中 token
        local token2 = ngx.md5(appId .. appKey); -- 用应用的 ID 找到对应的 key,然后根据算法计算 token
        -- 如果参数中的 token 和计算得到的 token 不相等,则说明访问非法,禁止访问,否则放行访问
        if token1 ~= token2 then
            ngx.exit(ngx.HTTP_FORBIDDEN);
        end
    ';
}

Nginx 和应用服务器上同时存储 appId 和 appKey,这样就能根据参数中的 appId 查找到对应的 appKey。至于使用 Lua 的变量存储,或者使用数据库,还是文件,根据具体的情况而定(Nginx 中 Lua 能够访问数据、Redis 等)。

上面的验证规则比较简单,如果其他人得到了 token,就可以无限制的访问了,为了增强安全性,可以使用更多的参数生成 token,例如用户 id,限制 URL 期限的时间戳等。

Nginx 默认没有安装 Lua 模块,需要自己安装,可参考 http://qtdebug.com/mac-nginx-lua

nginx+nginx_lua实现WAF防护功能

nginx_lua

nginx_lua模块是nginx的第三方模块,它可以将lua语言嵌入到nginx配置中,从而极大的扩展了nginx的能力,nginx以高并发而知名,而lua作为嵌入式语言轻便,两者的结合可以做到在nginx层就实现编程,而这里我们加入waf的lua过滤编程来实现waf。

安装

需要的程序包:

  • nginx

  • nginx_devel_kit(拓展nginx服务器核心功能的模块)

  • lua-nginx-module(nginx_lua模块)

  • nginx_lua_waf(waf策略 web应用防火墙)

  • LuaJIT(c实现的lua解释器)

LuaJIT

下载网站:

~]# wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz
~]# tar xf LuaJIT-2.0.5.tar.gz
~]# cd LuaJIT-2.0.5
~]# make -j 2 && make install

lib和include是直接放在/usr/local/lib和/usr/local/include

设置环境变量(nginx编译时需要)

~]# ~]# vim /etc/profile.d/LuaJIT.conf
export LUAJIT_LIB=/usr/local/lib
export LUAJIT_INC=/usr/local/include/luajit-2.0
export LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH
~]# . /etc/profile.d/LuaJIT.conf

nginx_devel_kit

第三方模块,我们可以到nginx wiki是查找:www.nginx.com/resources/wiki/modules/index.html

~]# git clone https://github.com/simpl/ngx_devel_kit

lua-nginx-module

~]# git clone https://github.com/openresty/lua-nginx-module

nginx

编译nginx_devel_kit和lua-nginx-module进nginx

~]# wget http://nginx.org/download/nginx-1.12.1.tar.gz
~]# tar xf nginx-1.12.1.tar.gz
~]# cd nginx-1.12.1
~]# yum install -y openssl-devel pcre-devel
~]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=../ngx_devel_kit --add-module=../lua-nginx-module --user=nginx --group=nginx

nginx_lua_waf

~]# wget -c https://github.com/loveshell/ngx_lua_waf/archive/master.zip
~]# mkdir -p /usr/local/nginx/conf/waf
~]# unzip master.zip 
~]# cd ngx_lua_waf-master
~]# cp -rf * /usr/local/nginx/conf/waf/
~]# mkdir -p /usr/local/nginx/logs/hack
~]# chown -R nginx /usr/local/nginx/logs/hack

nginx_lua_waf的用途

  • 防止sql注入,本地包含,部分溢出,fuzzing测试,xss,SSRF等web攻击

  • 防止svn/备份之类文件泄漏

  • 防止ApacheBench之类压力测试工具的攻击

  • 屏蔽常见的扫描黑客工具,扫描器

  • 屏蔽异常的网络请求

  • 屏蔽图片附件类目录php执行权限

  • 防止webshell上传

nginx_lua_waf的使用

nginx安装路径假设为:/usr/local/nginx/conf/
在nginx.conf的http段添加

lua_need_request_body on;
      lua_package_path "/usr/local/nginx/conf/waf/?.lua";
      lua_shared_dict limit 10m;
      init_by_lua_file  /usr/local/nginx/conf/waf/init.lua; 
      access_by_lua_file /usr/local/nginx/conf/waf/waf.lua;

配置config.lua里的waf规则目录(一般在waf/conf/目录下)

RulePath = "/usr/local/nginx/conf/waf/wafconf/"

config.lua 配置说明

RulePath = "/usr/local/nginx/conf/waf/wafconf/"
      --规则存放目录
      attacklog = "off"
      --是否开启攻击信息记录,需要配置logdir
      logdir = "/usr/local/nginx/logs/hack/"
      --log存储目录,该目录需要用户自己新建,切需要nginx用户的可写权限
      UrlDeny="on"
      --是否拦截url访问
      Redirect="on"
      --是否拦截后重定向
      CookieMatch = "on"
      --是否拦截cookie攻击
      postMatch = "on" 
      --是否拦截post攻击
      whiteModule = "on" 
      --是否开启URL白名单
      black_fileExt={"php","jsp"}
      --填写不允许上传文件后缀类型
      ipWhitelist={"127.0.0.1"}
      --ip白名单,多个ip用逗号分隔
      ipBlocklist={"1.0.0.1"}
      --ip黑名单,多个ip用逗号分隔
      CCDeny="on"
      --是否开启拦截cc攻击(需要nginx.conf的http段增加lua_shared_dict limit 10m;)
      CCrate = "100/60"
      --设置cc攻击频率,单位为秒.
      --默认1分钟同一个IP只能请求同一个地址100次
      html=[[Please go away~~]]
      --警告内容,可在中括号内自定义
      备注:不要乱动双引号,区分大小写

waf.conf 自定义过滤规则

  • args里面的规则get参数进行过滤的

  • url是只在get请求url过滤的规则

  • post是只在post请求过滤的规则

  • whitelist是白名单,里面的url匹配到不做过滤

  • user-agent是对user-agent的过滤规则

注意:默认开启了get和post过滤,需要开启cookie过滤的,编辑waf.lua取消部分–注释即可

WAF测试

未分类

看下日志:

hack]# tail -f localhost_2017-09-16_sec.log 
10.211.55.2 [2017-09-16 14:01:40] "GET localhost/?id=select%20*%20from%20mysql;" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0" "select.+(from|limit)"
10.211.55.2 [2017-09-16 14:05:51] "GET localhost/?id=union%20select%20*%20from%20mysql;" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:56.0) Gecko/20100101 Firefox/56.0" "select.+(from|limit)"

从日志中我们可以看见我么测试的url的args请求触发了那条规则。

从config.lua中我们还可以看见cc防护,测试下:

~]# cat /usr/local/nginx/conf/waf/config.lua
...
CCDeny="on"     #开启cc防护
CCrate="5/60"   #降低触发阀值便于测试
...
~]# nginx -s reload

测试结果,当我在1分钟频繁请求超过5次,返回404错误,最后结果返回的是503错误,当我们停止访问,过一会就可以恢复访问,经过测试这个防护是针对请求ip的,证明cc防护还是可以达到一定的效果的。

未分类

这是nginx+lua的一种扩展,而nginx的另一个分支openresty将nginx与lua做了很多扩展,有空一定需要好好研究下。

CentOS下Nginx的HTTPS配置

在前面的博客里也到了nginx的安装,现在需要给网站添加安全证书的达到可以实现https请求的功能。

1. 首先我们需要一个证书

可以使用自签名的证书(如何自签可以网上搜索下),虽然可以使用但不会被chrome,firefox,Safari等浏览器认可。

也可以去网上购买证书,加个几百元到上万元不等可以自行选择合适价位的证书,不过我在阿里云的购买证书上发现了赛门铁克的0元dv ssl可以使用一年,初次使用推荐去购买一个。

2. nginx的ssl模块安装

安装时直接./configure是不会安装ssl模块的,需要加上

./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  --with-http_realip_module 
make
make install

3. nginx的ssl配置

添加新的server代码块用来监听443端口

... 

#服务器的集群  
upstream  tomcats {  #服务器集群名字   
   server    127.0.0.1:8080  weight=10;#服务器配置   weight是权重的意思,权重越大,分配的概率越大。  
   #server    127.0.0.1:28080  weight=2;  
}  

server {
     listen     443;
     server_name  www.xxx.com;

     ssl on; 

     ssl_certificate   /usr/local/cert/证书名.pem;
     ssl_certificate_key  /usr/local/cert/证书名.key;
     ssl_session_timeout 5m;
     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
     ssl_prefer_server_ciphers on;

    location / {
        root html;
        proxy_pass http://tomcats;        
        index index.html index.htm;
    }



}
...

4. 将http重定向到https

server { 
listen 80; 
server_name www.xxx.com;
#添加下面这条代码  
rewrite ^(.*)$  https://$host$1 permanent; #用于将http页面重定向到https页面

  location / {
    root html;
    proxy_pass http://tomcats;
    index index.html index.htm;
}

5. 重启nginx

/usr/local/nginx/sbin/nginx -s reload

Nginx不安全配置可能导致的安全漏洞

前言:

Nginx (engine x) 是一个高性能的http和反向服务器,也可以作为IMAP/POP3/SMTP服务器。t engine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。

在渗透测试过程中发现很多网站使用了nginx或者tenginx来做反向代理,ningx的配置文件nginx.conf的一些错误配置可能引发一些安全漏洞。下面是总结的一些可能引发安全问题的错误配置,并且推荐了github上一款用于检测nginx安全配置的工具。

Ningx.conf配置一共分为4部分:1.顶级配置2.Events 模块3.http部分 4.server部分

0×00任意文件读取

这个常见于Nginx做反向代理的情况,动态的部分被proxy_pass传递给后端端口,而静态文件需要Nginx来处理。假设静态文件存储在/home/目录下,而该目录在url中名字为files,那么就需要用alias设置目录的别名:

location /files {
    alias /home/;
}

此时访问http://127.0.0.1:8080/files/1.txt,就可以获取/home/1.txt 文件。

未分类

我们发现,url上/files没有加后缀/ ,而alias设置的/home/是有后缀/的,这个 /就导致我们可以从/home/目录穿越到他的上层目录,造成任意文件下载:

未分类

修复方法:不写成上面那种有漏洞的形式,比如可以写成结尾都带着/字符。

0×01$uri导致的CRLF注入

在实际业务场景中经常需要在nginx中配置路径跳转。

比如用户访问http://x.com 自动跳转到https://x.com 或者是访问 http://x.com 自动跳转到 http://www.x.com

在跳转的过程中,我们需要保证用户访问的页面不变,所以需要从Nginx获取用户请求的文件路径,有三个可以表示uri的变量:

$uri
$document_uri
$request_uri

$uri 和 $document_uri表示的是解码以后的请求路径,不带参数,$request_uri表示的是完整的URI(没有解码),如果在nginx.conf中配置了下列的代码:

location /test {
             return 302 http://$host:81$uri;
                 }

因为$uri是解码以后的请求路径,所以可能就会包含换行符,也就造成了一个CRLF注入漏洞。

未分类

该漏洞除了发生在 return后面,也可能发生在rewrite、add_header、p roxy_set_header、proxy_pass之后。

修复方式:将$uri或者$document_uri改为 $request_uri。

0×02 SSRF

SSRF(服务端请求伪造)漏洞常出现在反向代理的配置中,反向代理的语法如下:proxy_pass http ://IP

如果攻击者可以操控IP, 将其修改成内网IP地址即可造成SSRF漏洞。

0×03目录遍历

autoindex off;#是否开启目录列表访问,默认关闭。

若设置成autoindex on;

未分类

未分类

0x04nginx版本泄露

对于nginx服务器,之前曾爆出过不同版本的解析漏洞,比如nginx 0.7.65以下(0.5.*, 0.6.*, 0.7.* )全版本系列和0.8.37(0.8.*)以下8系列受影响。下面假设在存在漏洞的站点上有一张图片url地址为:http://x.x.x.x/logo.jpg 而当我们正常访问图片时,nginx会把这个当作非脚本语言直接读取传送会客户端(也就是浏览器),但是

存在解析漏洞的nginx会把如下连接解析并且当作php文件执行~:

http://x.x.x.x/logo.jpg/x.php

http://x.x.x.x/logo.jpg%00x.php

因此隐藏 Nginx 的版本号,提高安全性。

在配置文件nginx.conf里面,设置如下:server_tokens off;

未分类

未分类

Nginx配置安全检查的工具

Github上开源了一款Nginx配置安全检查的工具,叫做gixy,可以覆盖以上的部分问题。

项目地址: https://github.com/yandex/gixy

工具是用python编写的,python2.7和3.5+版本都支持。可以直接用pip来安装:pip install gixy。

使用起来也很简单,直接将 gixy 命令后面加上 ningx.conf 文件的具体位置即可。

未分类

nginx的反向代理功能和缓存功能

一、nginx的反向代理功能

1.1 正向代理和反向代理

正向代理是众多内网客户机上网访问互联网上的网站时,将所有的请求交给内网前面处于公网上的”管家”服务器,由”管家”服务器代为请求想要访问的web服务器,然后将得到的结果缓存下来并提供给客户端,这是正向代理。”管家”服务器称为正向代理服务器。

未分类

反向代理是客户端访问web服务器时,请求发送到真实的web服务器的前端”助手”服务器上,由”助手”服务器决定将此请求转发给哪个真实的web服务器,外界客户端以为”助手”服务器就是真实的web服务器,而实际上它不是,也不需要安装任何web程序。”助手”服务器称为反向代理服务器。

未分类

nginx是一个优秀的反向代理服务程序,通过反向代理可以实现负载均衡的效果。因为是通过反向代理实现的负载均衡,所以nginx实现的是七层负载均衡。它能够识别http协议,根据http报文将不同类型的请求转发到不同的后端web服务器上。后端的web服务器称为”上游服务器”,即upstream服务器。

实际上,nginx和php-fpm结合的时候,指令fastcgi_pass实现的也是反向代理的功能,只不过这种代理功能是特定的功能,只能转发给php-fpm。

nginx的反向代理有几种实现方式:

  • 仅使用模块ngx_http_proxy_module实现简单的反向代理。指令为proxy_pass。

  • 使用fastcgi模块提供的功能,反向代理动态内容。指令为fastcgi_pass。

  • 使用ngx_http_memcached_module模块提供的功能,反向代理memcached缓存内容,指令为memcached_pass。

  • 结合upstream模块实现更人性化的分组反向代理。

1.2 配置简单的反代实验

实验环境如下图:

未分类

反向代理服务器nginx-proxy(192.168.100.29)的配置。由于是做代理,所以配置文件的location段不再需要root、index等指令,只需几个和代理相关的指令即可。

server {
    listen       80;
    server_name  www.longshuai.com;
    location ~ .(png|jpg|jpeg|bmp|gif)$ {
        proxy_pass http://192.168.100.28:80;
    }
    location / {
        proxy_pass http://192.168.100.30:80/;
    }
    location ~ .(php|php5)$ {
        proxy_pass http://192.168.100.25:80;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

提供动态服务的nginx服务器(192.168.100.25)的配置如下。

server {
    listen       80;
    server_name  www.longshuai.com;
    location / {
        root    /www/longshuai/;
        index   index.php index.html index.htm;
    }
    location ~ .php$ {
        root /php/;
        fastcgi_pass    192.168.100.27:9000;
        fastcgi_index   test.php;
        include         fastcgi.conf;
    }
}

其中php-fpm服务器(192.168.100.27)上的/www/longshuai/index.php内容如下:

<h1>page from php-fpm</h1>
<?php
phpinfo();
?>

LB1(192.168.100.28)和LB2(192.168.100.30)的web程序都是httpd。其中作为一般静态web服务器的LB2的配置文件没有任何修改,它的/var/www/html/index.html的内容如下:

<h1>LB2:static</h1>

作为图片服务器的LB1在配置文件中添加了如下几行。且其/var/www/html/下有一个图片文件a.png。

<Files ~ ".(png|jpeg|jpg|bmp|gif)">
        Order allow,deny
        Allow from all
</Files>

经过以上的配置,可以实现如下图的功能。当访问www.longshuai.com的时候,任意以php结尾的文件请求都转发给nginx再由nginx交由php-fpm处理;任意以图片格式结尾(png/jpg/jpeg/bmp/gif)的请求都转发给LB1;任意非以上两种格式的请求都转发给LB2。

未分类

重载nginx-proxy/nginx/LB1/LB2上的nginx或者httpd。然后进行测试。

未分类

未分类

1.3 使用upstream模块实现分组反向代理

前面只使用了ngx_http_proxy_module来实现反向代理,但是其缺陷在于在nginx-proxy上定义的每条代理规则都只能转发到后台的某一台服务器上,即后端服务器无法分组。例如当图片服务器压力太大,添加一台服务器想要减轻图片服务器压力,但是仅使用proxy模块无法实现此类负载均衡到多台图片服务器上。

这时需要借助ngx_http_upstream_module模块,该模块用于定义后端服务器池,后端服务器也称为上游服务器(upstream),可以为每一种类型的后端服务器分一个组。然后在结合proxy_pass或其他代理指令将相应的请求转发到池内。

服务器池可以有多台服务器,多台服务器如何实现负载均衡和算法有关,默认是指定权重的加权均衡算法,还可以指定ip_hash算法实现同一个客户端IP发起的请求总是转发到同一台服务器上。还有一些其它算法,如最小连接数算法。最常用的还是加权算法,然后通过session共享的方式实现同一个客户端IP发起的请求转发到同一服务器上。

例如,下图描述的需求。当请求图片服务器时,可以将请求均衡到IP3和IP4两台服务器上,当请求其他静态内容,可以将请求均衡到IP5和IP6两台服务器上。

未分类

要实现这样的功能,nginx-proxy上的nginx配置文件内容大致如下:

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;

    # define server pool
    upstream dynamic_pool {
        server IP1:80;
    }
    upstream pic_pool {
        server IP3:80 weight=2;
        server IP4:80 weight=1;
    }
    upstream static_pool {
        server IP5:80 weight=1;
        server IP6:80 weight=1;
    }

    server {
        listen 80;
        server_name www.longshuai.com;

        # define how to proxy
        location ~ .(php|php5)$ {
            proxy_pass http://dynamic_pool;
        }
        location ~ .(png|jpeg|jpg|bmp|gif)$ {
            proxy_pass http://pic_pool;
        }
        location / {
            proxy_pass http://static_pool;
        }
    }
}

1.4 ngx_http_proxy_module模块

1.4.1 指令及其意义

该模块默认安装。以下是相关指令的说明。

未分类

1.4.2 proxy_pass

proxy_pass http[s]://{ [IP:PORT/uri/] | upstream_pool };

该指令在前文示例中已经演示过了。此处只说明注意点。

当proxy_pass所在的location中使用了正则匹配时,则proxy_pass(包括fastcgi_pass和memcached_pass)定义的转发路径都不能包含任何URI信息。另外,location中使用了尾随斜线,那么proxy_pass定义的转发路径也必须使用斜线,或者都不加尾随斜线。

例如下面的配置方式是允许的。当访问www.longshuai.com/forum/时将被转发到http://192.168.100.25:8080/bbs/上。

server_name www.longshuai.com;
location /forum/ {
    proxy_pass http://192.168.100.25:8080/bbs/;
}

而如果使用了正则匹配,将是不允许的。如下。

server_name www.longshuai.com;
location ~ ^/forum/ {
    proxy_pass http://192.168.100.25:8080/bbs/;
}

只能修改转发路径使其不包含URI。如下。此时请求www.longshuai.com/forum/将转发到http://192.168.100.25:8080/forum/。

server_name www.longshuai.com;
location ~ ^/forum/ {
    proxy_pass http://192.168.100.25:8080/;
}

1.4.3 proxy_set_header

可以在nginx配置文件中的http段、server段或location段设置proxy_set_header指令。设置该指令后,传输给上游服务器的报文首部将包含相关的信息,如设置客户端的真实IP地址。设置如下:

server {
    listen       80;
    server_name  www.longshuai.com;
    location ~ .(png|jpg|jpeg|bmp|gif)$ {
        proxy_pass http://192.168.100.28:80;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
    location / {
        proxy_pass http://192.168.100.30:80/;
        proxy_set_header X-Forwarded-For $remote_addr;

    }
    location ~ .(php|php5)$ {
        proxy_pass http://192.168.100.25:80;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

仅在代理服务器上设置了该头部字段后还不够,因为后端服务器仅仅只是获取到它,默认并没有将其记录下来。所以需要在后端的服务的日志格式设置上记录此项或者在其他有需求的地方设置它。nginx的日志格式和apache的日志设置格式不同,以下分别是两种web程序的设置方法:

# nginx上的日志设置格式
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
              '$status $body_bytes_sent "$http_referer" '
              '"$http_user_agent" "$http_x_forwarded_for" ';
access_log logs/access.log main;

# apache上的日志设置格式
LogFormat "%{X-Forwarded-For}i %h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined

以下是nginx日志上记录的信息。

[root@xuexi nginx]# tail -1 logs/access.log 
192.168.100.29 - - [26/Apr/2017:14:35:30 +0800] "GET /index.php HTTP/1.0" 200 76990 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36" "192.168.100.1"

以下是apache日志中记录的信息。

[root@xuexi ~]# tail -1 /etc/httpd/logs/access_log
192.168.100.1 192.168.100.29 - - [26/Apr/2017:14:32:52 +0800] "GET /a.png HTTP/1.0" 200 2653 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36"

1.5 ngx_http_upstream_module模块

upstream模块定义上游服务器组。主要的指令有”upstream”、”server”、”ip_hash”。upstream指令必须定义在server段外面。

以下是一个综合示例定义方法,并非正确,只是放在一起方便比较用法。

upstream backend {
    server 192.168.100.25;
    server 192.168.100.26:80;
    server www.longshuai.com;
    server www.xiaofang.com:8080;
    server 192.168.100.27 weight=2 max_fails=2 fail_timeout=2s;
    server 192.168.100.28 down;
    server 192.168.100.29 backup;
    ip_hash;   # 定义此项后,前面的server附加项weight和backup功能失效。
}

默认使用加权均衡算法,使用ip_hash指令可设置为ip_hash算法,但使用ip_hash指令后,如果server指令中使用了weight和backup选项,这两个功能将会失效。

其中server指令后可以跟的附加选项有:

  • weight:定义该后端服务器在组中的权重,默认为1,权重越大,代理转发到此服务器次数越多。

  • max_fails和fail_timeout:定义代理服务器联系后端服务器的失败重联系次数和失败后重试等待时间。默认为1和10,如果设置为2和3,则表示只尝试联系2次,每次失败等待3秒后进行下一次重试,也就是说6秒后就能判定此后端服务器无法联系上,将负载均衡到下一台服务器上。常会配合proxy_next_upstream或者fastcgi_next_upstream或者memcached_next_upstream来指定失败时如何处理。

  • down:将此后端服务器定义为离线状态。此功能不同于直接在配置文件中删除此服务器配置或注释它。常用于ip_hash均衡算法。当使用ip_hash算法时,如果某台服务器坏了需要将其从服务器组中排除,直接从配置文件中直接删除该服务器将会导致此前分配到此后端服务器的客户端重新计算IP_HASH值,而使用down则不会。

  • backup:指定当其他非backup的server都联系不上时,将返回backup所定义的服务器内容。常用于显示sorry page。

当server指定后端服务器时使用的是主机名的方式时,需要在代理服务器上添加域名解析记录,如放到/etc/hosts中。

以下是一个配置示例。只定义了一个upstream组,所有请求都代理,权重为2比1,当192.168.100.28和192.168.100.30都断开联系时,将返回代理服务器本身配置的sorrypage。

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    upstream web_group {
        server 192.168.100.28 weight=2 max_fails=2 fail_timeout=2s;
        server 192.168.100.30 weight=1 max_fails=2 fail_timeout=2s;
        server 127.0.0.1:80 backup;
    }
    server {
        listen 127.0.0.1:80;
        root /www/longshuai/;
        index index.html;
    }
    server {
        listen       80;
        server_name  www.longshuai.com;
        location / {
                proxy_pass http://web_group;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root   html;
        }
    }
}

然后在反向代理服务器上创建/www/longshuai/目录,并向目录下的index.html文件中写入”sorry….”。

mkdir -p /www/longshuai/
echo "<h1>sorry pages...</h1>" >/www/longshuai/index.html

重载代理服务器。在浏览器上输入www.longshuai.com并不断刷新,结果应该是2:1的返回权重。再依次测试停掉某一台后端服务器和两台后端都停掉的情况。

1.6 反向代理的各种情况

反向代理时,可以根据uri的后缀来代理,也可以根据uri中的目录来代理,还可以根据客户端浏览器类型来代理。例如手机访问网站时转发到某个后端服务器组,IE浏览器访问的转发到某一个后端服务器组等。

# uri后缀代理。
location ~ .(jpeg|jpg|png|bmp|gif)$ {
    proxy_pass ...
}

# 目录代理。
location ~ /forum/ {
    proxy_pass ...
}

# 浏览器类型代理。
location / {
    if ($http_user_agent ~ "MSIE") {
        proxy_pass...
    }
    if ($http_user_agent ~ "Chrome") {
        proxy_pass...
    }
}

1.7 nginx代理memcached

该模块可以从将请求代理至memcached server上,并立即从server上获取响应数据。例如:

location / {
                set $memcached_key "$uri?$args";
                memcached_pass     127.0.0.1:11211;
}

nginx代理memcached时,需要以变量$memcached_key作为key去访问memcached server上的数据。例如此处将$uri$args变量赋值给$memcached_key变量作为key去访问memcached服务器上对应的数据。

但这样的代理显然不符合真正的需求:没有实现memcached的分布式功能。当memcached server宕机时,nginx将无法从中获取任何数据。所以应该使用上游服务器组。例如:

upstream memcached {
    server 127.0.0.1:11211;
    server 127.0.0.1:11212;
    server 127.0.0.1:11213;
    server 127.0.0.1:11214;
}

server {
    listen       80;
    server_name  dev.hwtrip.com;

    location ^~ /cache/ {
        set            $memcached_key "$uri$args";
        memcached_pass memcached;

但这也不适合,因为memcached是基于一致性哈希算法的,而upstream模块默认并不支持一致性哈希算法。可以通过upstream模块的hash指令或者另外使用一个第三方模块ngx_http_upstream_consistent_hash。

如果使用的是upstream模块的hash指令,配置如下:

upstream memcached {
    hash "$uri$args" consistent;
    server 127.0.0.1:11211;
    server 127.0.0.1:11212;
    server 127.0.0.1:11213;
    server 127.0.0.1:11214;
}

这样,各上游主机就通过hash一致性的算法进行负载均衡。

如果使用的是第三方模块ngx_http_upstream_consistent_hash,则在模块添加成功后如下配置upstream组:

upstream memcached {
    consistent_hash consistent;
    server 127.0.0.1:11211;
    server 127.0.0.1:11212;
    server 127.0.0.1:11213;
    server 127.0.0.1:11214;
}

二、nginx自带的缓存功能

nginx的ngx_http_proxy_module自带了缓存功能。有几种缓存:网页内容缓存,日志缓存,打开文件缓存,fastcgi缓存。fastcgi缓存功能应慎用,因为动态程序的前后逻辑可能改变了,缓存后的结果可能并非实际所需结果。

在说明nginx自带的缓存功能之前,需说明其缺陷。nginx的缓存功能主要用于缓存体积较小的页面资源,当数据较大时很容易出现瓶颈。在页面资源的缓存功能上,它属于业余玩家。而squid是科班出身,功能最全面,可以缓存大量数据,但架构太老,性能一般。varnish则是此类缓存的新贵,架构较新,内存管理完全交由操作系统内核,性能是squid的几倍之强,但缓存的内容不足squid。

本节所讲的主要是nginx自带缓存的网页内容缓存。当实现网页内容缓存时,作为web服务程序,它可以缓存自身返回给客户端的数据,包括读取的图片、文件等;作为代理,它可以缓存来自后端的数据。缓存后的数据在内存中有,也会放在设定的目录下。这样以后客户端继续请求相同资源时,可以直接从内存中或者自身的磁盘中获取并返回给客户端。当缓存超出指定的空间大小时,将会有一个专门的线程cache_manager来清理缓存。

定义的相关指令主要有3个:proxy_cache_path、proxy_cache、proxy_cache_valid。

  • proxy_cache_path:它的语法比较复杂,但用起来很简单。
proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

其中proxy_cache_path path [levels=levels] keys_zone=name:size [max_size=size]这几项是一般使用的选项和必需项。以下为一示例。

proxy_cache_path /usr/local/nginx/cache_dir levels=1:2 keys_zone=cache_one:20m max_size=1g;

其中:

  • path:定义缓存放在磁盘的哪个目录下。此处表示定义在/usr/local/nginx/cache_dir目录下。目录不存在会自动创建。

  • levels:定义缓存目录的级别,同时定义缓存目录名称的字符数。例如levels=1:2:2表示3级目录,且第一级目录名1个字符,第二级目录2个字符,第三级目录2个字符。目录最多3级,目录名最多为2个字符。例如上例中”levels=1:2″产生的缓存文件路径可能是这样的”/usr/local/nginx/cache_dir/d/f1/50a3269acaa7774c02d4da0968124f1d”,注意其中加粗的字体。

  • keys_zone:定义缓存标识名称和内存中缓存的最大空间。name部分必须唯一,在后面会引用name来表示使用该缓存方法。

  • max_size:定义磁盘中缓存目录的最大空间。即path定义的文件最大空间。

该指令定义后只是定义了一种缓存方法,并非开启了缓存。

  • proxy_cache:定义要使用哪个缓存方法。使用proxy_cache_path中的name来引用。

例如引用上例定义的cache_one。

proxy_cache cache_cache;
  • proxy_cache_valid:根据状态码来指定缓存有效期。

例如,下面的表示状态码为200和302的状态缓存1小时,状态码为404时即page not found的缓存只有1分钟,防止客户端请求一直错误,状态码为其他的则缓存5分钟。

proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 1m;
proxy_cache_valid any 5m;

如果不指定状态码,只指定时间,则默认只缓存状态码200、301、302各5分钟,其他的状态码不缓存。

以下是代理服务器192.168.100.29上定义的缓存示例。

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

        upstream web_group {
                server 192.168.100.28 weight=2 max_fails=2 fail_timeout=2s;
                server 192.168.100.30 weight=1 max_fails=2 fail_timeout=2s;
                server 127.0.0.1:80 backup;
        }
        proxy_cache_path /usr/local/nginx/cache_dir levels=1:2 keys_zone=cache_one:20m max_size=1g;
        server {
                listen 127.0.0.1:80;
                root /www/longshuai/;
                index index.html;
        }
        server {
                listen       80;
                server_name  www.longshuai.com;
              # 在响应报文中添加缓存首部字段
                add_header X-Cache "$upstream_cache_status from $server_addr";
                location / {
                        proxy_pass http://web_group;
                        proxy_cache cache_one;
                        proxy_cache_valid 200 1h;
                        proxy_cache_valid 404 1m;
                        proxy_cache_valid any 5m;
                }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

其中添加的一行”add_header X-Cache “$upstream_cache_status from $server_addr”;”表示在响应报文的头部加上一字段X-Cache,其值为是否命中缓存的状态($upstream_cache_status),从哪台服务器上($server_addr)取得的缓存。 重载代理服务器的配置文件后,在客户端打开”开发者工具”进行测试。

未分类

由于是第一次提供缓存功能,所以结果是未命中缓存。此时已经将缓存保存下来了。 再进行测试,结果将命中缓存是”hit from 192.168.100.29″。

未分类

查看缓存目录。

[root@xuexi nginx]# tree /usr/local/nginx/cache_dir/  
/usr/local/nginx/cache_dir/
├── 3
│   └── 26
│       └── 3abcc5796b407cf3db2716539d256263
└── d
    └── f1
        └── 3b37290aabefe7369a4680875f763f1d

如果想要删除缓存,只需删除对应的目录即可。

Linux(Ubuntu16.04)apt-get install安装Nginx + PHP7+Mysql5.7

切换到root帐号,安装软件包源: apt-get install software-properties-common

1、安装PHP7.1

add-apt-repository ppa:ondrej/php

apt-get update

apt-get install php7.1-cli php7.1-fpm php7.1-common php7.1-curl  php7.1-xml php7.1-gd php7.1-mysql php7.1-mbstring php7.1-bcmath php7.1-dev php7.1-zip

相关服务命令:

service php7.1-fpm start/stop/restart

2、安装Nginx

add-apt-repository ppa:ondrej/nginx

apt-get update

apt-get install nginx-full

配置站点php-fpm

vim /etc/nginx/sites-available/default
fastcgi_pass  unix:/run/php/php7.1-fpm.sock;

相关服务命令:

service nginx start/stop/restart

3、安装Mysql5.7

add-apt-repository ppa:ondrej/mysql

apt-get update

apt-get install mysql-server-5.7

配置远程链接

创建远程链接帐号

mysql -u root -h localhost -p

mysql> GRANT ALL PRIVILEGES ON *.* TO 'remote_root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;

mysql> FLUSH PRIVILEGES;

修改cnf配置

vim  /etc/mysql/mysql.conf.d/mysqld.cnf
将bind-address    = 127.0.0.1

设置成bind-address    = 0.0.0.0(设备地址)

重启mysql

service mysql restart

用supervisor+nginx部署服务的流程

以chat_service为例:

1、将项目拷贝至某一路径

2、更改supervisor配置文件:supervisor.conf(一般在/etc/目录下)

  • 在/etc/supervisor.d/目录下新建chat_service.conf配置文件,如下:
[program:chat_service]
command=/usr/local/bin/gunicorn -b 0.0.0.0:8001 -w 40 -k gevent -t 300 chat_service.wsgi:application
directory=/home/hongkeyuan/chat/bin/chat_system/chat_service
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/hongkeyuan/chat/log/chat_service.log
stderr_logfile=/home/hongkeyuan/chat/log/chat_service.err
  • 将配置文件包含到supervisor.conf中,在supervisor.conf中加入:
[include]
files = /etc/supervisor.d/*.conf

3、更改nginx配置文件,/etc/nginx/conf.d/目录下新建chat_service.conf配置文件,如下:

upstream chat_service {
        server localhost:8001;
}

server {
        listen 8000;
        location /static {
                alias /home/robot/chat/bin/chat_system/chat_service/static;
        }
        location / {
                proxy_pass_header Server;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Scheme $scheme;
                proxy_pass http://chat_service;
        }
}

4、重新加载supervisor:supervisorctl -c /etc/supervisor.conf reload,此时配置的服务也将重启。

5、重新加载nginx:nginx -s reload。

tips:

  • 如果需要sudo权限,相关命令前需要加sudo。
  • 这里nginx主要起重定向作用,如果不需要重定向,则无需配置nginx。

ubuntu 16.04配置nginx服务器实现一个IP一个端口多个站点

未分类

特点:

  • Nginx 可以部署在网络上使用 FastCGI,脚本,SCGI 处理程序,WSGI 应用服务器或 Phusion 乘客模块的动态 HTTP 内容,并可作为软件负载均衡器。

  • Nginx 使用异步事件驱动的方法来处理请求。 Nginx的模块化事件驱动架构可以在高负载下提供更可预测的性能。

  • Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不同,nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。 在Linux作业系统下,nginx使用epoll事件模型,得益于此,nginx在Linux作业系统下效率相当高。同时Nginx在OpenBSD或FreeBSD作业系统上采用类似于epoll的高效事件模型kqueue。

实现两个域名,打开两个不同的站点

  • 把0522.com和0o0.live解析到同一个IP

  • 检查nginx配置文件

vim /etc/nginx/nginx.conf

确保,配置文件的http{}大括号里有:

include /etc/nginx/conf.d/*.conf

例如:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;    #就是这里,如果前面有#号,请把#号去掉
        include /etc/nginx/sites-enabled/*;
}
  • 在目录/etc/nginx/conf.d/下面新建两个文件:
0522.conf
0o0.conf #.conf前的名字随你

写入以下内容:

server
{
listen       80;
server_name 0522.us www.0522.us;   #这里填写你的域名,包括无www301转向有www
index index.html index.htm index.php default.html default.htm default.php;
root  /var/www/0522.us;     #这里填写域名对应的站点根目录


location / {
try_files $uri $uri/ /index.php;

}

location ~ .php$ {
try_files $uri =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}



location ~ .*.(gif|jpg|jpeg|png|bmp|swf|ico)$
{
expires      30d;
}

location ~ .*.(js|css)?$
{
expires      30d;
}


}
  • 以上是0522.conf的内容
server
{
listen       80;
server_name 0o0.live www.0o0.live;
index index.html index.htm index.php default.html default.htm default.php;
root  /var/www/0o0.live;     


location / {
try_files $uri $uri/ /index.php;

}

location ~ .php$ {
try_files $uri =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}



location ~ .*.(gif|jpg|jpeg|png|bmp|swf|ico)$
{
expires      30d;
}

location ~ .*.(js|css)?$
{
expires      30d;
}


}

以上是0o0.conf的内容

  • 重启nginx
sudo service nginx restart  #所有nginx的设置要重启后才先效
  • 分别上传两个域名的不同网站文件到相应的网站根目录

例如:

0522.us域名上传网站文件到/var/www/0522.us目录下
0o0.live域名上传网站文件到/var/www/0o0.live目录下
#你的域名上传到你自己设置的根目录

完美