Patterns :

Access log Apache

#Gestion des logs access apache dans syslog
grok {
	match => { "message" => "%{SYSLOG5424PRI}%{SYSLOGBASE2} %{COMBINEDAPACHELOG}" }
  add_tag => [ "apache", "accesslogs" ]
}

iptables

grok {
	patterns_dir => ["/etc/logstash/patterns"]
	match => { "message" => "%{IPTABLES}"}
	add_tag => [ "iptables", "iptables-drop"]
}

Fichier de pattern :

DHCPD ((%{SYSLOGTIMESTAMP:timestamp})\s*(%{HOSTNAME:hostname})\s*dhcpd\S+\s*(%{WORD:dhcp_action})?.*[for|on] (%{IPV4:dhcp_client_ip})?.*[from|to] (%{COMMONMAC:dhcp_client_mac})?.*via (%{USERNAME:interface}))
#IPTABLES ((%{SYSLOGTIMESTAMP:nf_timestamp})\s*(%{HOSTNAME:nf_host})\s*kernel\S+\s*(%{WORD:nf_action})?.*IN=(%{USERNAME:nf_in_interface})?.*OUT=(%{USERNAME:nf_out_interface})?.*MAC=(%{COMMONMAC:nf_dst_mac}):(%{COMMONMAC:nf_src_mac})?.*SRC=(%{IPV4:nf_src_ip}).*DST=(%{IPV4:nf_dst_ip}).*PROTO=(%{WORD:nf_protocol}).?*SPT=(%{INT:nf_src_port}?.*DPT=%{INT:nf_dst_port}?.*))
#Gestion de IPv4 et v6
IPTABLES ((%{SYSLOGTIMESTAMP:nf_timestamp})\s*(%{HOSTNAME:nf_host})\s*kernel\S+\s*(%{WORD:nf_action})?.*IN=(%{USERNAME:nf_in_interface})?.*OUT=(%{USERNAME:nf_out_interface})?.*MAC=(%{COMMONMAC:nf_dst_mac}):(%{COMMONMAC:nf_src_mac})?.*SRC=(%{IP:nf_src_ip}).*DST=(%{IP:nf_dst_ip}).*PROTO=(%{WORD:nf_protocol}).?*SPT=(%{INT:nf_src_port}?.*DPT=%{INT:nf_dst_port}?.*))
DNS ((%{MONTHDAY:day})-(%{MONTH:month})-(%{YEAR:year}) (%{TIME:timestamp}) client (%{IPV4:dns_client_ip})#(%{NONNEGINT:dns_uuid})?.*query: (%{HOSTNAME:dns_dest}) (%{WORD:dns_type}) (%{WORD:dns_record})?.*(%{IPV4:dns_server}))
PGSQL ((%{SYSLOGTIMESTAMP:pgsql_timestamp}) (%{HOSTNAME:pgsql_hostname})?.*SAST >(%{WORD:pgsql_severity}):  (%{GREEDYDATA:pgsql_message}))
SQUID ((%{DATA:squid_timestamp_unix}) (%{INT:squid_time_elapsed_ms}) (%{IPV4:squid_client_ip}) (%{DATA:squid_action})/(%{INT:squid_reply_code}) (%{INT:squid_request_size}) (%{WORD:squid_method}) (%{URIPROTO:squid_request_protocol})://(%{DATA:squid_request_hostname}) - (%{WORD:squid_heirarchy})/(%{IPV4:squid_dest_ip}) (%{WORD:squid_content_type})/(%{WORD:squid_content_object}))
RADIUSINFO ((%{SYSLOGTIMESTAMP:radius_timestamp}) (%{YEAR}) : (%{WORD:radius_severity}): (%{GREEDYDATA:radius_messsage}))
RADIUSERROR ((%{SYSLOGTIMESTAMP:radius_timestamp}) (%{YEAR}) : (%{WORD:radius_severity}): (%{DATA:radius_module}): (%{GREEDYDATA:radius_messsage}))
RADIUSAUTHOKMAC ((%{SYSLOGTIMESTAMP:radius_timestamp}) (%{YEAR}) : (%{WORD:radius_severity}): (%{GREEDYDATA:radius_login_status}) \[(%{USERNAME:radius_user})/(%{USERNAME:radius_password})\] \(from client (%{GREEDYDATA:radius_from_client}) port (%{INT:radius_nas_port}) (%{WORD}) (%{GREEDYDATA:radius_mac})\))
RADIUSAUTHOK ((%{SYSLOGTIMESTAMP:radius_timestamp}) (%{YEAR}) : (%{WORD:radius_severity}): (%{GREEDYDATA:radius_login_status}) \[(%{USERNAME:radius_user})/(%{USERNAME:radius_password})\] \(from client (%{GREEDYDATA:radius_from_client}) port (%{INT:radius_nas_port}))
RADIUSAUTHFAIL ((%{SYSLOGTIMESTAMP:radius_timestamp}) (%{YEAR}) : (%{WORD:radius_severity}): (%{GREEDYDATA:radius_login_status}): \[(%{USERNAME:radius_user})/(%{USERNAME:radius_password})\] \(from client (%{GREEDYDATA:radius_from_client}) port (%{INT:radius_nas_port}))

fail2ban

grok {
	match => { "message" => "(%{SYSLOGTIMESTAMP:f2b_timestamp})\s*(%{HOSTNAME:f2b_host})\s*fail2ban.action\S+\s*(%{WORD:f2b_level})\s*\[(%{GREEDYDATA:f2b_jail})\s*\]\s*(%{WORD:f2b_action})\s*(%{IPORHOST:src_ip})" }
	add_tag => [ "fail2ban" ]
}

DenyALL rWeb

Trafic logs

grok {
	keep_empty_captures => true
	match => { "message" => "<(?<id>[^>]+)>(?<first_timestamp_MMM>\w{3})\s+(?<first_timestamp_dd>\d{1,2})\s+(?<first_timestamp_hh>\d{2}):(?<first_timestamp_mm>\d{2}):(?<first_timestamp_ss>\d{2})\s+(?<device>\S+)\s+(?<program>\S+)\s+(?<timestamp_yyyy>\d{4})-(?<timestamp_MM>\d{2})-(?<timestamp_dd>\d{2})\s+(?<timestamp_hh>\d{2}):(?<timestamp_mm>\d{2}):(?<timestamp_ss>\d{2})\.(?<timestamp_SSSSS>\d+)\s+(?<timestamp_ZZ>[^,]*),%{IP:local_ip},(?<hostname>[^,]+),%{IP:remote_ip},(?<x_forwarded_for>(\"([^\"])*\")|([^,]*)),(?<via>[^,]*),(?<user>[^,]*),(?<user_agent>(\"+[^\"]+\"+|[^,]*)),(?<SSL>\d),(?<SSL_version>[^,]*),(?<SSL_client_DN>[^,]*),(?<SSL_certificate_start>[^,]*),(?<SSL_certificate_end>[^,]*),(?<HTTP_method>[^,]+),(?<URL>[^,]+),(?<URL_options>.*),(?<HTTP_version>HTTP[^,]+),%{NUMBER:HTTP_response_code:int},%{NUMBER:HTTP_response_time:int},%{NUMBER:bytes_received:int},%{NUMBER:bytes_sent:int},(?<referrer>[^,]*),(?<cache>[^,]*),(?<gzip_ratio>[^,]*),(?<applicationID>[^,]+),(?<source_port>\d+),(?<application>[^,]+),(?<unique_id>[^,]+),(?<cookie>[^,]*)(,?)(?<posted_data>.*)"}
	# Specify in this custom field the +/- hours of the timezone (+1h for Europe/Paris)
	add_field => [ "timezone", "+0100" ]
	add_field => [ "log_type", "traffic" ]
	add_tag => [ "rweb_logs", "rweb_traffic_logs" ]
}

Alert logs

grok {
	keep_empty_captures => true
	match => { "message" => "<(?<id>[^>]+)>(?<first_timestamp_MMM>\w{3})\s+(?<first_timestamp_dd>\d{1,2})\s+(?<first_timestamp_hh>\d{2}):(?<first_timestamp_mm>\d{2}):(?<first_timestamp_ss>\d{2})\s+(?<device>\S+)\s+\S+\s+(?<log_id>\d+)\s+(?<timestamp_yyyy>\d{4})-(?<timestamp_MM>\d{2})-(?<timestamp_dd>\d{2})\s+(?<timestamp_hh>\d{2}):(?<timestamp_mm>\d{2}):(?<timestamp_ss>\d{2})\.(?<timestamp_SSSSS>\d+)\s+%{IP:source_ip}\s+%{IP:remote_ip}\s+\S+\s+(?<alert_id>\d+\.\d+\.\d+\.\d+)\s+(?<applicationID>\S+)\s+(?<unique_id>\S+)\s+(?<sec_bl_sl_id>(([0-9]{5}|.{0})-[0-9]{0,3}\s)+)\s*(?<sec_attack_id>([0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}|-))\s+\'(?<description>[^']*)\'\s+\'(?<attack_family>[^']+)\'" }

	# Specify in this custom field the +/- hours of the timezone (+1h for Europe/Paris)
	add_field => [ "timezone", "+0100" ]
	add_field => [ "log_type", "alert" ]
	# Duplicate field for get Application Name after
	add_field => [ "application", "%{applicationID}" ]
	add_tag => [ "rweb_logs" , "rweb_alert_logs"]
}

Du fait que les Alert logs ne fournissent pas le nom d’application mais que l’UID, on duplique l’UID dans un nouveau champ (application) et ensuite on modifie de manière statique (ou scripté) via un mutate.

mutate {
	#  remove_field => [ "message" ]
	} alter {
	condrewrite => [
	"user", "", "-",
	"bytes_received", "", "-",
	"referrer", "", "-",
	"application", "56b7df6c-e9e6-454d-9ab5-45d357aaf5e7", "APP_NAME",
	"timestamp_MM", "01", "Jan",
	"timestamp_MM", "02", "Feb",
	"timestamp_MM", "03", "Mar",
	"timestamp_MM", "04", "Apr",
	"timestamp_MM", "05", "May",
	"timestamp_MM", "06", "Jun",
	"timestamp_MM", "07", "Jul",
	"timestamp_MM", "08", "Aug",
	"timestamp_MM", "09", "Sep",
	"timestamp_MM", "10", "Oct",
	"timestamp_MM", "11", "Nov",
	"timestamp_MM", "12", "Dec" ]
	}
}

Aide au debug

Aide/debug de pattern grok