Coder Social home page Coder Social logo

connbeat's Introduction

Connbeat

Join the chat at https://gitter.im/connbeat/Lobby

Build Status

Connbeat, short for 'Connectionbeat', is an open source agent that monitors TCP connection metadata and ships the data to Kafka or Elasticsearch, or an HTTP endpoint.

The main distinction from Packetbeat is that Connbeat is intended to be able to monitor all connections on a machine (rather than just selected protocols), and does not inspect the package/connection contents, only metadata.

Credits

Development of connbeat was funded by StackState. Collecting connection data is only part of the puzzle: StackState combines it with information from many other sources, presenting it in a way that provides actionable insights.

StackState logo

Building

On linux and mac osx

Connbeat is built with 'make'. You need at least golang 1.7.3.

# Make sure $GOPATH is set
go get github.com/raboof/connbeat
cd $GOPATH/src/github.com/raboof/connbeat
make

It is possible to build connbeat on OSX. However, no integrations are implemented at this point. It is possible to run the unit tests.

Building for linux on OSX

To build a linux binary on OSX you can use docker:

docker run --rm -v "$PWD":/go/src/github.com/raboof/connbeat -w /go/src/github.com/raboof/connbeat golang:1.7.4 make

This will produce a dynamically linked connbeat executable in the current directory.

To create linux packages, use make package

Running

Edit the configuration (connbeat.yml) to specify where you want your events to go (e.g. Kafka, Elasticsearch, the console).

You need to be root if you want to see the process for processes other than your own:

sudo ./connbeat

You can view the events on kafka with something like kafkacat:

kafkacat -C -b localhost -t connbeat

Docker

You can use connbeat to monitor TCP connections from docker instances - see here for details.

Performance overhead

We tested the overhead of running the connbeat agent using the TechEmpower web framework benchmarks.

After deploying to AWS, we ran the query benchmark workload against the Spring Boot framework.

The result was encouraging: the total requests throughput took a hit of only 0.47% (58 fewer requests on a total of 12312). The average latency was in fact a little better in the test runs with connbeat - which must of course be caused by noise, but inspires confidence that connbeat introduce no noticable degredation.

The complete test results can be found in the /tests/performance folder of this repo.

Of course performance impact may vary due to all kinds of circumstances and differences in workload. We're aware of several potential further optimizations, which can be applied when a situation comes up where connbeat does have a noticable impact. If you encounter such a situation, be sure to file an issue.

Events

For connections where the agent is the server:

{
  "@timestamp": "2016-05-20T14:54:29.442Z",
  "beat": {
    "hostname": "yinka",
    "name": "yinka",
    "local_ips": [
      "192.168.2.243"
    ]
  },
  "local_port": 80,
  "local_process": {
    "binary": "dnsmasq",
    "cmdline": ""/usr/sbin/dnsmasq -x /var/run/dnsmasq/dnsmasq.pid -u dnsmasq -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new --local-service",
    "environ": [
    "LANGUAGE=en_US:en",
    "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin",
    "LANG=en_US.UTF-8",
    "_SYSTEMCTL_SKIP_REDIRECT=true",
    "PWD=/",

    ]
  },
  "type": "connbeat"
}

For connections where the agent appears to be the client:

{
  "@timestamp": "2016-05-20T14:54:29.506Z",
  "beat": {
    "hostname": "yinka",
    "name": "yinka",
    "local_ips": [
      "192.168.2.243"
    ]
  },
  "local_ip": "192.168.2.243",
  "local_port": 40074,
  "local_process": {
    "binary": "chromium",
    "cmdline": "/usr/lib/chromium/chromium --show-component-extension-options --ignore-gpu-blacklist --ppapi-flash-path=/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so --ppapi-flash-version=20.0.0.228",
    "environ": [
      ""
    ]
  },
  "remote_ip": "52.91.150.74",
  "remote_port": 443,
  "type": "connbeat"
}

Testing

To run the regular go unit test, run 'make unit'.

To also run docker-based system tests, run 'make testsuite'

Packaging

Preliminary packaging is available, but the resulting packages are not yet intended for general consumption.

'make package' should be sufficient to produce a deb, rpm and a binary .tar.gz

Elastic Beat Upgrade

Currently elastic\beats package is set to 5.6.9 and there is a manual change in the vendor/github/com/elastic/beats/libbeat/script/Makefile for parameter TESTIFY_TOOL_REPO. The value is set from github.com/elastic/beats/vendor/github.com/stretchr/testify to github.com/elastic/beats/vendor/github.com/stretchr/testify/assert because it tries to download master and the repo doesn't contain the actual code. and also this paramter can't be overriden in this version 5.6.9. So please check this parameter if it can be overriden or not and then change that in your Makefile when you update the elastic/beats library. Mostly in the latest library you don't need to change this parameter becuase it is fixed.

Contributing

Contributions are welcome! Feel free to submit issues to discuss problems and propose solutions, or send a pull request.

Pull requests are expected to include tests (which are run on Travis). We strive to merge any reasonable features, though features that might increase the load on the machine will likely have to be behind a feature switch that is off by default.

Security

We take great care to ensure connbeat is secure. If despite our efforts you have found what looks like a vulnerability, please contact us privately at [email protected]. For extra safety the email may be encrypted with the public key which can be found at https://keybase.io/raboof

connbeat's People

Contributors

adrianlzt avatar craffit avatar gitter-badger avatar glidebot avatar konstantintatarnikov avatar ktatarnikov avatar raboof avatar rb3ckers avatar toke avatar vishalxebia avatar vk7282 avatar whazenberg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

connbeat's Issues

Feature Request: Make fields of type sequence non-nullable.

It can happen for list fields now to be null, that requires some extra handling on our side. It would be nice if they can never be null, and report an empty sequence when there is no data. E.g. the beat.local_ips field can report null sometimes. Would be nice to do this for beats.local_ips as well as container.docker_host.ips and docker.local_ips.

Support for detecting connections to ports published to the host of a docker container

If a docker container publishes its port to the host machine, with the -p flag, or running in host network mode, a connection to that container cannot be discovered, because the host ip-address and the published port are used to connect to.

E.g. consider a docker container c1 listening on 172.17.0.1:10 on machine m1, that has published port 10 to its host on 192.168.2.38:80. Another docker container than can connect to 192.168.2.38:80, which gets forwarded to 172.17.0.1:10, but 192.168.2.38:10 is not registered with c1.

Pretty console output

This seems to have been removed in a libbeat update - either describe how this should now work or remove it from the examples

No empty docker host ip

When the docker host IP is not found, output an empty list instead of a list containing ""

Monitor both docker images and regular containers at the same time

Currently you have to choose between monitoring docker containers or monitoring local processes.

It'd be useful to create a way to do both simultaneously. This also means for options that currently conflict with monitoring docker containers (expose process, expose environment, etc) should just be disabled (perhaps with a warning) instead of leading to an error.

Remote IP of incoming connections?

Hi,

we want to use connbeat to monitor the connections of a server. What I do not get so far: Do you report the remote IP of incoming connections? This would be particularly useful for us.

thanks a lot

Matt

Connbeat assumes port 80 in the HTTP output URL if no port is specified

How to reproduce

  • configure Connbeat with an HTTPS URL without a port number (eg {{https://host/stsAgent/}})
  • start the agent
  • check the connbeat log for errors

What was the result

The log file contains the following:

{{2017-10-17T08:53:02Z WARN Fail to insert a single event: Post https://host:80/stsAgent/connbeat?api_key=xxx: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)}}

Notice port 80 is inserted into the URL.

What expected

Connbeat uses the URL as-is.

Workaround

If you change the URL to include an explicit port (eg {{https://host:443/stsAgent/}}) connbeat does not change the port number.

Connectionbeat does not report some connections

A reproducible case can be found in the following docker container image: 508573134510.dkr.ecr.eu-west-1.amazonaws.com/bug-reports:connbeat_bug.

Steps to reproduce:

docker run -it bug-reports:connbeat_bug bash
./start_services.sh
lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 7343 root 28u IPv6 59782685 0t0 TCP localhost:36124->localhost:8888 (ESTABLISHED)
java 7369 root 30u IPv6 59782687 0t0 TCP localhost:36128->localhost:8888 (ESTABLISHED)
java 7458 root 27u IPv6 59780886 0t0 TCP *:8888 (LISTEN)
java 7458 root 28u IPv6 59783431 0t0 TCP localhost:8888->localhost:36124 (ESTABLISHED)
java 7458 root 31u IPv6 59784340 0t0 TCP localhost:8888->localhost:36128 (ESTABLISHED)
tail -f /var/log/stackstate/connbeat.out | grep 36128

OBSERVED:
No connections are observed for one of the two processes. We have observed instances where a connection is reported, but only in one direction.

EXPECTED:
Connections in both directions should be reported by connbeat, for both processes.

Reporting of env variables of docker containers

We would like connectionbeat to report the env variables passed into a docker container. This is available when using docker inspect. It might be nice to be able to filter on specific env variables upfront.

Make DOCKERHOST_IP and DOCKERHOST_HOSTNAME a configuration option

Currently DOCKERHOST_IP and DOCKERHOST_NAME are not configuration options. This not work well when turning connectionbeat into a linux service, because linux services have their environment cleared. The configuration file would be a more logical place for these settings.

Describe resource usage plans in more detail

Our performance impact measurements look good, but it'd be useful to write down which options and plans we have when it turns out performance is an issue.

Out of the top of my head:

  • nice and rtprio
  • GOMAXPROCS
  • slower polling intervals
  • 'statistically smart' checking of /proc
  • connection filtering
  • further profiling

Feature request: Change datastructure of ports of docker container

The datastructure of the ports variable which connbeat reports for a docker container is now a Sequence of Maps, it would be nice if it was just a map.

The structure now is e.g. the following:

"ports": [
      {
        "80": [
          {
            "HostIp": "0.0.0.0",
            "HostPort": "10000"
          }
        ]
      },
      {
        "8125": [
          {
            "HostIp": "0.0.0.0",
            "HostPort": "10002"
          }
        ]
      }, ....

It would be nice to change it to just one map like this:

"ports": { 
        "80": [
          {
            "HostIp": "0.0.0.0",
            "HostPort": "10000"
          }
        ],
      "8125": [
          {
            "HostIp": "0.0.0.0",
            "HostPort": "10002"
          }
        ]
      }, 

Benchmarking

It would be nice if we could perform some kind of reproducable system benchmark against a Linux server, and compare performance with and without running connbeat. I haven't found a good benchmark setup for this yet, though.

The suites at http://openbenchmarking.org/tests/pts seem to be geared towards benchmarking on the local machine, and not taking into account heavy networking workloads, which are the most interesting ones for connbeat.

Connbeat triggers docker memory leak on docker containers without 'cat' executable

Introduction:
The docker daemon suffers from a memory leak, as described here:

https://forums.docker.com/t/docker-engine-leaks-memory-when-doing-a-docker-exec-on-a-non-existing-command/33820

Unfortunately, connbeat triggers this leak a lot when enabled on a kubernetes cluster on coreos, making machines going OOM in 30 minutes.

The cause is that connbeat tries to run the 'cat' executable on /pause containers from kubernetes, which don't have that executable. Connbeat handles this well, but as you can see in the above bug report, dockerd will leak.

Reproduce:

Run a linux dockerd version as specified in the docker bugticket (https://coreos.com/os/docs/latest/booting-on-virtualbox.html for example)
docker run -d gcr.io/google_containers/pause-amd64:3.0 /pause
Start connbeat with docker enabled

Observe:
Machine going OOM

Expected:
Not going OOM

Although this is a docker issue, this issue is hitting older and 'stable' versions of docker, so I think we should work around this from connbeat.

Connection filtering

To reduce noise, we might want to add filtering in connbeat: both excluding known-uninteresting nodes and restricting ourselves to known-interesting subnets.

It might be nice to use an existing library for the filtering expressions.

Importing into 6.6.2 ElasticSearch

I'll admit I am new to ElasticSearch... and I'm willing to remove/close the issue by stating I'm wrong...

I am trying to setup connbeat on ElasticSearch 6.6.2... I am using docker-elk, and getting to know the framework(s). I am trying to use connbeat for per connection status rather than metricbeat, or packetbeat's alternatives. I am not familiar however with dashboard schema, etc. I tried import---dashboards but am getting to this error message:

Initialize the Elasticsearch 6.6.2 loader
Elasticsearch URL http://127.0.0.1:9200
For Elasticsearch version >= 6.0.0, the Kibana dashboards need to be imported via the Kibana API.

It sort of feels like learning MySQL again, and I understand that the software cannot handle all known/future cases but I figured I'd open up a ticket to show that in comparison to packetbeat, and metricbeat that it is an issue to get going...

Connection beat inside docker container crashes sometimes when other container stops

When stopping another docker container, which is being reported by connection beat, it sometimes crashes with the following error:
(It happens to me quite often when stopping a container running graphite e.g. and not a container running elasticsearch. So if you need help reproducing the issue you can ask me)

panic: API error (500): {"message":"Container 0ac8fd95f9a9743d398a8054ea7b565dd5a00b18a1805322434b4bd85e03964b is not running"}

goroutine 34 [running]:
panic(0x906e40, 0xc420254200)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
github.com/raboof/connbeat/sockets/docker.(*Poller).pollCurrentConnectionsFor(0xc420310000, 0xc4201548c0, 0x40, 0xc4203ad900, 0x17, 0xc4203cb120, 0xd, 0x57ff5a7c, 0xc4203cb1a0, 0x7, ...)
/go/src/github.com/raboof/connbeat/sockets/docker/docker.go:62 +0x599
github.com/raboof/connbeat/sockets/docker.(*Poller).pollCurrentConnections(0xc420310000, 0xc4201548c0, 0x40, 0xc4203ad900, 0x17, 0xc4203cb120, 0xd, 0x57ff5a7c, 0xc4203cb1a0, 0x7, ...)
/go/src/github.com/raboof/connbeat/sockets/docker/docker.go:44 +0x9e
github.com/raboof/connbeat/sockets/docker.(*Poller).PollCurrentConnections(0xc420310000, 0xc420159da0, 0x0, 0x0)
/go/src/github.com/raboof/connbeat/sockets/docker/docker.go:36 +0x135
github.com/raboof/connbeat/beater.getSocketInfoFromDocker(0xc420310000, 0x77359400, 0xc420159da0)
/go/src/github.com/raboof/connbeat/beater/connections.go:34 +0x41
created by github.com/raboof/connbeat/beater.Listen
/go/src/github.com/raboof/connbeat/beater/connections.go:137 +0x9e

Process and container information are mixed up

Process and container information are mixed up like in the json below, we have Nginx and Java app with mixed information.

Expected that container and java information are not mixed

{
	"@timestamp": "2017-01-24T10:25:05.592Z",
	"beat": {
		"hostname": "a1.dcos",
		"local_ips": ["192.168.65.111", "198.51.100.3", "198.51.100.2", "198.51.100.1", "10.0.2.15"],
		"name": "a1.dcos",
		"version": "5.2.0"
	},
	"container": {
		"docker_host": {
			"hostname": "a1.dcos",
			"ips": ["192.168.65.111"]
		},
		"env": ["MESOS_TASK_ID=nginx.bc6c1b8d-e219-11e6-9e69-70b3d5800001", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
		"id": "8ed4e482b3160a33944458eaf05e82795ecce94e0378020110f89b189c08d036",
		"image": "nginx",
		"local_ips": null,
		"name": "/mesos-d8370c69-23b0-4cc4-bc7d-772e688749b5-S3.7f44f0ba-eb58-4ea9-b229-099b23728f04",
		"ports": {
			"443": [],
			"80": [{
				"HostIp": "0.0.0.0",
				"HostPort": "19758"
			}]
		}
	},
	"local_ip": "192.168.65.111",
	"local_port": 54166,
	"local_process": {
		"binary": "",
		"cmdline": "/opt/mesosphere/bin/java -cp /tmp/SimpleHttpApp.jar com.stackstate.SimpleHttpServer",
		"environ": ["LIBPROCESS_IP=192.168.65.111", "MESOS_AGENT_ENDPOINT=192.168.65.111:5051", "SHELL=/usr/bin/bash", "HOST=192.168.65.111", "PORT0=22233", "MESOS_DIRECTORY=/var/lib/mesos/slave/slaves/d8370c69-23b0-4cc4-bc7d-772e688749b5-S3/frameworks/d8370c69-23b0-4cc4-bc7d-772e688749b5-0001/executors/javaapp3.01f50600-e21e-11e6-9e69-70b3d5800001/runs/bb4c7515-c747-408a-bc0e-15fcf24434a8", "PORT_10001=22233", "MESOS_TASK_ID=javaapp3.01f50600-e21e-11e6-9e69-70b3d5800001", "LIBPROCESS_NUM_WORKER_THREADS=8", "LD_LIBRARY_PATH=/opt/mesosphere/lib", "MESOS_EXECUTOR_ID=javaapp3.01f50600-e21e-11e6-9e69-70b3d5800001", "PATH=/usr/bin:/bin", "PWD=/var/lib/mesos/slave/slaves/d8370c69-23b0-4cc4-bc7d-772e688749b5-S3/frameworks/d8370c69-23b0-4cc4-bc7d-772e688749b5-0001/executors/javaapp3.01f50600-e21e-11e6-9e69-70b3d5800001/runs/bb4c7515-c747-408a-bc0e-15fcf24434a8", "MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=5secs", "MESOS_NATIVE_JAVA_LIBRARY=/opt/mesosphere/packages/mesos--253f5cb0a96e2e3574293ddfecf5c63358527377/lib/libmesos-1.0.1.so", "MESOS_NATIVE_LIBRARY=/opt/mesosphere/packages/mesos--253f5cb0a96e2e3574293ddfecf5c63358527377/lib/libmesos-1.0.1.so", "MARATHON_APP_RESOURCE_DISK=0.0", "SASL_PATH=/opt/mesosphere/lib/sasl2", "MARATHON_APP_RESOURCE_MEM=128.0", "PORTS=22233", "MESOS_HTTP_COMMAND_EXECUTOR=0", "MESOS_SLAVE_PID=slave(1)@192.168.65.111:5051", "MARATHON_APP_RESOURCE_GPUS=0", "MESOS_FRAMEWORK_ID=d8370c69-23b0-4cc4-bc7d-772e688749b5-0001", "MESOS_CHECKPOINT=1", "MARATHON_APP_LABELS=", "SHLVL=1", "MARATHON_APP_ID=/javaapp3", "LIBPROCESS_PORT=0", "MARATHON_APP_VERSION=2017-01-24T10:15:19.086Z", "MESOS_SLAVE_ID=d8370c69-23b0-4cc4-bc7d-772e688749b5-S3", "PORT=22233", "MESOS_SUBSCRIPTION_BACKOFF_MAX=2secs", "MESOS_RECOVERY_TIMEOUT=15mins", "MARATHON_APP_RESOURCE_CPUS=1.0", "MESOS_SANDBOX=/var/lib/mesos/slave/slaves/d8370c69-23b0-4cc4-bc7d-772e688749b5-S3/frameworks/d8370c69-23b0-4cc4-bc7d-772e688749b5-0001/executors/javaapp3.01f50600-e21e-11e6-9e69-70b3d5800001/runs/bb4c7515-c747-408a-bc0e-15fcf24434a8", "_=/opt/mesosphere/bin/java"]
	},
	"remote_ip": "192.168.65.90",
	"remote_port": 2181,
	"type": "connbeat"
}

tcp_diag leaks file handles

pollCurrentConnectionsForFamily creates a socket via netlink.NewNetlinkSocket
this socket is never closed and leaks. After some time the process runs out of file handles.

How to reproduce:

Use: enable_tcp_diag: true
Run connbeat and watch connbeat filehandles list grow:

sudo watch 'ls -sla /proc/$(pgrep connbeat)/fd'

Report local IP even when bound to 0.0.0.0

Especially when running in Docker, we might not always/immediately see the docker container IP when the service is bound to 0.0.0.0. Let's see if we can make that smarter.

Report correct hostname for docker containers.

Currently all docker containers discovered by connection beat report the hostname and local_ips of the docker container that connection beat is running in. In order to discover connections between docker containers this should be the local_ips of the docker container itself.

The hostname that is reported is currently the hostname of the docker container, but perhaps this should be the hostname of the host that runs docker.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.