func (beat *Beat) ConfigSetup(beater Beater, inputConfig interface{}) { config := &ConfigSettings{ //Input: inputConfig, } err := cfgfile.Read(config) beat.Config = *config if err != nil { logp.Debug("Log read error", "Error %v\n", err) } logp.Init(beat.Name, &beat.Config.Logging) logp.Debug("main", "Initializing output plugins") if err := publisher.Publisher.Init(beat.Config.Output, beat.Config.Shipper); err != nil { logp.Critical(err.Error()) os.Exit(1) } beat.events = publisher.Publisher.Queue logp.Debug(beat.Name, "Init %s", beat.Name) if err := beater.Init(beat); err != nil { logp.Critical(err.Error()) os.Exit(1) } }
func loadTLSConfig(config *TLSConfig) (*tlsConfig, error) { var tlsconfig tlsConfig // Support minimal TLS 1.0. // TODO: check supported JRuby versions for logstash supported // TLS 1.1 and switch tlsconfig.MinVersion = tls.VersionTLS10 hasCertificate := config.Certificate != "" hasKey := config.Key != "" switch { case hasCertificate && !hasKey: return nil, ErrCertificateNoKey case !hasCertificate && hasKey: return nil, ErrKeyNoCertificate case hasCertificate && hasKey: cert, err := tls.LoadX509KeyPair(config.Certificate, config.Key) if err != nil { logp.Critical("Failed loading client certificate", err) return nil, err } tlsconfig.Certificates = []tls.Certificate{cert} } if len(config.CAs) > 0 { tlsconfig.RootCAs = x509.NewCertPool() } for _, caFile := range config.CAs { pemData, err := ioutil.ReadFile(caFile) if err != nil { logp.Critical("Failed reading CA certificate: %s", err) return nil, err } block, _ := pem.Decode(pemData) if block == nil { logp.Critical("Failed to decode PEM. Is certificate %s valid?", caFile) return nil, ErrNotACertificate } if block.Type != "CERTIFICATE" { logp.Critical("PEM File %s is not a certificate", caFile) return nil, ErrNotACertificate } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { logp.Critical("Failed to parse certificate file %s", caFile) return nil, ErrNotACertificate } tlsconfig.RootCAs.AddCert(cert) } return &tlsconfig, nil }
// LoadTLSConfig will load a certificate from config with all TLS based keys // defined. If Certificate and CertificateKey are configured, client authentication // will be configured. If no CAs are configured, the host CA will be used by go // built-in TLS support. func LoadTLSConfig(config MothershipConfig) (*tls.Config, error) { certificate := config.Certificate key := config.CertificateKey rootCAs := config.CAs hasCertificate := certificate != "" hasKey := key != "" var certs []tls.Certificate switch { case hasCertificate && !hasKey: return nil, ErrCertificateNoKey case !hasCertificate && hasKey: return nil, ErrKeyNoCertificate case hasCertificate && hasKey: cert, err := tls.LoadX509KeyPair(certificate, key) if err != nil { logp.Critical("Failed loading client certificate", err) return nil, err } certs = []tls.Certificate{cert} } var roots *x509.CertPool if len(rootCAs) > 0 { roots = x509.NewCertPool() for _, caFile := range rootCAs { pemData, err := ioutil.ReadFile(caFile) if err != nil { logp.Critical("Failed reading CA certificate: %s", err) return nil, err } if ok := roots.AppendCertsFromPEM(pemData); !ok { return nil, ErrNotACertificate } } } insecureSkipVerify := false if config.TLSInsecure != nil { insecureSkipVerify = *config.TLSInsecure } // Support minimal TLS 1.0. // TODO: check supported JRuby versions for logstash supported // TLS 1.1 and switch tlsConfig := tls.Config{ MinVersion: tls.VersionTLS10, Certificates: certs, RootCAs: roots, InsecureSkipVerify: insecureSkipVerify, } return &tlsConfig, nil }
func (pb *Packetbeat) Run(b *beat.Beat) error { // run the sniffer in background go func() { err := pb.Sniff.Run() if err != nil { logp.Critical("Sniffer main loop failed: %v", err) os.Exit(1) } pb.over <- true }() // Startup successful, disable stderr logging if requested by // cmdline flag logp.SetStderr() logp.Debug("main", "Waiting for the sniffer to finish") // Wait for the goroutines to finish for _ = range pb.over { if !pb.Sniff.IsAlive() { break } } waitShutdown := pb.CmdLineArgs.WaitShutdown if waitShutdown != nil && *waitShutdown > 0 { time.Sleep(time.Duration(*waitShutdown) * time.Second) } return nil }
func main() { // Create Beater object fb := &filebeat.Filebeat{} // Initi beat objectefile b := beat.NewBeat(Name, Version, fb) // Additional command line args are used to overwrite config options b.CommandLineSetup() // Loads base config b.LoadConfig() // Configures beat err := fb.Config(b) if err != nil { logp.Critical("Config error: %v", err) os.Exit(1) } // Run beat. This calls first beater.Setup, // then beater.Run and beater.Cleanup in the end b.Run() }
// LoadConfig inits the config file and reads the default config information // into Beat.Config. It exists the processes in case of errors. func (b *Beat) LoadConfig() { err := cfgfile.Read(&b.Config, "") if err != nil { // logging not yet initialized, so using fmt.Printf fmt.Printf("%v\n", err) os.Exit(1) } err = logp.Init(b.Name, &b.Config.Logging) if err != nil { fmt.Printf("Error initializing logging: %v\n", err) os.Exit(1) } logp.Debug("beat", "Initializing output plugins") if err := publisher.Publisher.Init(b.Name, b.Version, b.Config.Output, b.Config.Shipper); err != nil { logp.Critical(err.Error()) os.Exit(1) } b.Events = publisher.Publisher.Client() logp.Debug("beat", "Init %s", b.Name) }
// LoadConfig inits the config file and reads the default config information // into Beat.Config. It exists the processes in case of errors. func (b *Beat) LoadConfig() { err := cfgfile.Read(&b.Config, "") if err != nil { // logging not yet initialized, so using fmt.Printf fmt.Printf("Loading config file error: %v\n", err) os.Exit(1) } err = logp.Init(b.Name, &b.Config.Logging) if err != nil { fmt.Printf("Error initializing logging: %v\n", err) os.Exit(1) } // Disable stderr logging if requested by cmdline flag logp.SetStderr() logp.Debug("beat", "Initializing output plugins") if err := publisher.Publisher.Init(b.Name, b.Config.Output, b.Config.Shipper); err != nil { fmt.Printf("Error Initialising publisher: %v\n", err) logp.Critical(err.Error()) os.Exit(1) } b.Events = publisher.Publisher.Client() logp.Debug("beat", "Init %s", b.Name) }
func (p *Pingbeat) Run(b *beat.Beat) error { p.isAlive = true fp := fastping.NewPinger() errInput, err := fp.Network(p.pingType) if err != nil { logp.Critical("Error: %v (input %v)", err, errInput) os.Exit(1) } if p.useIPv4 { for addr, details := range p.ipv4targets { logp.Debug("pingbeat", "Adding target IP: %s, Name: %s, Tag: %s\n", addr, details[0], details[1]) fp.AddIP(addr) } } if p.useIPv6 { for addr, details := range p.ipv6targets { logp.Debug("pingbeat", "Adding target IP: %s, Name: %s, Tag: %s\n", addr, details[0], details[1]) fp.AddIP(addr) } } fp.OnRecv = func(addr *net.IPAddr, rtt time.Duration) { var name, tag string ip := addr.IP if ip.To4() != nil { name = p.ipv4targets[addr.String()][0] tag = p.ipv4targets[addr.String()][1] } else { name = p.ipv6targets[addr.String()][0] tag = p.ipv6targets[addr.String()][1] } event := common.MapStr{ "timestamp": common.Time(time.Now()), "type": "pingbeat", "target_name": name, "target_addr": addr.String(), "tag": tag, "rtt": milliSeconds(rtt), } p.events.PublishEvent(event) } // fp.OnIdle = func() { // fmt.Println("loop done") // } for p.isAlive { time.Sleep(p.period) err := fp.Run() if err != nil { logp.Warn("Warning: %v", err) } } return nil }
func (p *Pingbeat) Config(b *beat.Beat) error { // Read in provided config file, bail if problem err := cfgfile.Read(&p.config, "") if err != nil { logp.Err("Error reading configuration file: %v", err) return err } // Use period provided in config or default to 5s if p.config.Input.Period != nil { p.period = time.Duration(*p.config.Input.Period) * time.Second } else { p.period = 5 * time.Second } logp.Debug("pingbeat", "Period %v\n", p.period) // Check if we can use privileged (i.e. raw socket) ping, // else use a UDP ping if *p.config.Input.Privileged { p.pingType = "ip" } else { p.pingType = "udp" } logp.Debug("pingbeat", "Using %v for pings\n", p.pingType) // Check whether IPv4/IPv6 pings are requested in config // Default to just IPv4 pings if &p.config.Input.UseIPv4 != nil { p.useIPv4 = *p.config.Input.UseIPv4 } else { p.useIPv4 = true } if &p.config.Input.UseIPv6 != nil { p.useIPv6 = *p.config.Input.UseIPv6 } else { p.useIPv6 = false } logp.Debug("pingbeat", "IPv4: %v, IPv6: %v\n", p.useIPv4, p.useIPv6) // Fill the IPv4/IPv6 targets maps p.ipv4targets = make(map[string][2]string) p.ipv6targets = make(map[string][2]string) if p.config.Input.Targets != nil { for tag, targets := range *p.config.Input.Targets { for i := 0; i < len(targets); i++ { p.AddTarget(targets[i], tag) } } } else { logp.Critical("Error: no targets specified, cannot continue!") os.Exit(1) } return nil }
// Run calls the beater Setup and Run methods. In case of errors // during the setup phase, it exits the process. func (b *Beat) Run() { // Setup beater object err := b.BT.Setup(b) if err != nil { logp.Critical("Setup returned an error: %v", err) os.Exit(1) } // Up to here was the initialization, now about running if cfgfile.IsTestConfig() { // all good, exit with 0 os.Exit(0) } service.BeforeRun() // Callback is called if the processes is asked to stop. // This needs to be called before the main loop is started so that // it can register the signals that stop or query (on Windows) the loop. service.HandleSignals(b.BT.Stop) // Startup successful, disable stderr logging if requested by // cmdline flag logp.SetStderr() // Run beater specific stuff err = b.BT.Run(b) if err != nil { logp.Critical("Run returned an error: %v", err) } service.Cleanup() logp.Debug("beat", "Cleanup") // Call beater cleanup function err = b.BT.Cleanup(b) if err != nil { logp.Err("Cleanup returned an error: %v", err) } }
// Run calls the beater Setup and Run methods. In case of errors // during the setup phase, it exits the process. func (b *Beat) Run() { // Setup beater object err := b.BT.Setup(b) if err != nil { logp.Critical("Setup returned an error: %v", err) os.Exit(1) } // Up to here was the initialization, now about running if cfgfile.IsTestConfig() { // all good, exit with 0 os.Exit(0) } service.BeforeRun() // Callback is called if the processes is asked to stop. // This needs to be called before the main loop is started so that // it can register the signals that stop or query (on Windows) the loop. service.HandleSignals(b.BT.Stop) logp.Info("%s sucessfully setup. Start running.", b.Name) // Run beater specific stuff err = b.BT.Run(b) if err != nil { logp.Critical("Run returned an error: %v", err) } service.Cleanup() logp.Info("Cleaning up %s before shutting down.", b.Name) // Call beater cleanup function err = b.BT.Cleanup(b) if err != nil { logp.Err("Cleanup returned an error: %v", err) } }
func (crawler *Crawler) Start(files []config.ProspectorConfig, eventChan chan *input.FileEvent) { pendingProspectorCnt := 0 crawler.running = true // Prospect the globs/paths given on the command line and launch harvesters for _, fileconfig := range files { logp.Debug("prospector", "File Configs: %v", fileconfig.Paths) prospector := &Prospector{ ProspectorConfig: fileconfig, registrar: crawler.Registrar, } err := prospector.Init() if err != nil { logp.Critical("Error in initing prospector: %s", err) fmt.Printf("Error in initing prospector: %s", err) os.Exit(1) } go prospector.Run(eventChan) pendingProspectorCnt++ } // Now determine which states we need to persist by pulling the events from the prospectors // When we hit a nil source a prospector had finished so we decrease the expected events logp.Debug("prospector", "Waiting for %d prospectors to initialise", pendingProspectorCnt) for event := range crawler.Registrar.Persist { if event.Source == nil { pendingProspectorCnt-- if pendingProspectorCnt == 0 { logp.Debug("prospector", "No pending prospectors. Finishing setup") break } continue } crawler.Registrar.State[*event.Source] = event logp.Debug("prospector", "Registrar will re-save state for %s", *event.Source) if !crawler.running { break } } logp.Info("All prospectors initialised with %d states to persist", len(crawler.Registrar.State)) }
func (p *Pingbeat) Config(b *beat.Beat) error { err := cfgfile.Read(&p.config, "") if err != nil { logp.Err("Error reading configuration file: %v", err) return err } if p.config.Input.Period != nil { p.period = time.Duration(*p.config.Input.Period) * time.Second } else { p.period = 1 * time.Second } logp.Debug("pingbeat", "Period %v\n", p.period) if *p.config.Input.Privileged { p.pingType = "ip" } else { p.pingType = "udp" } logp.Debug("pingbeat", "Using %v for pings\n", p.pingType) if &p.config.Input.UseIPv4 != nil { p.useIPv4 = *p.config.Input.UseIPv4 } else { p.useIPv4 = true } if &p.config.Input.UseIPv6 != nil { p.useIPv6 = *p.config.Input.UseIPv6 } else { p.useIPv6 = false } logp.Debug("pingbeat", "IPv4: %v, IPv6: %v\n", p.useIPv4, p.useIPv6) p.ipv4targets = make(map[string][2]string) p.ipv6targets = make(map[string][2]string) if p.config.Input.Targets != nil { for tag, targets := range *p.config.Input.Targets { for i := 0; i < len(targets); i++ { p.AddTarget(targets[i], tag) } } } else { logp.Critical("Error: no targets specified, cannot continue!") os.Exit(1) } return nil }
func main() { gb := &Gzipbeat{} b := beat.NewBeat(Name, Version, gb) b.CommandLineSetup() b.LoadConfig() err := gb.Config(b) if err != nil { logp.Critical("Config error: %v", err) os.Exit(1) } b.Run() }
// Check that the file isn't a symlink, mode is regular or file is nil func (f *File) IsRegularFile() bool { if f.File == nil { logp.Critical("Harvester: BUG: f arg is nil") return false } info, e := f.File.Stat() if e != nil { logp.Err("File check fault: stat error: %s", e.Error()) return false } if !info.Mode().IsRegular() { logp.Warn("Harvester: not a regular file: %q %s", info.Mode(), info.Name()) return false } return true }
// Inits the config file and reads the default config information into Beat.Config // This is Output, Logging and Shipper config params func (b *Beat) LoadConfig() { err := cfgfile.Read(&b.Config) if err != nil { logp.Debug("Log read error", "Error %v\n", err) } logp.Init(b.Name, &b.Config.Logging) logp.Debug("main", "Initializing output plugins") if err := publisher.Publisher.Init(b.Name, b.Config.Output, b.Config.Shipper); err != nil { logp.Critical(err.Error()) os.Exit(1) } logp.Debug(b.Name, "Init %s", b.Name) }
func main() { ab := &beat.AmqpBeat{} b := libbeat.NewBeat(name, version, ab) b.CommandLineSetup() b.LoadConfig() err := ab.Config(b) if err != nil { logp.Critical("Cannot start due to configuration error: %v", err) os.Exit(1) } b.Run() }
func (l *lumberjackClient) compressEvents(events []common.MapStr) (uint32, []byte) { buf := bytes.NewBuffer(nil) // compress events compressor, _ := zlib.NewWriterLevel(buf, 3) // todo make compression level configurable? var sequence uint32 for _, event := range events { sequence++ err := l.writeDataFrame(event, sequence, compressor) if err != nil { logp.Critical("failed to encode event: %v", err) sequence-- //forget this last broken event and continue } } compressor.Flush() compressor.Close() payload := buf.Bytes() return sequence, payload }
// internal libbeat function that calls beater Run method func (beat *Beat) Run(beater Beater) { service.BeforeRun() service.HandleSignals(beat.stop) beat.isAlive = true for beat.isAlive { time.Sleep(beat.Period) err := beater.Run(beat) if err != nil { logp.Critical("Fetching failed: %v", err) os.Exit(1) } } logp.Debug("main", "Cleanup") service.Cleanup() }
// Initiates and runs a new beat object func Run(name string, version string, bt Beater) *Beat { b := NewBeat(name, version, bt) // Additional command line args are used to overwrite config options b.CommandLineSetup() // Loads base config b.LoadConfig() // Configures beat err := bt.Config(b) if err != nil { logp.Critical("Config error: %v", err) os.Exit(1) } // Run beat. This calls first beater.Setup, // then beater.Run and beater.Cleanup in the end b.Run() return b }
func main() { over := make(chan bool) // Use our own FlagSet, because some libraries pollute the global one var cmdLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) cfgfile.CmdLineFlags(cmdLine, Name) logp.CmdLineFlags(cmdLine) service.CmdLineFlags(cmdLine) publishDisabled := cmdLine.Bool("N", false, "Disable actual publishing for testing") printVersion := cmdLine.Bool("version", false, "Print version and exit") cmdLine.Parse(os.Args[1:]) if *printVersion { fmt.Printf("%s version %s (%s)\n", Name, Version, runtime.GOARCH) return } err := cfgfile.Read(&Config) logp.Init(Name, &Config.Logging) logp.Debug("main", "Initializing output plugins") if err = publisher.Publisher.Init(*publishDisabled, Config.Output, Config.Shipper); err != nil { logp.Critical(err.Error()) os.Exit(1) } topbeat := &Topbeat{} if err = topbeat.Init(Config.Input, publisher.Publisher.Queue); err != nil { logp.Critical(err.Error()) os.Exit(1) } // Up to here was the initialization, now about running if cfgfile.IsTestConfig() { // all good, exit with 0 os.Exit(0) } service.BeforeRun() // run the Beat code in background go func() { err := topbeat.Run() if err != nil { logp.Critical("Sniffer main loop failed: %v", err) os.Exit(1) } over <- true }() service.HandleSignals(topbeat.Stop) // Startup successful, disable stderr logging if requested by // cmdline flag logp.SetStderr() logp.Debug("main", "Starting topbeat") // Wait for the goroutines to finish for _ = range over { if !topbeat.IsAlive() { break } } logp.Debug("main", "Cleanup") service.Cleanup() }
func main() { // Use our own FlagSet, because some libraries pollute the global one var cmdLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) // configfile := cmdLine.String("c", "packetbeat.dev.yml", "Configuration file") configfile := cmdLine.String("c", "/etc/packetbeat/packetbeat.yml", "Configuration file") file := cmdLine.String("I", "", "file") loop := cmdLine.Int("l", 1, "Loop file. 0 - loop forever") debugSelectorsStr := cmdLine.String("d", "", "Enable certain debug selectors") oneAtAtime := cmdLine.Bool("O", false, "Read packets one at a time (press Enter)") toStderr := cmdLine.Bool("e", false, "Output to stdout instead of syslog") topSpeed := cmdLine.Bool("t", false, "Read packets as fast as possible, without sleeping") publishDisabled := cmdLine.Bool("N", false, "Disable actual publishing for testing") verbose := cmdLine.Bool("v", false, "Log at INFO level") printVersion := cmdLine.Bool("version", false, "Print version and exit") memprofile := cmdLine.String("memprofile", "", "Write memory profile to this file") cpuprofile := cmdLine.String("cpuprofile", "", "Write cpu profile to file") dumpfile := cmdLine.String("dump", "", "Write all captured packets to this libpcap file.") testConfig := cmdLine.Bool("test", false, "Test configuration and exit.") cmdLine.Parse(os.Args[1:]) sniff := new(sniffer.SnifferSetup) if *printVersion { fmt.Printf("Packetbeat version %s (%s)\n", Version, runtime.GOARCH) return } logLevel := logp.LOG_ERR if *verbose { logLevel = logp.LOG_INFO } debugSelectors := []string{} if len(*debugSelectorsStr) > 0 { debugSelectors = strings.Split(*debugSelectorsStr, ",") logLevel = logp.LOG_DEBUG } var err error filecontent, err := ioutil.ReadFile(*configfile) if err != nil { fmt.Printf("Fail to read %s: %s. Exiting.\n", *configfile, err) return } if err = yaml.Unmarshal(filecontent, &config.ConfigSingleton); err != nil { fmt.Printf("YAML config parsing failed on %s: %s. Exiting.\n", *configfile, err) return } if len(debugSelectors) == 0 { debugSelectors = config.ConfigSingleton.Logging.Selectors } logp.LogInit(logp.Priority(logLevel), "", !*toStderr, true, debugSelectors) if !logp.IsDebug("stdlog") { // disable standard logging by default log.SetOutput(ioutil.Discard) } // CLI flags over-riding config if *topSpeed { config.ConfigSingleton.Interfaces.TopSpeed = true } if len(*file) > 0 { config.ConfigSingleton.Interfaces.File = *file } config.ConfigSingleton.Interfaces.Loop = *loop config.ConfigSingleton.Interfaces.OneAtATime = *oneAtAtime if len(*dumpfile) > 0 { config.ConfigSingleton.Interfaces.Dumpfile = *dumpfile } logp.Debug("main", "Configuration %s", config.ConfigSingleton) logp.Debug("main", "Initializing output plugins") if err = publisher.Publisher.Init(*publishDisabled, config.ConfigSingleton.Output, config.ConfigSingleton.Shipper); err != nil { logp.Critical(err.Error()) os.Exit(1) } if err = procs.ProcWatcher.Init(config.ConfigSingleton.Procs); err != nil { logp.Critical(err.Error()) os.Exit(1) } logp.Debug("main", "Initializing protocol plugins") for proto, plugin := range EnabledProtocolPlugins { logp.Debug("protos", proto.String()) err = plugin.Init(false, publisher.Publisher.Queue) if err != nil { logp.Critical("Initializing plugin %s failed: %v", proto, err) os.Exit(1) } protos.Protos.Register(proto, plugin) } if err = tcp.TcpInit(); err != nil { logp.Critical(err.Error()) os.Exit(1) } over := make(chan bool) logp.Debug("main", "Initializing filters plugins") for filter, plugin := range EnabledFilterPlugins { filters.Filters.Register(filter, plugin) } filters_plugins, err := LoadConfiguredFilters(config.ConfigSingleton.Filter) if err != nil { logp.Critical("Error loading filters plugins: %v", err) os.Exit(1) } logp.Debug("main", "Filters plugins order: %v", filters_plugins) var afterInputsQueue chan common.MapStr if len(filters_plugins) > 0 { runner := NewFilterRunner(publisher.Publisher.Queue, filters_plugins) go func() { err := runner.Run() if err != nil { logp.Critical("Filters runner failed: %v", err) // shutting doen sniff.Stop() } }() afterInputsQueue = runner.FiltersQueue } else { // short-circuit the runner afterInputsQueue = publisher.Publisher.Queue } logp.Debug("main", "Initializing sniffer") err = sniff.Init(false, afterInputsQueue) if err != nil { logp.Critical("Initializing sniffer failed: %v", err) os.Exit(1) } // This needs to be after the sniffer Init but before the sniffer Run. if err = droppriv.DropPrivileges(config.ConfigSingleton.RunOptions); err != nil { logp.Critical(err.Error()) os.Exit(1) } // Up to here was the initialization, now about running if *testConfig { // all good, exit with 0 os.Exit(0) } if *cpuprofile != "" { f, err := os.Create(*cpuprofile) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } // run the sniffer in background go func() { err := sniff.Run() if err != nil { logp.Critical("Sniffer main loop failed: %v", err) os.Exit(1) } over <- true }() // On ^C or SIGTERM, gracefully stop the sniffer sigc := make(chan os.Signal, 1) signal.Notify(sigc, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigc logp.Debug("signal", "Received sigterm/sigint, stopping") sniff.Stop() }() if !*toStderr { logp.Info("Startup successful, sending output only to syslog from now on") logp.SetToStderr(false) } logp.Debug("main", "Waiting for the sniffer to finish") // Wait for the goroutines to finish for _ = range over { if !sniff.IsAlive() { break } } logp.Debug("main", "Cleanup") if *memprofile != "" { // wait for all TCP streams to expire time.Sleep(tcp.TCP_STREAM_EXPIRY * 1.2) tcp.PrintTcpMap() runtime.GC() writeHeapProfile(*memprofile) debugMemStats() } }
func (p *Pingbeat) Run(b *beat.Beat) error { fp := fastping.NewPinger() // Set the MaxRTT, i.e., the interval between pinging a target fp.MaxRTT = p.period errInput, err := fp.Network(p.pingType) results := make(map[string]*response) if err != nil { logp.Critical("Error: %v (input %v)", err, errInput) os.Exit(1) } if p.useIPv4 { for addr, details := range p.ipv4targets { logp.Debug("pingbeat", "Adding target IP: %s, Name: %s, Tag: %s\n", addr, details[0], details[1]) fp.AddIP(addr) results[addr] = nil } } if p.useIPv6 { for addr, details := range p.ipv6targets { logp.Debug("pingbeat", "Adding target IP: %s, Name: %s, Tag: %s\n", addr, details[0], details[1]) fp.AddIP(addr) results[addr] = nil } } onRecv, onIdle := make(chan *response), make(chan bool) fp.OnRecv = func(addr *net.IPAddr, t time.Duration) { // Find the name and tag associated with this address name, tag := p.Addr2Name(addr) // Send the name, addr, rtt and tag as a struct through the onRecv channel onRecv <- &response{name: name, addr: addr, rtt: t, tag: tag} } fp.OnIdle = func() { onIdle <- true } fp.RunLoop() for { select { case <-p.done: logp.Debug("pingbeat", "Got interrupted, shutting down\n") fp.Stop() return nil case res := <-onRecv: results[res.addr.String()] = res case <-onIdle: for target, r := range results { if r == nil { var name, tag string if _, found := p.ipv4targets[target]; found { name = p.ipv4targets[target][0] tag = p.ipv4targets[target][1] } else if _, found := p.ipv6targets[target]; found { name = p.ipv6targets[target][0] tag = p.ipv6targets[target][1] } else { logp.Warn("Error: Unexpected target returned: %s", target) break } // Packet loss event := common.MapStr{ "@timestamp": common.Time(time.Now()), "type": "pingbeat", "target_name": name, "target_addr": target, "tag": tag, "loss": true, } p.events.PublishEvent(event) } else { // Success, ping received event := common.MapStr{ "@timestamp": common.Time(time.Now()), "type": "pingbeat", "target_name": r.name, "target_addr": target, "tag": r.tag, "rtt": milliSeconds(r.rtt), } p.events.PublishEvent(event) } results[target] = nil } case <-fp.Done(): if err = fp.Err(); err != nil { logp.Critical("Error: %Ping failed v", err) } break } } fp.Stop() return nil }
func main() { // Use our own FlagSet, because some libraries pollute the global one var cmdLine = flag.NewFlagSet(os.Args[0], flag.ExitOnError) cfgfile.CmdLineFlags(cmdLine, Name) logp.CmdLineFlags(cmdLine) service.CmdLineFlags(cmdLine) publisher.CmdLineFlags(cmdLine) file := cmdLine.String("I", "", "file") loop := cmdLine.Int("l", 1, "Loop file. 0 - loop forever") oneAtAtime := cmdLine.Bool("O", false, "Read packets one at a time (press Enter)") topSpeed := cmdLine.Bool("t", false, "Read packets as fast as possible, without sleeping") printVersion := cmdLine.Bool("version", false, "Print version and exit") dumpfile := cmdLine.String("dump", "", "Write all captured packets to this libpcap file.") cmdLine.Parse(os.Args[1:]) sniff := new(sniffer.SnifferSetup) if *printVersion { fmt.Printf("Packetbeat version %s (%s)\n", Version, runtime.GOARCH) return } err := cfgfile.Read(&config.ConfigSingleton) logp.Init(Name, &config.ConfigSingleton.Logging) // CLI flags over-riding config if *topSpeed { config.ConfigSingleton.Interfaces.TopSpeed = true } if len(*file) > 0 { config.ConfigSingleton.Interfaces.File = *file } config.ConfigSingleton.Interfaces.Loop = *loop config.ConfigSingleton.Interfaces.OneAtATime = *oneAtAtime if len(*dumpfile) > 0 { config.ConfigSingleton.Interfaces.Dumpfile = *dumpfile } logp.Debug("main", "Initializing output plugins") if err = publisher.Publisher.Init(config.ConfigSingleton.Output, config.ConfigSingleton.Shipper); err != nil { logp.Critical(err.Error()) os.Exit(1) } if err = procs.ProcWatcher.Init(config.ConfigSingleton.Procs); err != nil { logp.Critical(err.Error()) os.Exit(1) } logp.Debug("main", "Initializing protocol plugins") for proto, plugin := range EnabledProtocolPlugins { err = plugin.Init(false, publisher.Publisher.Queue) if err != nil { logp.Critical("Initializing plugin %s failed: %v", proto, err) os.Exit(1) } protos.Protos.Register(proto, plugin) } tcpProc, err := tcp.NewTcp(&protos.Protos) if err != nil { logp.Critical(err.Error()) os.Exit(1) } udpProc, err := udp.NewUdp(&protos.Protos) if err != nil { logp.Critical(err.Error()) os.Exit(1) } over := make(chan bool) stopCb := func() { sniff.Stop() } logp.Debug("main", "Initializing filters") afterInputsQueue, err := filters.FiltersRun( config.ConfigSingleton.Filter, EnabledFilterPlugins, publisher.Publisher.Queue, stopCb) if err != nil { logp.Critical("%v", err) os.Exit(1) } logp.Debug("main", "Initializing sniffer") err = sniff.Init(false, afterInputsQueue, tcpProc, udpProc) if err != nil { logp.Critical("Initializing sniffer failed: %v", err) os.Exit(1) } // This needs to be after the sniffer Init but before the sniffer Run. if err = droppriv.DropPrivileges(config.ConfigSingleton.RunOptions); err != nil { logp.Critical(err.Error()) os.Exit(1) } // Up to here was the initialization, now about running if cfgfile.IsTestConfig() { // all good, exit with 0 os.Exit(0) } service.BeforeRun() // run the sniffer in background go func() { err := sniff.Run() if err != nil { logp.Critical("Sniffer main loop failed: %v", err) os.Exit(1) } over <- true }() service.HandleSignals(stopCb) // Startup successful, disable stderr logging if requested by // cmdline flag logp.SetStderr() logp.Debug("main", "Waiting for the sniffer to finish") // Wait for the goroutines to finish for _ = range over { if !sniff.IsAlive() { break } } logp.Debug("main", "Cleanup") if service.WithMemProfile() { // wait for all TCP streams to expire time.Sleep(tcp.TCP_STREAM_EXPIRY * 1.2) tcpProc.PrintTcpMap() } service.Cleanup() }
// LoadTLSConfig will load a certificate from config with all TLS based keys // defined. If Certificate and CertificateKey are configured, client authentication // will be configured. If no CAs are configured, the host CA will be used by go // built-in TLS support. func LoadTLSConfig(config *TLSConfig) (*tls.Config, error) { if config == nil || config.Disabled { return nil, nil } certificate := config.Certificate key := config.CertificateKey rootCAs := config.CAs hasCertificate := certificate != "" hasKey := key != "" var certs []tls.Certificate switch { case hasCertificate && !hasKey: return nil, ErrCertificateNoKey case !hasCertificate && hasKey: return nil, ErrKeyNoCertificate case hasCertificate && hasKey: cert, err := tls.LoadX509KeyPair(certificate, key) if err != nil { logp.Critical("Failed loading client certificate", err) return nil, err } certs = []tls.Certificate{cert} } var roots *x509.CertPool if len(rootCAs) > 0 { roots = x509.NewCertPool() for _, caFile := range rootCAs { pemData, err := ioutil.ReadFile(caFile) if err != nil { logp.Critical("Failed reading CA certificate: %s", err) return nil, err } if ok := roots.AppendCertsFromPEM(pemData); !ok { return nil, ErrNotACertificate } } } insecureSkipVerify := false if config.TLSInsecure != nil { insecureSkipVerify = *config.TLSInsecure } minVersion, err := parseTLSVersion(config.MinVersion) if err != nil { return nil, err } maxVersion, err := parseTLSVersion(config.MaxVersion) if err != nil { return nil, err } cipherSuites, err := parseTLSCipherSuites(config.CipherSuites) if err != nil { return nil, err } curveIDs, err := parseCurveTypes(config.CurveTypes) if err != nil { return nil, err } tlsConfig := tls.Config{ MinVersion: minVersion, MaxVersion: maxVersion, Certificates: certs, RootCAs: roots, InsecureSkipVerify: insecureSkipVerify, CipherSuites: cipherSuites, CurvePreferences: curveIDs, } return &tlsConfig, nil }
// Setup packetbeat func (pb *Packetbeat) Setup(b *beat.Beat) error { if err := procs.ProcWatcher.Init(pb.PbConfig.Procs); err != nil { logp.Critical(err.Error()) os.Exit(1) } pb.Sniff = new(sniffer.SnifferSetup) logp.Debug("main", "Initializing protocol plugins") for proto, plugin := range EnabledProtocolPlugins { err := plugin.Init(false, b.Events) if err != nil { logp.Critical("Initializing plugin %s failed: %v", proto, err) os.Exit(1) } protos.Protos.Register(proto, plugin) } var err error tcpProc, err := tcp.NewTcp(&protos.Protos) if err != nil { logp.Critical(err.Error()) os.Exit(1) } udpProc, err := udp.NewUdp(&protos.Protos) if err != nil { logp.Critical(err.Error()) os.Exit(1) } pb.over = make(chan bool) /* logp.Debug("main", "Initializing filters") _, err = filters.FiltersRun( config.ConfigSingleton.Filter, EnabledFilterPlugins, b.Events, b.Stop) if err != nil { logp.Critical("%v", err) os.Exit(1) } */ logp.Debug("main", "Initializing sniffer") err = pb.Sniff.Init(false, tcpProc, udpProc) if err != nil { logp.Critical("Initializing sniffer failed: %v", err) os.Exit(1) } // This needs to be after the sniffer Init but before the sniffer Run. if err = droppriv.DropPrivileges(config.ConfigSingleton.RunOptions); err != nil { logp.Critical(err.Error()) os.Exit(1) } return err }