首页 应用实战正文

ModSecurity日志保存至MySQL数据库(通过Logstash)

王子 应用实战 2020-03-07 8907 0

本文主要介绍如何使用Logstash,将ModSecurity的JSON格式的审计日志保存至MySQL数据库中。


测试环境:

操作系统:CentOS-7-x86_64-DVD-1810.iso

JDK:jdk-8u241-linux-x64.tar.gz

Logstash:logstash-5.6.16.tar.gz

JDBC:mysql-connector-java-5.1.48.jar


一、软件上传

将上述JDK及Logstash的软件压缩包下载后,上传至服务器/usr/local目录下并解压,将JDBC上传至解压后的Logstash目录下。

cd /usr/local
tar -zxvf jdk-8u241-linux-x64.tar.gz
tar -zxvf logstash-5.6.16.tar.gz


二、配置JDK

如果服务器中已经安装了其他版本的JDK,且不可随意变更,可对Logstash进行单独的JDK配置,将以下内容复制到Logstash目录下bin/logstash、bin/logstash.lib.sh两个文件的首行位置即可:

export JAVA_HOME=/usr/local/jdk1.8.0_241


三、测试Logstash

首先,测试Logstash是否可以正常工作,在控制台输入以下命令等待Logstash启动:

/usr/local/logstash-5.6.16/bin/logstash -e 'input { stdin { } } output { stdout {} }'

启动成功的结果类似于下图(电脑端右击图片点击“在新标签页中打开图片”即可查看大图):

image.png然后直接输入字符串,如“Test”回车,如出现类似以下信息,表明Logstash可正常工作:

image.png

测试结束后通过Ctrl+C结束进程


四、安装logstash-output-jdbc

由于要把日志输入到数据库中,因此需要安装logstash-output-jdbc,该插件为第三方所开发,并未在Logstash 6.3及以上版本进行测试。

/usr/local/logstash-5.6.16/bin/logstash-plugin install logstash-output-jdbc

由于要从国外(https://rubygems.org)下载插件,因此在线安装过程较慢,如果发现无法在线安装,可下载logstash-output-jdbc.zip,上传至Logstash目录下。该安装包为本人基于Logstash 5.6.16在线安装logstash-output-jdbc成功后,所生成的离线安装包,其他版本的Logstash不一定适用。运行以下命令即可进行离线安装:

/usr/local/logstash-5.6.16/bin/logstash-plugin install file:///usr/local/logstash-5.6.16/logstash-output-jdbc.zip


五、创建日志同步配置文件

在Logstash目录下创建文件mslogtomysql.conf,并将以下内容复制进文件中,保存时要使用UTF8格式,或将中文注释删除,否则Logstash启动时会报错:

input {
    	file {
	    #ModSecurity审计日志的存放位置,请根据实际情况进行修改
		path => ["/var/log/modsecurity/*/*/*"]
		start_position => "beginning"
	}
}
filter{
	json{
		source => "message"
		remove_field => ["message"]
	}
    #以下到filter节点结束的内容,是为了将ModSecurity记录的日期转换为数据库可存放的datetime格式
	mutate{
		split => ["[transaction][time_stamp]"," "]    
		add_field => { "date" => "yyyy-MM-dd HH:mm:ss" }
		add_field => { "month" => "%{[transaction][time_stamp][1]}" }
		add_field => { "day" => "%{[transaction][time_stamp][2]}" }
		add_field => { "time" => "%{[transaction][time_stamp][3]}" }
		add_field => { "year" => "%{[transaction][time_stamp][4]}" } 
	}
	
	if [month] == "Jan" {
		mutate {
			gsub =>["month","Jan",'01']
		}
	} else if [month] == "Feb" {
		mutate {
			gsub =>["month","Feb",'02']
		}
	} else if [month] == "Mar"{
		mutate {
			gsub =>["month","Mar",'03']
		}
	} else if [month] == "Apr"{
		mutate {
			gsub =>["month","Apr",'04']
		}
	} else if [month] == "May"{
		mutate {
			gsub =>["month","May",'05']
		}
	} else if [month] == "Jun"{
		mutate {
			gsub =>["month","Jun",'06']
		}
	} else if [month] == "Jul"{
		mutate {
			gsub =>["month","Jul",'07']
		}
	} else if [month] == "Aug"{
		mutate {
			gsub =>["month","Aug",'08']
		}
	} else if [month] == "Sep"{
		mutate {
			gsub =>["month","Sep",'09']
		}
	} else if [month] == "Oct"{
		mutate {
			gsub =>["month","Oct",'10']
		}
	} else if [month] == "Nov"{
		mutate {
			gsub =>["month","Nov",'11']
		}
	} else if [month] == "Dec"{
		mutate {
			gsub =>["month","Dec",'12']
		}
	}
	
	mutate {
		gsub =>["date","yyyy",'%{[year]}']
		gsub =>["date","MM",'%{[month]}']
		gsub =>["date","dd",'%{[day]}']
		gsub =>["date","HH:mm:ss",'%{[time]}']
	}
}


output {
    #该节点会将最终日志数据以JSON格式打印到控制台中,便于观测进行调试,测试无问题后可将此节点删除
	stdout {
		codec => json {
			charset => "UTF-8"
		}
	}

	jdbc {
		driver_jar_path => "/usr/local/logstash-5.6.16/mysql-connector-java-5.1.48.jar"
		driver_class => "com.mysql.jdbc.Driver"
		connection_string => "jdbc:mysql://服务器IP地址:数据库端口/modsecurity?user=数据库用户名&password=数据库密码"
		statement => [ "insert into data (client_ip,time_stamp,date,server_id,client_port,host_ip,host_port,uri,unique_id,request,response,producer,messages) values (?,?,?,?,?,?,?,?,?,?,?,?,?)","[transaction][client_ip]","[transaction][time_stamp]","[date]","[transaction][server_id]","[transaction][client_port]","[transaction][host_ip]","[transaction][host_port]","[transaction][request][uri]","[transaction][unique_id","[transaction][request]","[transaction][response]","[transaction][producer]","[transaction][messages]" ]
	}
}



六、创建数据库

创建名为modsecurity的数据库,并执行以下SQL创建数据表

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `data`
-- ----------------------------
DROP TABLE IF EXISTS `data`;
CREATE TABLE `data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `client_ip` varchar(255) DEFAULT NULL,
  `time_stamp` varchar(255) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  `server_id` varchar(255) DEFAULT NULL,
  `client_port` int(11) DEFAULT NULL,
  `host_ip` varchar(255) DEFAULT NULL,
  `host_port` int(11) DEFAULT NULL,
  `uri` varchar(255) DEFAULT NULL,
  `unique_id` varchar(255) DEFAULT NULL,
  `request` mediumtext,
  `response` mediumtext,
  `producer` mediumtext,
  `messages` mediumtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


七、配置ModSecurity记录审计日志

modsecurity.conf文件需进行以下配置:

SecAuditEngine On
#注意,ModSecurity 3.x版本中目前不支持使用IJ记录请求体内容,如果要记录请求体,请用C代替IJ
#但此时会有一个情况,如果通过网站进行文件上传,文件的内容也会被记录到日志中,因此请勿通过网站上传大容量文件
SecAuditLogParts ABIJDEFHZ
#设置并行方式记录日志
SecAuditLogType Concurrent
#配置存放日志的目录,该目录必须存在且赋予777权限,否则可能无法正常写入日志
SecAuditLogStorageDir /var/log/modsecurity/
#配置记录的日志为JSON格式
SecAuditLogFormat JSON

配置完成后需要重新加载WEB服务


八、同步日志

运行以下命令,使Logstash以指定的配置文件启动:

/usr/local/logstash-5.6.16/bin/logstash -f /usr/local/logstash-5.6.16/mslogtomysql.conf

启动成功的结果类似于下图(电脑端右击图片点击“在新标签页中打开图片”即可查看大图):

image.png启动后,网站的最新访问,会先被ModSecurity记录,然后同步到数据库中


九、最后工作(可选)

编写脚本,将Logstash以后台服务方式运行,并设置开机自启;

编写定时脚本,在凌晨1点时,将前一天的ModSecurity审计日志删除,避免日志越来越多,占用磁盘空间。

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。