Skip to content

Commit c0e37ac

Browse files
authored
Merge pull request #31 from wizecore/ottimo-pr28
Ottimo pr28
2 parents ecd20fb + a39d906 commit c0e37ac

File tree

4 files changed

+291
-3
lines changed

4 files changed

+291
-3
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,23 @@ Example:
6262
<14>1 2016-03-31T19:19:02.524Z graylog unknown - nginx [all@0 request_verb="GET" remote_addr="192.168.1.37" response_status="404" from_nginx="true" level="6" connection_requests="1" http_version="1.1" response_bytes="1906" source="nginx" message="GET /test1/x HTTP/1.1" gl2_source_input="566c96abe4b094dfbc2661a8" version="1.1" nginx_access="true" http_user_agent="Wget/1.15 (linux-gnu)" remote_user="-" connection_id="970" http_referer="-" request_path="/test1/x" gl2_source_node="bebd092c-85d7-49a3-8188-f7af734747fb" _id="6d833da0-f775-11e5-b30c-0800276c97db" millis="0.002" facility="runit-service" timestamp="2016-03-31T19:19:02.000Z"] source: nginx | message: GET /test1/x HTTP/1.1 { request_verb: GET | remote_addr: 192.168.1.37 | response_status: 404 | from_nginx: true | level: 6 | connection_requests: 1 | http_version: 1.1 | response_bytes: 1906 | gl2_source_input: 566c96abe4b094dfbc2661a8 | version: 1.1 | nginx_access: true | http_user_agent: Wget/1.15 (linux-gnu) | remote_user: - | connection_id: 970 | http_referer: - | request_path: /test1/x | gl2_source_node: bebd092c-85d7-49a3-8188-f7af734747fb | _id: 6d833da0-f775-11e5-b30c-0800276c97db | millis: 0.002 | facility: runit-service | timestamp: 2016-03-31T19:19:02.000Z }
6363
````
6464

65+
### trasparent syslog
66+
67+
A variation of plain sender without facility and source (there are in
68+
original message).
69+
Example:
70+
````
71+
<14>Feb 11 17:32:06 graylog01 sshd[26524]: Failed password for admin7 from 10.128.230.28 port 58363 ssh2
72+
````
73+
74+
### snare windows
75+
76+
Re-build a snare log format of windows event in stream.
77+
Example:
78+
````
79+
<14>Feb 11 17:32:26 graylog01 MSWinEventLog 1 Security 65493 Mon Feb 11 17:32:26 2019 4726 Microsoft-Windows-Security-Auditing N/A N/A AUDIT_SUCCESS WIN-8F8OSAB5AMC.testwin.lan User Account Management A user account was deleted. Subject: Security ID: S-1-5-21-2081084977-3747244460-254679223-500 Account Name: Administrator Account Domain: TESTWIN Logon ID: 0x5F1B5 Target Account: Security ID: S-1-5-21-2081084977-3747244460-254679223-1126 Account Name: admintest Account Domain: TESTWIN Additional Information: Privileges - 65493
80+
````
81+
6582
### custom:FQCN
6683

6784
Specify your implementation of com.wizecore.graylog2.plugin.MessageSender interface.
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package com.wizecore.graylog2.plugin;
2+
3+
import java.text.SimpleDateFormat;
4+
import java.util.Date;
5+
import java.util.Locale;
6+
import java.util.logging.Logger;
7+
8+
import org.graylog2.plugin.Message;
9+
import org.graylog2.syslog4j.SyslogIF;
10+
11+
/**
12+
* Formats fields into message text
13+
*
14+
15+
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOM'su root' failed for lonvick on /dev/pts/8
16+
^priority
17+
^ version
18+
^ date
19+
^ host
20+
^ APP-NAME
21+
^ structured data?
22+
^ MSGID
23+
24+
*/
25+
public class SnareWindowsSender implements MessageSender {
26+
private Logger log = Logger.getLogger(SnareWindowsSender.class.getName());
27+
28+
public static final String SYSLOG_DATEFORMAT = "MMM dd HH:mm:ss";
29+
public static final String MSEVENT_DATEFORMAT = "EEE MMM dd HH:mm:ss yyyy";
30+
public static final String SEPARATOR = "\t";
31+
/**
32+
* From syslog4j
33+
*
34+
* @param dt
35+
* @return
36+
*/
37+
public static void appendSyslogTimestamp(Date dt, StringBuilder buffer) {
38+
SimpleDateFormat dateFormat = new SimpleDateFormat(SYSLOG_DATEFORMAT,Locale.ENGLISH);
39+
String datePrefix = dateFormat.format(dt);
40+
41+
int pos = buffer.length() + 4;
42+
buffer.append(datePrefix);
43+
44+
// RFC 3164 requires leading space for days 1-9
45+
if (buffer.charAt(pos) == '0') {
46+
buffer.setCharAt(pos,' ');
47+
}
48+
}
49+
50+
public static void appendMSEventTimestamp(Date dt, StringBuilder buffer) {
51+
SimpleDateFormat dateFormat = new SimpleDateFormat(MSEVENT_DATEFORMAT,Locale.ENGLISH);
52+
String datePrefix = dateFormat.format(dt);
53+
54+
int pos = buffer.length() + 4;
55+
buffer.append(datePrefix);
56+
57+
// RFC 3164 requires leading space for days 1-9
58+
if (buffer.charAt(pos) == '0') {
59+
buffer.setCharAt(pos,' ');
60+
}
61+
}
62+
63+
@Override
64+
public void send(SyslogIF syslog, int level, Message msg) {
65+
StringBuilder out = new StringBuilder();
66+
//appendHeader(msg, out);
67+
68+
69+
Date dt = null;
70+
Object ts = msg.getField("timestamp");
71+
if (ts != null && ts instanceof Number) {
72+
dt = new Date(((Number) ts).longValue());
73+
}
74+
75+
if (dt == null) {
76+
dt = new Date();
77+
}
78+
79+
out.append("MSWinEventLog").append(SEPARATOR);
80+
appendCriticality(msg, out);
81+
appendField(msg, out, "Channel");
82+
appendField(msg, out, "RecordNumber"); // we do not have snare counter
83+
// Write time
84+
appendMSEventTimestamp(dt, out);
85+
out.append(SEPARATOR);
86+
87+
appendField(msg, out, "EventID");
88+
89+
appendField(msg, out, "SourceName");
90+
appendWinUser(msg, out);
91+
appendField(msg, out, "AccountType");
92+
93+
appendField(msg, out, "EventType");
94+
95+
appendField(msg, out, "source");
96+
appendField(msg, out, "Category");
97+
98+
// manca il data
99+
out.append(SEPARATOR);
100+
101+
// ExtendedData
102+
appendField(msg, out, "message");
103+
104+
Object fld = msg.getField("RecordNumber");
105+
if (fld == null){
106+
fld = new String("N/A");
107+
}
108+
out.append(fld.toString());
109+
110+
//out.append(msg.getMessage());
111+
String str = out.toString();
112+
// log.info("Sending plain message: " + level + ", " + str);
113+
syslog.log(level, str);
114+
}
115+
116+
public static void appendHeader(Message msg, StringBuilder out) {
117+
Date dt = null;
118+
Object ts = msg.getField("timestamp");
119+
if (ts != null && ts instanceof Number) {
120+
dt = new Date(((Number) ts).longValue());
121+
}
122+
123+
if (dt == null) {
124+
dt = new Date();
125+
}
126+
127+
//appendPriority(msg, out);
128+
129+
// Write time
130+
appendSyslogTimestamp(dt, out);
131+
out.append(" ");
132+
133+
Object fld = msg.getField("source");
134+
if (fld == null){
135+
fld = new String("N/A");
136+
}
137+
out.append(fld.toString());
138+
out.append(" ");
139+
}
140+
141+
public static void appendField(Message msg, StringBuilder out, String field){
142+
Object fld = msg.getField(field.toString());
143+
if (fld == null){
144+
fld = new String("N/A");
145+
}
146+
String f = fld.toString().replaceAll("\t", " ");
147+
out.append(f).append(SEPARATOR);
148+
}
149+
150+
public static void appendWinUser(Message msg, StringBuilder out){
151+
Object domain = msg.getField("Domain");
152+
if(domain != null){
153+
out.append(domain.toString()).append("\\");
154+
}
155+
appendField(msg, out, "AccountName");
156+
}
157+
158+
public static void appendCriticality(Message msg, StringBuilder out){
159+
Object severityValue = msg.getField("SeverityValue");
160+
String criticality = "0";
161+
if(severityValue!=null){
162+
int i_severityValue = Integer.parseInt(severityValue.toString());
163+
criticality = String.valueOf(i_severityValue-1);
164+
}
165+
out.append(criticality.toString()).append(SEPARATOR);
166+
}
167+
168+
public static void appendPriority(Message msg, StringBuilder out){
169+
out.append("<").append("14").append(">");
170+
}
171+
}

src/main/java/com/wizecore/graylog2/plugin/SyslogOutput.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import java.util.List;
55
import java.util.Map;
6+
import java.util.HashMap;
67
import java.util.logging.Logger;
78

89
import javax.inject.Inject;
@@ -13,6 +14,7 @@
1314
import org.graylog2.plugin.configuration.fields.ConfigurationField;
1415
import org.graylog2.plugin.configuration.fields.DropdownField;
1516
import org.graylog2.plugin.configuration.fields.TextField;
17+
import org.graylog2.plugin.configuration.fields.BooleanField;
1618
import org.graylog2.plugin.outputs.MessageOutput;
1719
import org.graylog2.plugin.streams.Stream;
1820
import org.graylog2.syslog4j.Syslog;
@@ -46,11 +48,17 @@ public class SyslogOutput implements MessageOutput {
4648
private String format;
4749
private MessageSender sender;
4850

49-
public static MessageSender createSender(String fmt) {
51+
public static MessageSender createSender(String fmt, Configuration conf) {
5052
try {
5153
if (fmt == null || fmt.equalsIgnoreCase("plain")) {
5254
return new PlainSender();
5355
} else
56+
if (fmt == null || fmt.equalsIgnoreCase("transparent")) {
57+
return new TrasparentSyslogSender(conf);
58+
} else
59+
if (fmt == null || fmt.equalsIgnoreCase("snare")) {
60+
return new SnareWindowsSender();
61+
} else
5462
if (fmt == null || fmt.equalsIgnoreCase("structured")) {
5563
return new StructuredSender();
5664
} else
@@ -135,7 +143,7 @@ public SyslogOutput(@Assisted Stream stream, @Assisted Configuration conf) {
135143
String hash = protocol + "_" + host + "_" + port + "_" + format;
136144
syslog = Syslog.exists(hash) ? Syslog.getInstance(hash) : Syslog.createInstance(hash, config);
137145

138-
sender = createSender(format);
146+
sender = createSender(format, conf);
139147
if (sender instanceof StructuredSender) {
140148
// Always send via structured data
141149
syslog.getConfig().setUseStructuredData(true);
@@ -247,12 +255,21 @@ public ConfigurationRequest getRequestedConfiguration() {
247255
configurationRequest.addField(new TextField("host", "Syslog host", "localhost", "Remote host to send syslog messages to.", ConfigurationField.Optional.NOT_OPTIONAL));
248256
configurationRequest.addField(new TextField("port", "Syslog port", "514", "Syslog port on the remote host. Default is 514.", ConfigurationField.Optional.NOT_OPTIONAL));
249257

250-
final Map<String, String> formats = ImmutableMap.of("plain", "plain", "structured", "structured", "cef", "cef", "full", "full");
258+
HashMap<String, String> types = new HashMap<String,String>();
259+
types.put("plain", "plain");
260+
types.put("structured", "structured");
261+
types.put("cef", "cef");
262+
types.put("full", "full");
263+
types.put("transparent", "transparent");
264+
types.put("snare", "snare");
265+
266+
final Map<String, String> formats = ImmutableMap.copyOf(types);
251267
configurationRequest.addField(new DropdownField(
252268
"format", "Message format", "plain", formats,
253269
"Message format. For detailed explanation, see https://github.com/wizecore/graylog2-output-syslog",
254270
ConfigurationField.Optional.NOT_OPTIONAL)
255271
);
272+
configurationRequest.addField(new BooleanField("transparentFormatRemoveHeader", "Remove header (only for transparent)", false, "Do not insert timestamp header when it forwards the message content."));
256273

257274
configurationRequest.addField(new TextField("maxlen", "Maximum message length", "", "Maximum message (body) length. Longer messages will be truncated. If not specified defaults to 16384 bytes.", ConfigurationField.Optional.OPTIONAL));
258275

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package com.wizecore.graylog2.plugin;
2+
3+
import java.text.SimpleDateFormat;
4+
import java.util.Date;
5+
import java.util.Locale;
6+
import java.util.logging.Logger;
7+
8+
import org.graylog2.plugin.configuration.Configuration;
9+
import org.graylog2.plugin.Message;
10+
import org.graylog2.syslog4j.SyslogIF;
11+
12+
/**
13+
* Formats fields into message text
14+
*
15+
16+
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - BOM'su root' failed for lonvick on /dev/pts/8
17+
^priority
18+
^ version
19+
^ date
20+
^ host
21+
^ APP-NAME
22+
^ structured data?
23+
^ MSGID
24+
25+
*/
26+
public class TrasparentSyslogSender implements MessageSender {
27+
private Logger log = Logger.getLogger(TrasparentSyslogSender.class.getName());
28+
private boolean removeHeader = false;
29+
30+
public static final String SYSLOG_DATEFORMAT = "MMM dd HH:mm:ss";
31+
32+
public TrasparentSyslogSender(Configuration conf){
33+
removeHeader = conf.getBoolean("transparentFormatRemoveHeader");
34+
}
35+
36+
/**
37+
* From syslog4j
38+
*
39+
* @param dt
40+
* @return
41+
*/
42+
public static void appendSyslogTimestamp(Date dt, StringBuilder buffer) {
43+
SimpleDateFormat dateFormat = new SimpleDateFormat(SYSLOG_DATEFORMAT,Locale.ENGLISH);
44+
String datePrefix = dateFormat.format(dt);
45+
46+
int pos = buffer.length() + 4;
47+
buffer.append(datePrefix);
48+
49+
// RFC 3164 requires leading space for days 1-9
50+
if (buffer.charAt(pos) == '0') {
51+
buffer.setCharAt(pos,' ');
52+
}
53+
}
54+
55+
@Override
56+
public void send(SyslogIF syslog, int level, Message msg) {
57+
StringBuilder out = new StringBuilder();
58+
if(removeHeader!=true){
59+
appendHeader(msg, out);
60+
}
61+
62+
out.append(msg.getMessage());
63+
String str = out.toString();
64+
// log.info("Sending plain message: " + level + ", " + str);
65+
syslog.log(level, str);
66+
}
67+
68+
public static void appendHeader(Message msg, StringBuilder out) {
69+
Date dt = null;
70+
Object ts = msg.getField("timestamp");
71+
if (ts != null && ts instanceof Number) {
72+
dt = new Date(((Number) ts).longValue());
73+
}
74+
75+
if (dt == null) {
76+
dt = new Date();
77+
}
78+
79+
// Write time
80+
appendSyslogTimestamp(dt, out);
81+
out.append(" ");
82+
}
83+
}

0 commit comments

Comments
 (0)