|
5 | 5 | "encoding/json"
|
6 | 6 | "fmt"
|
7 | 7 | "io/ioutil"
|
| 8 | + syslog "github.com/RackSec/srslog" |
8 | 9 | "net/http"
|
9 | 10 | "os"
|
10 | 11 | "os/signal"
|
@@ -192,6 +193,18 @@ func setupOutput(outputs []string) *flamingo.RecordWriter {
|
192 | 193 | continue
|
193 | 194 | }
|
194 | 195 |
|
| 196 | + if strings.HasPrefix(output, "syslog:") || output == "syslog" { |
| 197 | + writer, cleaner, err := getSyslogWriter(output) |
| 198 | + if err != nil { |
| 199 | + log.Fatalf("failed to configure output %s: %s", output, err) |
| 200 | + } |
| 201 | + rw.OutputWriters = append(rw.OutputWriters, writer) |
| 202 | + if cleaner != nil { |
| 203 | + rw.OutputCleaners = append(rw.OutputCleaners, cleaner) |
| 204 | + } |
| 205 | + continue |
| 206 | + } |
| 207 | + |
195 | 208 | // Assume anything else is a file output
|
196 | 209 | writer, cleaner, err := getFileWriter(output)
|
197 | 210 | if err != nil {
|
@@ -252,6 +265,65 @@ func getWebhookWriter(url string) (flamingo.OutputWriter, flamingo.OutputCleaner
|
252 | 265 | }, flamingo.OutputCleanerNoOp, nil
|
253 | 266 | }
|
254 | 267 |
|
| 268 | +func getSyslogWriter(url string) (flamingo.OutputWriter, flamingo.OutputCleaner, error) { |
| 269 | + |
| 270 | + var syslogWriter *syslog.Writer |
| 271 | + var err error |
| 272 | + |
| 273 | + // Supported formats |
| 274 | + // - syslog:unix:/dev/log |
| 275 | + // - syslog:host:port |
| 276 | + // - syslog:udp:host |
| 277 | + // - syslog:udp:host:port |
| 278 | + // - syslog:tcp:host:port |
| 279 | + |
| 280 | + bits := strings.Split(url, ":") |
| 281 | + switch len(bits) { |
| 282 | + case 1: |
| 283 | + syslogWriter, err = syslog.Dial("", "", syslog.LOG_ALERT, "flamingo") |
| 284 | + case 2: |
| 285 | + syslogWriter, err = syslog.Dial("udp", fmt.Sprintf("%s:514", bits[1]), syslog.LOG_ALERT, "flamingo") |
| 286 | + case 3: |
| 287 | + switch bits[1] { |
| 288 | + case "unix": |
| 289 | + syslogWriter, err = syslog.Dial("", bits[2], syslog.LOG_ALERT, "flamingo") |
| 290 | + case "udp", "tcp", "tcp+tls": |
| 291 | + syslogWriter, err = syslog.Dial(bits[1], fmt.Sprintf("%s:514", bits[2]), syslog.LOG_ALERT, "flamingo") |
| 292 | + default: |
| 293 | + syslogWriter, err = syslog.Dial("udp", fmt.Sprintf("%s:%s", bits[1], bits[2]), syslog.LOG_ALERT, "flamingo") |
| 294 | + } |
| 295 | + |
| 296 | + case 4: |
| 297 | + switch bits[1] { |
| 298 | + case "unix": |
| 299 | + syslogWriter, err = syslog.Dial("", bits[2], syslog.LOG_ALERT, "flamingo") |
| 300 | + case "udp", "tcp", "tcp+tls": |
| 301 | + syslogWriter, err = syslog.Dial(bits[1], fmt.Sprintf("%s:%s", bits[2], bits[3]), syslog.LOG_ALERT, "flamingo") |
| 302 | + default: |
| 303 | + err = fmt.Errorf("unsupported syslog transport %s", bits[1]) |
| 304 | + } |
| 305 | + default: |
| 306 | + err = fmt.Errorf("unsupported syslog destination %s", url) |
| 307 | + } |
| 308 | + |
| 309 | + if err != nil { |
| 310 | + return flamingo.OutputWriterNoOp, flamingo.OutputCleanerNoOp, err |
| 311 | + } |
| 312 | + |
| 313 | + err = syslogWriter.Debug("flamingo is starting up") |
| 314 | + if err != nil { |
| 315 | + return flamingo.OutputWriterNoOp, flamingo.OutputCleanerNoOp, err |
| 316 | + } |
| 317 | + |
| 318 | + return func(rec map[string]string) error { |
| 319 | + bytes, err := json.Marshal(rec) |
| 320 | + if err != nil { |
| 321 | + return err |
| 322 | + } |
| 323 | + return sendSyslog(syslogWriter, string(bytes)) |
| 324 | + }, func() { syslogWriter.Close() }, nil |
| 325 | +} |
| 326 | + |
255 | 327 | func setupTLS() {
|
256 | 328 | tlsCertData := ""
|
257 | 329 | tlsKeyData := ""
|
@@ -510,3 +582,7 @@ func sendWebhook(url string, msg string) error {
|
510 | 582 |
|
511 | 583 | return nil
|
512 | 584 | }
|
| 585 | + |
| 586 | +func sendSyslog(w *syslog.Writer, msg string) error { |
| 587 | + return w.Alert(msg) |
| 588 | +} |
0 commit comments