http_name 和 sent_http_name 变量
Nginx 中 $http_name
是任意请求头字段,例如 Nginx 默认访问日志格式 main 中的 $http_user_agent
,$http_referer
字段对应 client 请求头中的 User-agent,refer。
$http_name
arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores
Nginx 的默认访问日志格式 main
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
而 $sent_http_name
是响应请求头字段
$sent_http_name
arbitrary response header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores
下图是api.bilibili.com的某个接口的响应头:
在Nginx访问日志格式中添加 $sent_http_bili_status_code
和 $sent_http_bili_trace_id
字段,记录 api.bilibili.com 响应头 Bili-Status-Code 和 Bili-Trace-Id 字段,新建一个 log_format s1
:
log_format s1 '$time_iso8601|$remote_addr|"$http_x_forwarded_for"|"$request"|'
'$status|$upstream_status|$body_bytes_sent|'
'$request_time|$upstream_response_time|'
'$sent_http_bili_status_code|$sent_http_bili_trace_id';
access_log /var/log/nginx/test_bili_access.log s1;
在 Nginx 配置一个 vhost 反向代理到 api.bilibili.com ,来模拟请求
root@zvps1:~# curl 'https://api.bilibili.com/x/space/user/setting/list' -H 'accept: application/json, text/plain, */*' -H 'accept-language: zh-CN,zh;q=0.9,ja;q=0.8' -H 'cookie: *******' -H 'origin: https://www.bilibili.com' -H 'priority: u=1, i' -H 'referer: https://www.bilibili.com/' -H 'sec-ch-ua: "Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"' -H 'sec-ch-ua-mobile: ?0' -H 'sec-ch-ua-platform: "Windows"' -H 'sec-fetch-dest: empty' -H 'sec-fetch-mode: cors' -H 'sec-fetch-site: same-site' -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' -sv --resolve api.bilibili.com:443:127.0.0.1 -k
* Added api.bilibili.com:443:127.0.0.1 to DNS cache
* Hostname api.bilibili.com was found in DNS cache
* Trying 127.0.0.1:443...
* Connected to api.bilibili.com (127.0.0.1) port 443 (#0)
......
> referer: https://www.bilibili.com/
> sec-ch-ua: "Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"
> sec-ch-ua-mobile: ?0
> sec-ch-ua-platform: "Windows"
> sec-fetch-dest: empty
> sec-fetch-mode: cors
> sec-fetch-site: same-site
> user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 200
< server: openresty
< date: Sun, 12 May 2024 08:55:49 GMT
< content-type: application/json; charset=utf-8
< content-length: 133
< access-control-allow-credentials: true
< access-control-allow-methods: GET,POST,PUT,DELETE
< access-control-allow-origin: https://www.bilibili.com
< access-control-expose-headers: X-Bili-Gaia-Vvoucher,X-Bili-Trace-Id
< bili-status-code: 0
< bili-trace-id: 4e9d97949c664084
< cpu_usage: 79
< vary: Origin
< x-bili-trace-id: 2669676c319b22c04e9d97949c664084
< x-ticket-status: 1
< access-control-allow-headers: Origin,No-Cache,X-Requested-With,If-Modified-Since,Pragma,Last-Modified,Cache-Control,Expires,Content-Type,Access-Control-Allow-Credentials,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Cache-Webcdn,x-bilibili-key-real-ip,x-backend-bili-real-ip,x-risk-header
< cross-origin-resource-policy: cross-origin
< idc: shjd
< expires: Sun, 12 May 2024 08:55:48 GMT
< cache-control: no-cache
< x-cache-webcdn: BYPASS from blzone06
< strict-transport-security: max-age=63072000
<
* Connection #0 to host api.bilibili.com left intact
{"code":0,"message":"0","ttl":1,"data":{"setting":{"hotspot_info":"1","live_broadcast":"1","play_continuation":"1","up_update":"1"}}}
查看对应访问日志
root@zvps1:~# cat /var/log/nginx/test_bili_access.log | grep list
2024-05-12T08:55:49+00:00|127.0.0.1|"-"|"GET /x/space/user/setting/list HTTP/2.0"|200|200|133|0.402|0.402|0|4e9d97949c664084
使用Nginx模拟ip.sb返回client公网ip
很多人喜欢使用curl ip.sb
来查询本机公网 ip 或者查看服务器出口 ip ,其实使用 Nginx 几行配置也可以实现。如下配置所示,$remote_addr
变量是 client 地址
location / {
return 200 $remote_addr;
}
x.zwade.top 是使用上面 Nginx 配置的演示环境,可以看到 ip.sb 和 ipify.org 站点返回的公网ip是一样的
输出 request header
相信在不少公司都会有开发在他们的应用把用户请求header或者body都输出到应用日志上,其实nginx+lua也可以实现这块。比如之前debug的时候会临时将request header 输出到 nginx error log 上,如下配置所示:
location / {
header_filter_by_lua_block {
-- 获取请求头信息
local headers = ngx.req.get_headers()
local header_string = ""
for k, v in pairs(headers) do
header_string = header_string .. k .. ": " .. v .. "\n"
end
-- 写入错误日志
ngx.log(ngx.ERR, "Request headers:\n", header_string)
}
default_type text/html;
echo "Are you OK?";
}
每个请求都会写到 nginx error log中
结束语
Nginx 还有很多好用好玩的功能。由于笔者技术水平有限,可能会有疏漏或错误,如果您在阅读过程中发现了任何问题,或者有任何可以改进的地方,欢迎在留言或者私信我。