# Nginx

# 快速关闭
nginx -s stop

# 优雅地关闭。停止 nginx 进程并等待 worker 进程完成服务当前请求
nginx -s quit

# 重新加载配置文件
nginx -s reload

# 重新打开日志文件
nginx -s reopen

# 到底用的那个地方的nginx?
ps -ef | grep nginx

# 状态
service nginx status

# 查看html默认主目录、错误日志、配置文件在哪个目录
nginx -help

#守护(使某服务自动启动?)
systemctl enable nginx

#当前的配置文件路径( https://stackoverflow.com/a/38547591/4493393 )
nginx -t 都会打印出默认的 nginx 配置文件路径:

# 查看最后400行访问日志,-f跟踪
$ tail -f -n 400 /var/log/nginx/access.log


$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

# 仅查看版本号
$ nginx -v

# Ubuntu
Enable Nginx server at boot time using the systemctl command:
$ sudo systemctl enable nginx

Start Nginx server using the systemctl command:
$ sudo systemctl start nginx

Restart Nginx server using the systemctl command:
$ sudo systemctl restart nginx

Stop Nginx server using the systemctl command:
$ sudo systemctl stop nginx

Reload Nginx server using the systemctl command:
$ sudo systemctl reload nginx

Get status of Nginx server using the systemctl command:
$ sudo systemctl status nginx


# # 配置

# 如果请求头里面不带Cookie就返回403
if ($http_Cookie = "") { return 403; }

#internal指令指定某个location只能被“内部的”请求调用,外部的调用请求会返回”Not found” (404)

# location proxy_pass

#假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问

#第一种:绝对路径
location /proxy/ {
    proxy_pass http://127.0.0.1/;}
#代理到URL:http://127.0.0.1/test.html

#第二种(相对路径,相对第一种最后少一个 / )
location /proxy/ {
    proxy_pass http://127.0.0.1;}
#代理到URL:http://127.0.0.1/proxy/test.html

#第三种:
location /proxy/ {
    proxy_pass http://127.0.0.1/aaa/;}
#代理到URL:http://127.0.0.1/aaa/test.html

#第四种(相对于第三种,最后少一个 / )
location /proxy/ {
    proxy_pass http://127.0.0.1/aaa;}
#代理到URL:http://127.0.0.1/aaatest.html



location = /abc {} matches the exact uri /abc

location ~ /abc is a regex match on the uri, meaning any uri containing /abc, you probably want: location ~ ^/abc for the uri begining with /abc instead


# 禁用指定类型文件缓存

# 此文件1月22更新,但是:
$ curl -v http://xxxxxx/l/pydx280.ipa -o ppppp.ipa
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 173.242.126.204...
* TCP_NODELAY set
* Connected to pandago.tk (173.242.126.204) port 80 (#0)
> GET /l/pydx280.ipa HTTP/1.1
> Host: pandago.tk
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.18.0
< Date: Fri, 22 Jan 2021 06:40:38 GMT
< Content-Type: application/octet-stream
< Content-Length: 49447398
< Last-Modified: Mon, 18 Jan 2021 01:49:36 GMT
< Connection: keep-alive
< ETag: "6004e930-2f281e6"
< Accept-Ranges: bytes
<
{ [1388 bytes data]
  0 47.1M    0 84668    0     0  42826      0  0:19:14  0:00:01  0:19:13 42869^C
  
  
  
  
  #未测试
  #location \.(ipa|apk|swf)$ {
  #    add_header Cache-Control no-store;
  #}
  location ~* \.(apk|pdf|ipa)$ {
      expires -1;
  }

# macOS

==> nginx Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that nginx can run without sudo.

nginx will load all files in /usr/local/etc/nginx/servers/.

To have launchd start nginx now and restart at login: brew services start nginx Or, if you don't want/need a background service you can just run: nginx

# Openresty

# 安装及配置

macOS安装:

brew install openresty/brew/openresty

安装结果:

Installing openresty/brew/openresty
==> ./configure -j12 --prefix=/usr/local/Cellar/openresty/1.19.9.1_2 --pid-path=/usr/local/var/run/openresty.pid --lock
==> make
==> make install
==> Caveats
You can find the configuration files for openresty under /usr/local/etc/openresty/.

To start openresty/brew/openresty now and restart at login:
  brew services start openresty/brew/openresty
Or, if you don't want/need a background service you can just run:
  openresty
==> Summary
🍺  /usr/local/Cellar/openresty/1.19.9.1_2: 305 files, 6.8MB, built in 1 minute 1 second
==> Running `brew cleanup openresty`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
==> Caveats
==> openresty
You can find the configuration files for openresty under /usr/local/etc/openresty/.

To start openresty/brew/openresty now and restart at login:
  brew services start openresty/brew/openresty
Or, if you don't want/need a background service you can just run:
  openresty

nginx -V查看已经编译的配置

nginx -V
nginx version: nginx/1.21.5
built by clang 13.0.0 (clang-1300.0.29.3)
built with OpenSSL 1.1.1m  14 Dec 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/nginx/1.21.5 --sbin-path=/usr/local/Cellar/nginx/1.21.5/bin/nginx --with-cc-opt='-I/usr/local/opt/pcre/include -I/usr/local/opt/openssl@1.1/include' --with-ld-opt='-L/usr/local/opt/pcre/lib -L/usr/local/opt/openssl@1.1/lib' --conf-path=/usr/local/etc/nginx/nginx.conf --pid-path=/usr/local/var/run/nginx.pid --lock-path=/usr/local/var/run/nginx.lock --http-client-body-temp-path=/usr/local/var/run/nginx/client_body_temp --http-proxy-temp-path=/usr/local/var/run/nginx/proxy_temp --http-fastcgi-temp-path=/usr/local/var/run/nginx/fastcgi_temp --http-uwsgi-temp-path=/usr/local/var/run/nginx/uwsgi_temp --http-scgi-temp-path=/usr/local/var/run/nginx/scgi_temp --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-compat --with-debug --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-ipv6 --with-mail --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module

# 配置路径:

macOS:/usr/local/etc/openresty/nginx.conf

# 开启nginx访问日志

nginx.conf 文件解注释并修改:

logs/access.log改成/usr/local/etc/openresty/logs/access.log

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  /usr/local/etc/openresty/logs/access.log  main;

# 开启openresty lua输出日志

nginx.conf 文件解注释并修改:

error_log  /usr/local/etc/openresty/logs/error.log;

lua文件打印:

ngx.log(ngx.ERR, "lua log")

会看到/usr/local/etc/openresty/logs/error.log文件内容有了lua log

INFO级别的同理。

ngx.log(ngx.INFO, " string:", str)

Nginx 的日志级别,请看下表:

ngx.STDERR     -- 标准输出
ngx.EMERG      -- 紧急报错
ngx.ALERT      -- 报警
ngx.CRIT       -- 严重,系统故障,触发运维告警系统
ngx.ERR        -- 错误,业务不可恢复性错误
ngx.WARN       -- 告警,业务中可忽略错误
ngx.NOTICE     -- 提醒,业务比较重要信息
ngx.INFO       -- 信息,业务琐碎日志信息,包含不同情况判断等
ngx.DEBUG      -- 调试

# 在nginx.conf里提供web内容:

server {
        listen 9080;
        location / {
            default_type text/html;
            content_by_lua_block {
                ngx.say("<p>hello, lua</p>")
            }
        }
    }

启动服务器:

# macOS
openresty

# or Linux (-p:设置前缀路径 -c:设置配置文件)
/usr/local/openresty/nginx/sbin/nginx -p `pwd`/ -c conf/nginx.conf

此时访问 http://localhost:9080 可看到网页显示hello lua

# 通过lua脚本文件提供内容:

hello.lua 文件内容如下(此时的路径是/usr/local/etc/openresty/lua/hello.lua):

ngx.say("<p>hello, world from hello.lua</p>")

nginx.conf 文件如下:

server {
        listen 9080;
        location ~ /lua/(.+) {
            default_type text/html;
            content_by_lua_file /usr/local/etc/openresty/lua/$1.lua;
        }
    }

其中,location ~ /lua/(.+) 用于动态匹配 url,content_by_lua_file lua/$1.lua; 用于指明 Lua 文件位置

刷新openresty服务器:

openresty -s reload

此时访问 http://localhost:9080/lua/hello 可看到网页显示 hello, world from hello.lua

# 获取请求参数

创建 lua/req.lua 文件,提供 get_args 函数,用于提取请求参数:

local _M = {}
-- 获取 http get/post 请求参数
function _M.get_args()
    -- 获取 http 请求方式 get/post
    local request_method = ngx.var.request_method
    -- 这里是一个 table,包含所有 get 请求参数
    local args = ngx.req.get_uri_args()
    -- 如果是 post 参数获取
    if "POST" == request_method then
        -- 先读取请求体
        ngx.req.read_body()
        -- 这里也是一个 table,包含所有 post 请求参数
        local post_args = ngx.req.get_post_args()
        if post_args then
            for k, v in pairs(post_args) do
                args[k] = v
            end
        end
    end
    return args
end

return _M

创建 lua/test.lua ,通过调用 get_args 函数,提取 name 参数值:

-- 引入 req 模块
local req = require "req"

-- 获取请求参数列表
local args = req.get_args()

-- 获取 key 为 name 的值
local name = args['name']

-- 如果不存在指定默认值
if name == nil or name == "" then
    name = "leo"
end

-- 输出结果
ngx.say("<p>hello " .. name .. "!</p>")

刷新openresty 然后访问

http://localhost:9080/lua/test?name=Panda

http://localhost:9080/lua/test

# 静态资源访问权限控制

假设你的服务器以下目录存在panda.jpg和panda.mp4两个文件(以macOS为例):

/usr/local/Cellar/openresty/1.19.9.1_2/nginx/html/uploads

浏览器打开 http://localhost:9080/uploads/panda.jpg 任何人都可以访问。

假设你想对uploads文件夹的文件进行限制:任何文件都没法按照上面的方式直接访问,而是带上参数才能访问,且一段时间后失效,类似于http://localhost:9080/uploads/panda.jpg?token=c38bb6de659b2fdaf83a2a9dc5a3f1ed&timestamp=1642146124

指定时间戳,打开x秒内链接失效,返回403错误(参数见下面的diff_time)

指定签名token,由md5(timestamp + secret_key)产生。

这样的话一段时间后别人就没法访问了这个带token和timestamp参数的链接了

server {
    listen 9080;
    location ~ /lua/(.+) {
        default_type text/html;
        content_by_lua_file /usr/local/etc/openresty/lua/$1.lua;
    }

    location ^~ /uploads/ {
        access_by_lua '
            local secret_key = "prefix_eu56#42dfd6g*@"

            local diff_time  = 10000
            local local_time = ngx.time()
            local timestamp = tonumber(ngx.var.arg_timestamp)
            local token     = ngx.var.arg_token

            if (timestamp == nil or token == nil) then
                ngx.exit(403)
            elseif (math.abs(timestamp - local_time) > diff_time) then
                ngx.exit(403)
            end

            local access_token = ngx.md5(timestamp..secret_key)

            if token == access_token then
                return true
            else
                ngx.exit(403)
            end
        ';
    }

}

如果你的服务器视频文件比较重要,只想限制mp4和ts文件播放的话,可以进行如下配置:

location ^~ /uploads/ {
            access_by_lua '
                local secret_key = "prefix_eu56#42dfd6g*@"
                -- second 传入的时间戳距离服务器时间允许的最大差距。单位:秒
                local diff_time   = 1000000
                local server_time = ngx.time()
                local timestamp   = tonumber(ngx.var.arg_timestamp)
                local token       = ngx.var.arg_token
                local urlstr			= string.lower(ngx.var.request_uri)

                -- 如果是mp4或ts文件,采用验证url的方式
                if string.find(urlstr, ".mp4") or string.find(urlstr, ".ts") then
                    if (timestamp == nil or token == nil) then
                        ngx.exit(403)
                    elseif (math.abs(timestamp - server_time) > diff_time) then
                        ngx.exit(403)
                    end

                    local access_token = ngx.md5(timestamp..secret_key)
                    -- ngx.log(ngx.ERR, "=====is my type")
                    if token == access_token then
                        return true
                    else
                        ngx.exit(403)
                    end
                else
                    -- 返回true表示可以直接访问。
                    return true
                end
                
            ';
        }

✅ http://localhost:9080/uploads/panda.png

❌ http://localhost:9080/uploads/panda.mp4

✅ http://localhost:9080/uploads/panda.mp4?token=c38bb6de659b2fdaf83a2a9dc5a3f1ed&timestamp=1642146124

✅ http://localhost:9080/uploads/index.html

相关链接:

https://www.cnblogs.com/gouyg/p/lua-nginx-url-access.html

https://www.zybuluo.com/dume2007/note/665548

# Tips

获取http://localhost:9080/uploads/panda.jpg?token=x/uploads/panda.jpg?token=x

ngx.var.request_uri

其他:

--local arg = ngx.req.get_uri_args()
--   for k,v in pairs(arg) do
--       ngx.log(ngx.ERR, "[PPGET ] key:", k, " v:", v)
--   end

-- ngx.log(ngx.ERR, "=====uri=====",ngx.var.request_uri)

-- local extension = urlstr:match("/.+(jpg|mp4).*$")

# 博客链接

https://moonbingbing.gitbooks.io/openresty-best-practices/content/openresty/get_url_param.html

https://leehao.me/OpenResty-%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/

上次更新: 3/13/2022, 12:02:34 AM