[nginx] 说明如何查看、配置和查找访问日志

大家好。
我在系统解决方案部门工作,每天经常犯困,不想睡的时候困得不行,想睡的时候却睡不着。

这次,我们将讨论“访问日志”,在操作和维护 Web 服务器时,您肯定会经常接触到它。

其中,近年来,nginx 终于在全球市场份额上超越了 Apache,我想解释一下如何查看、配置和定位 nginx 访问日志。

测试环境

  • Linux 环境
    操作系统:AlmaLinux 9.2 版(VirtualBox 7.0.12 环境)
    中间件:nginx (1:1.20.1-14.el9_2.1.alma.1),HTTP(80)
  • 浏览器
    Chrome:120.0.6099.217(正式版本)(64 位)

测试页

  • 域名:example.com
    * 由于这是一个本地主机环境,请使用 hosts 重写规则访问它。
  • HTML:index.html(首页),FAQ.html(常见问题解答页面)

nginx 访问日志的位置和日志示例

访问日志的默认位置是“/var/log/nginx/access.log”。
如果您想先查看访问日志,我们建议使用负载较低的 less 命令打开它。

删除 /var/log/nginx/access.log

1️⃣ URL:example.com (index.html) 访问日志

192.168.33.1 - - [17/Jan/2024:08:47:50 +0000] "GET / HTTP/1.1" 200 37 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"

2️⃣ index.html(页面内链接)→ FAQ.html 访问日志

192.168.33.1 - - [17/Jan/2024:08:50:33 +0000] "GET /FAQ.html HTTP/1.1" 200 34 "http://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"

我在本地环境中创建了一个网站,该网站接受来自 example.com 的请求,并从浏览器中访问该网站时摘录了一些日志。

这是从 example.com 的首页 (index.html) 和 FAQ 页面 (FAQ.html) 访问时输出的日志。

初始 IP 地址和时间很容易理解,但其余部分可能比较难理解,所以我将通过与设置项进行比较来解释它们。

日志格式设置

nginx 的基本配置文件是“/etc/nginx/nginx.conf”。

其中,“log_format”指令(设置)定义了访问日志的格式。
* 它还定义了访问日志的输出目标。

less /etc/nginx/nginx.conf ~Excerpt~ http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';

“log_format main”部分将格式名称定义为“main”,
后跟要输出的内容格式,以及[nginx变量+连字符、括号等,用于格式化显示]。

日志格式说明/与访问日志的比较表 2️⃣

日志格式 内容 访问日志 2️⃣ 值 备注栏
远程地址 已连接的 IP 地址 192.168.33.1 由于这是直接请求的 IP 地址,因此
当通过 LB 发出请求时,LB 的 IP 地址会被记录下来。
- 分隔符 -
远程用户 基本身份验证指定的用户名 - (空白的)
在开发和维护期间
使用一般为空。
[$time_local] [处理完成时的当地时间 + 时区] [2024年1月17日 08:27:22
+0000]
“+0000”部分表示时差。
“+0000”是世界协调时(UTC)
,“+0900”是日本标准时间(JST)。
“$request” 请求内容
方法、请求路径、HTTP 版本)
"GET /FAQ.html
HTTP/1.1"

这意味着通过“HTTP/1.1”收到了对“FAQ.html”的“GET”(显示)请求
状态  状态码 200(成功)
已发送的字节数 “已发送至客户端的字节数” 34(字节) FAQ.html 等。
主数据(主体)部分的字节数
"$http_referer" “来源网址”
(访问该页面的URL)
"http://example.com/"
*首页
访问首页 ⇨ 常见问题解答
当显示“-”(空白)时,
可通过直接指定 URL 进行访问。
"$http_user_agent" 用户代理
(浏览器/操作系统信息)
“Mozilla/5.0
( Windows NT 10.0;Win64;x64)
AppleWebKit/537.36
(KHTML,如 Gecko)
Chrome /120.0.0.0 Safari/537.36”
Windows (OS) 上的
Chrome 浏览器进行访问
"$http_x_转发_for" "X-Forwarded-For"
(源 IP
"-" 通过代理或负载均衡器访问时,
会显示之前的源 IP 地址。

有很多信息可供参考。

上表可以更简单地概括如下:

  • IP : 192.168.33.1
  • 用户名:无(=未认证)
  • 访问时间:2024年1月17日08:27:22 UTC(日本时间+9小时)
  • 访问:常见问题解答页面 (FAQ.html)
  • 连接状态:成功(200)
  • 数据量:4B(字节)
  • 访问来源:从首页 (http://example.com)
  • 环境:Windows操作系统,使用基于Chrome的浏览器(如声明所述)
  • 是通过负载均衡器还是代理?:否(因为它是空的)

如您所见,我们可以从访问日志中获取大量信息。
通过以各种方式汇总这些信息,可以调查访问趋势以及访问是否恶意。

默认日志格式非常有用,请务必加以利用。

术语

基本身份验证

这是一个简单的身份验证功能,需要输入预先设定的用户名和密码。
由于它非常基础且简单,因此通常用于临时用途,例如施工或紧急维护期间。

尤其需要注意的是,HTTP(80)通信的安全性较弱,因为身份验证信息也是以明文(未加密)形式发送的。
即使您只是临时使用该网站,也建议该网站仅使用HTTPS(443)通信。

推荐人

指的是所访问页面的前一个 URL。

如果通过 Google 搜索打开主页,则 Google 网址会被记录在日志中;如果从网站主页打开 FAQ,则主页网址会被记录在日志中。

这个术语实际上是英文单词“referrer”(意思是:参考来源)的拼写错误,但由于在制定规范时就决定采用这种拼写错误的形式,因此它有着一段有趣的历史,并一直沿用至今。

HTTP 状态码

这段代码告诉你HTTP(S)通信时的处理结果。
这里无法一一列举,但第三位数字很重要。

  • 2xx:响应成功
  • 3xx:重定向响应
  • 4xx:客户端错误响应
  • 5xx:服务器错误响应

如上所述,第三位数字可以让你大致了解情况。

您最常看到的错误代码是 200(成功)、302(临时重定向)、404(无法访问不存在的位置)
和 503(服务器无法处理)。

用户代理

用户代理一词指的是“用于与网站通信的软件”。

通常情况下,网站是通过浏览器访问的,因此从扩展意义上讲,它被视为“有关用户正在使用的浏览器(和操作系统等)的信息”。

X-转发

这是负载均衡器或代理通信时描述源 IP 的项目(标头)。

当客户端(用户)与 Web 服务器(例如负载均衡器或代理服务器)之间进行通信时,负载均衡器或代理服务器的 IP 地址会被记录在 Web 服务器端,但其前面发送客户端的 IP 地址是未知的。

因此,当通信通过负载均衡器或代理时,将源 IP 保存在X-Forwarded-For已成为事实上的标准

附注:在日志格式中定义名称“main”

为什么需要定义名称?答案是“因为在配置日志输出时,要使用的日志格式是由名称指定的”。

less /etc/nginx/nginx.conf ~部分摘录~ access_log /var/log/nginx/access.log main;

它用于“access_log”指令中,该指令是一个设置(指令),用于指定日志输出目标。由于定义的项和使用的项目不同,因此需要一个名称。

这意味着您可以设置多个定义。

例如,您可以将简化的日志格式定义为“简单”,以减少不必要的信息;或者,如果您想要更详细的信息,您可以将包含更多项目(变量)的日志格式定义为“详细”。

这意味着您可以为每个域和环境使用不同的定义。

如果在 access_log 指令中不指定格式名称会发生​​什么情况?

你们中的一些人可能身处一个未指定格式名称的环境中。

在这种情况下,语法检查或操作都没有问题。

此 access_log 指令中未指定格式名称则默认设置为内置的“combined”定义,该定义未写入 conf

log_format combined '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"';

上述定义的使用方法在 nginx 官方文档中有详细说明。

该内容的格式与 conf 中默认写入的“main”略有不同,并且末尾没有指定“$http_x_forwarded_for”

顺便说一下,这与 Apache 中的默认定义名称“combined”相同,输出内容也相同。

最后

Apache 日志是我们经常接触的内容,其中包含大量信息。

相比之下,我没有太多机会接触 nginx,所以我认为整理相关信息会更方便,因此我写了这篇文章。

就我个人而言,我觉得它比 Apache 的日志格式规范更容易理解。

希望这篇文章对读者有所帮助。
感谢您读到这里。

*如果您想了解更多关于 Nginx 的信息,也请查看这篇博客:
【超级新手】只需阅读本文!即使是新手也能理解的 Nginx 讲解

参考资料

模块 ngx_http_log_module
https://nginx.org/en/docs/http/ngx_http_log_module.html

模块 ngx_http_core_module
https://nginx.org/en/docs/http/ngx_http_core_module.html

“基本”HTTP身份验证方案
https://datatracker.ietf.org/doc/html/rfc7617

引荐来源网址
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Referer

HTTP 响应状态码
https://developer.mozilla.org/ja/docs/Web/HTTP/Status

用户代理
https://developer.mozilla.org/en/docs/Glossary/User_agent

X-Forwarded-For
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-For

如果您觉得这篇文章有用,请点击【点赞】!
8
加载中...
8票,平均分:1.00/18
35,549
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

里面

我中途加入 Beyond 公司,
在系统解决方案部门
。我拥有 LPIC-3 304 和 AWS SAA 认证。