Cloud-Based Applications and Protocols
In the previous article, we established that security in cloud-based applications is important and searching for vulnerabilities in cloud applications is not somewhat harder or different than it is in web based applications. In this article we’ll take a somewhat different approach and take a look at protocols the cloud-based applications use under the hood and will apply the deep packet inspection techniques to look for malicious traffic.Every cloud-based application is running on top of a protocol that allows the clients to communicate with the server in a standardized way; otherwise, the client applications wouldn’t be able to communicate with the server at all. If we have a room full of people and everybody speaks a different language, they won’t be able to communicate. In order to reach a common goal, they would have to agree on a way to interact among themselves, thus forming a standard for communication that everybody would understand.
There are many protocols that we use in our daily lives when communicating with cloud-based applications, perhaps without even realizing it. The most commonly used protocols are the following:
- HTTP
- HTTPS
- DNS
- SMTP
- Custom Protocols
In order to analyze traffic coming to and going from Docker applications, we have to look at Packetbeat, which ships the traffic to Elasticsearch, which further enables the analysis and visualization of real-time traffic in Kibana.
Introduction to Packetbeat
We’ll assume that we already have Docker installed and ready to use, since it’s fairly easy to do so. You can check whether Docker is installed by issuing the following command:# docker –version
Docker version 1.7.1, build df2f73d-dirty
After ensuring the Docker is installed, we can install Packetbeat, which requires only libpcap, a system-independent library for network traffic capture, enabling us to capture packets as they arrive on a network interface.
We can install Packetbeat fairly easily by pulling the Docker image from the official Docker Hub.
# docker pull proteansec/packetbeat
Then we have to create the packetbeat.yml configuration file, which must include the following categories, each containing specific information to configure Packetbeat:
- Interfaces: This specifies the interface on which we would like to capture the traffic. We can use any to specify that we would like to capture traffic on all connected interfaces.
- Protocols: We can monitor only a limited number of
protocols for now, including DNS, HTTP, Memcache, Mysql, Postgresql,
Redis, Thrift, and MongoDB. For each protocol, we must specify on which
port the application using it is running.
- Output: specifies where the analyzed traffic information will be stored, which currently supports Elasticsearch, LogStash and in a File. In most cases, we want to use the Elasticsearch output because it allows us to easily search through the analyzed data as well as present it in a nice-looking graph with Kibana.
interfaces:
device: docker0
protocols:
dns:
ports: [53]
include_authorities: true
include_additionals: true
http:
ports: [80, 8080, 8000, 5000, 8002]
memcache:
ports: [11211]
mysql:
ports: [3306]
pgsql:
ports: [5432]
redis:
ports: [6379]
thrift:
ports: [9090]
mongodb:
ports: [27017]
output:
elasticsearch:
enabled: true
hosts: [“localhost:9200”]
shipper:
geoip:
paths: [“/usr/local/share/GeoIP/GeoIP.dat.gz”]
Afterwards we can start the container with the following command, which starts the packet container by giving it access to host’s network interfaces, services, etc. Below we’ve started the container, and then we use the docker exec command to obtain command-line access to the running container, after which we verify that the host’s Elasticsearch port 9200
is actually accessible in the container itself.
# docker run -d –net=host proteansec/packetbeat
# docker exec -it $(docker ps -l -q) /bin/bash
root@container:/# sudo -i
root@container:/# netstat -luntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp6 0 0 :::9200 :::* LISTEN –
To manually build the Packetbeat, we can use the following Dockerfile, which provides many configuration parameters that enable us to change how we run Packetbeat inside the container. Therefore, the Packetbeat container can be up and running with the one simple command shown below. Note that the Packetbeat is configured through the use of input parameters we supply when running docker, but additionally GeoIP database is downloaded and Kibana dashboards are automatically downloaded and applied to Kibana, so we can instantly view the graphs and analyze the traffic without much further ado.
# docker run –name packetbeat -d –net=host -d proteansec/packetbeat app:start
Note that Packetbeat container needs access to the host network, so we need to apply the “–net=host” option when running the container, which enables the container to access the interface on the host, thus making it possible to sniff the traffic coming and going to every dockerized application running on the same host.
Topbeat
Besides Packetbeat, there is also Topbeat, which, rather than analyzing the traffic coming and going to dockerized applications, rather collects and presents statistics about the other parts of the environment, mainly the CPU, memory and disk usage.- System load
- Disk usage
- Process status
- Memory usage
- CPU usage
# docker run –name topbeat -d –privileged -d proteansec/topbeat app:start
Note that Topbeat needs to be running in privileged mode, because it need to be able to access system information from a container, which is only possible when the container itself is run with enough privileges.
After the Topbeat container has been run, we can access the Kibana interface, which will contain a new Topbeat index pattern as presented below:
The Docker0 Network Interface
In the previous section, we specified docker0 network interface in the [interfaces] section of the packetbeat.conf configuration file. Note that, at the time of this writing, we can only choose a single interface with each Packetbeat instance, so if we would like to monitor multiple network interfaces at the same time, we have to instantiate new Packetbeat instances, each of which is sniffing network traffic on a single network interface and sending it to Elasticsearch. Note that we can specify any as the network interface, which will sniff the traffic on all interfaces, but that is often not what we want to achieve; also, it is currently not supported on all operating system, so it doesn’t work on OS X for example.Nevertheless, we can specify docker0 network interface, which will allow us to sniff the network traffic from all container veth* network interfaces, which is exactly what we want to achieve. It’s often the case that we want to sniff the network traffic of every running container in order to analyze the traffic going to services running in the containers.
When Docker starts, it creates a virtual interface docker0 and assigns it a private random IP address range, which is often set to 172.17.42/16 if available. Note the netmask is 16-bit, which means there are 65534 available IP addresses that can be assigned to any running containers [1].
The docker0 is a network bridge, which itself contains the other veth* network interfaces of running Docker containers. Because of this, the containers can communicate with the host as well as with each other in order for one service to talk to the other running in a different container. Note that all interfaces belonging to the same bridge are in the same collision domain, so when one interface broadcasts a request, it is sent over the bridge to every other network interface, any of which may respond with a packer response.
- none: The docker container will have its own
unconfigured network stack, which allows us to build our own network
inside the container.
- container:name/id: The docker container will share
the network stack with another container identified with NAME/ID, where
the containers will be able to talk to each other though loopback
interface.
- bridge: This option is the default and connects the container interface to the Docker bridge as already described.
- host: The container will share the network with the Docker host and will have access to all its network interfaces. By using this option, the container will not be able to reconfigure the host’s interfaces, which would require the privilege mode to be given to the container by using “–privileged=true” option.
Monitoring a HTTP application running in Docker
Now that we have Packetbeat up and running, we have to provide a service for Packetbeat to monitor by sniffing traffic from docker0 bridge. In our case we’ll provide a static website, which is a great example for testing the Packetbeat capabilities.Let’s first create the /home/core/website and copy some static website content into that directory. After that, we should run the nginx container mounting the static website content into the Nginx html directory, which can be done with the -v option. Note that we’ve also exposed the container port, so we can access the website running in that container on HTTP port 80.
# docker run -p 80:80 -v /home/core/website:/usr/share/nginx/html:ro -d nginx
Afterward, we should connect to the Nginx container, where our website application is running. We can see that Protean Security website is running in the container as can be seen on the picture below.
# curl -XGET ‘http://localhost:9200/packetbeat-*/_search?pretty‘
By navigating through the website, all the HTTP queries will be gathered by Packetbeat and stored in Elasticsearch.
Viewing Analyzed Data through Kibana Graphs
The exposed RESTful API interface is great, but fails to provide a quick and nice-looking way of presenting what is happening in our network. To solve that, we can use Kibana, where dashboards can be instantiated in order to see the gathered data quickly and instantly tell what is happening on our network.First, we must go to “Settings – Indices,” where new indices will be shown as below.
# curl ‘localhost:9200/_cat/indices?v’
Note that in Discover tab, we can select the index pattern “packetbeat-” in a drop-down list to view the gathered data.
To install the dashboards from the beats-dashboards Github repository, we can simply clone the repository and run the “./load.sh http://localhost:9200” command to load the dashboards (this is already done by the docker images presented in the previous section, so there’s no need to do it again). Then, back in Kibana, we can go to “Dashboard – Load Saved Dashboard” to see newly added dashboards, as shown below.
We also have to verify that Packetbeat can monitor requests coming from another Docker container running on the same physical host. But instead of specifying the external IP address, we’ll rather specify the internal IP address of the container. Basically, we have to run “docker exec -it ID /bin/bash” and execute the ifconfig command in the Docker container running Nginx to discover the internal IP address of that container. Then we have to issue the same command to gain command-line interface to some other container running on the same host and executing the “curl http://172.17.0.11/” command to download the website HTML source code. Note that curl is not capable of parsing the returned website HTML, so no additional requests for images, JavaScript/CSS files will be made, which means only one request will be generated.
If we set the timer in Kibana web interface to the last number of minutes (1 minute is good enough) where no requests have been generated, the counter of requests will again be back to zero. Then we can issue the curl command, which will generate 1 request as shown below.
Conclusion
In this article we’ve seen that we can gather a lot of useful information about packets flowing to and from our Docker container, which can be beneficial to discover any anomalies that can be further analyzed for potential threats.This exercise proved that we can use Packetbeat for our defense, because of its capabilities to sniff traffic from Docker containers. Note that many cloud-based applications are running in Docker containers, so sniffing the packets to analyze them or possibly pipe them to an IDS/IPS proves beneficial to discover malicious traffic and block the attacker as soon as possible.
0 comments:
Post a Comment