Пример #1
0
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)
	}
}
Пример #2
0
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
}
Пример #3
0
// 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
}
Пример #4
0
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
}
Пример #5
0
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()

}
Пример #6
0
// 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)
}
Пример #7
0
// 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)
}
Пример #8
0
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
}
Пример #9
0
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
}
Пример #10
0
// 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)
	}
}
Пример #11
0
// 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)
	}
}
Пример #12
0
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))
}
Пример #13
0
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
}
Пример #14
0
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()
}
Пример #15
0
// 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
}
Пример #16
0
// 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)
}
Пример #17
0
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()

}
Пример #18
0
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
}
Пример #19
0
// 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()
}
Пример #20
0
// 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
}
Пример #21
0
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()
}
Пример #22
0
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()
	}
}
Пример #23
0
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
}
Пример #24
0
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()
}
Пример #25
0
// 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
}
Пример #26
0
// 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
}