![有没有办法对 Apache 服务器日志文件中的 IP 字段进行哈希处理?](https://linux22.com/image/743027/%E6%9C%89%E6%B2%A1%E6%9C%89%E5%8A%9E%E6%B3%95%E5%AF%B9%20Apache%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%20IP%20%E5%AD%97%E6%AE%B5%E8%BF%9B%E8%A1%8C%E5%93%88%E5%B8%8C%E5%A4%84%E7%90%86%EF%BC%9F.png)
我有一台 Apache 服务器。当流量到来时,我想对日志文件中的 IP 字段进行哈希处理或删除。有没有比编写脚本删除每行中的 IP 字段或使用任何 Apache 模块对 IP 字段进行哈希处理的更好方法?谢谢阅读。
答案1
是的,可以自定义 Apache 日志格式,如日志文件文档。
服务器访问日志记录服务器处理的所有请求。访问日志的位置和内容由
CustomLog
指令。LogFormat
指令可用于简化日志内容的选择。本节介绍如何配置服务器以在访问日志中记录信息。
来自自定义日志格式您可以找到%h
涉及以下内容的列表:
HostnameLookups
远程主机名。如果设置为Off
(默认值),则记录 IP 地址。
通过使用LogFormat
不带的,%h
您将停止记录 IP 地址,例如
LogFormat "%l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common
答案2
以下是如何在 Apache 2.4 中记录哈希 IP 地址。我在此处提供的解决方案允许您以 CustomLog 格式记录 IP 地址和 Cookie,同时允许将其记录用于故障排除或有问题的 IP。请注意,这并不妨碍其他模块(例如 mod_security、mod_status、PHP 或应用程序)也记录这些内容。
我的 CustomLog 是制表符分隔格式,可用于使用 awk 或 splunk-forwarders 进行解析。我的解决方案适用于具有反向代理的 Apache 服务器,并向下游发送请求。下游日志配置使用此处定义的标头,而不是正常值。此解决方案使用但不要求mod_unique_id
和mod_logio
。此解决方案假定当 URL 中出现 an/admin/
部分时,这是为了管理,应该记录下来。还应记录特殊的不良状态响应,例如 403、500 和 502。
为了使哈希值在命中时保持值不变,但又能抵御彩虹攻击,每次轮换 Apache 日志时都会用一个随机值作为哈希值的种子。这是通过 RHEL 的 logrotate 模块完成的,下面是一个例子:
Define HTTPD_RND_SEED "-dummy-string-"
# Include a wildcard below for Apache < 2.4.30
IncludeOptional /var/run/httpd/random_seed.co?nf
LogFormat "%{%s}t\t%{%T}t\t%{%F}t\t%{%w}t\t%{%W}t\t%>s\t\t%a\t%u\t%v\t%{local}p\t%H\t%{SSL_PROTOCOL}x\t%m\t%U\t%q\t%{UNIQUE_ID}e\t%{Referer}i\t%{User-agent}i\t%{Cookie}i\t%f\t%D\t%B\t%O\t%{ratio}n\t%{no-gzip}e\t%{SSL_CIPHER}x\t%P\t%{tid}P\t%R\t%k\t%X\t%{ModSecAnomalyScoreIn}e\t%{ModSecAnomalyScoreOut}e" tdf_normal
LogFormat "%{%s}t\t%{%T}t\t%{%F}t\t%{%w}t\t%{%W}t\t%>s\t\t%{REMOTE_IPHASH}e\t%u\t%v\t%{local}p\t%H\t%{SSL_PROTOCOL}x\t%m\t%U\t%q\t%{UNIQUE_ID}e\t%{Referer}i\t%{User-agent}i\t%{COOKIE_HASH}e\t%f\t%D\t%B\t%O\t%{ratio}n\t%{no-gzip}e\t%{SSL_CIPHER}x\t%P\t%{tid}P\t%R\t%k\t%X\t%{ModSecAnomalyScoreIn}e\t%{ModSecAnomalyScoreOut}e" tdf_hashed
CustomLog /var/log/httpd/tdf.log tdf_normal "expr=-T reqenv('log_normal') || %{REQUEST_STATUS} in { 403,406,429,431,500,502 }"
CustomLog /var/log/httpd/tdf.log tdf_hashed "expr=-T reqenv('log_hashed') && ! %{REQUEST_STATUS} in { 403,406,429,431,500,502 }"
RequestHeader set "X-UNIQUE-ID" "%{UNIQUE_ID}e"
## Case 1: admin activity is fully logged, troubleshooting mode too
## or when very bad HTTP Status, but this isn't available to if-else
<if "-f '/var/www/TROUBLESHOOTING' || %{REQUEST_URI} =~ m#/admin/#">
SetEnvIfExpr "-z reqenv('nolog')" log_normal=true
# Forward the unhashed elements downstream for its logging
SetEnvIfExpr "%{HTTP_COOKIE} =~ /(.{3,})$/" X_COOKIE=$1
RequestHeader set "X-COOKIE" "%{X_COOKIE}e"
RequestHeader set "X-REMOTE-ADDR" "%{REMOTE_ADDR}s"
</if>
<else>
## Case 2: all other activity: hash IPs and cookies
SetEnvIfExpr "true" log_hashed=true
# Use only the last 10 characters of the hash for the IP.
SetEnvIfExpr "md5(%{REMOTE_ADDR}.'${HTTPD_RND_SEED}') =~ /(.{10})$/" REMOTE_IPHASH=$1
# Forward the hashed elements downstream for its logging
RequestHeader set "X-REMOTE-ADDR" "%{REMOTE_IPHASH}e"
SetEnvIfExpr "md5(%{HTTP_COOKIE}.'${HTTPD_RND_SEED}') =~ /(.{3,})$/" COOKIE_HASH=$1
RequestHeader set "X-COOKIE" "%{COOKIE_HASH}e"
</else>
重新设定哈希值的 logrotate 示例:
/var/log/httpd/*log {
daily
sharedscripts
prerotate
openssl passwd 20 | sed 's/^.*/Define HTTPD_RND_SEED "&"/' >/var/run/httpd/random_seed.conf
endscript
postrotate
/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
endscript
}