• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Remote monitoring and metrics visualization
2
3AFL++ can send out metrics as StatsD messages. For remote monitoring and
4visualization of the metrics, you can set up a tool chain. For example, with
5Prometheus and Grafana. All tools are free and open source.
6
7This enables you to create nice and readable dashboards containing all the
8information you need on your fuzzer instances. There is no need to write your
9own statistics parsing system, deploy and maintain it to all your instances, and
10sync with your graph rendering system.
11
12Compared to the default integrated UI of AFL++, this can help you to visualize
13trends and the fuzzing state over time. You might be able to see when the
14fuzzing process has reached a state of no progress and visualize what are the
15"best strategies" for your targets (according to your own criteria). You can do
16so without logging into each instance individually.
17
18![example visualization with Grafana](resources/statsd-grafana.png)
19
20This is an example visualization with Grafana. The dashboard can be imported
21with [this JSON template](resources/grafana-afl++.json).
22
23## AFL++ metrics and StatsD
24
25StatsD allows you to receive and aggregate metrics from a wide range of
26applications and retransmit them to a backend of your choice.
27
28From AFL++, StatsD can receive the following metrics:
29- cur_item
30- cycle_done
31- cycles_wo_finds
32- edges_found
33- execs_done
34- execs_per_sec
35- havoc_expansion
36- max_depth
37- corpus_favored
38- corpus_found
39- corpus_imported
40- corpus_count
41- pending_favs
42- pending_total
43- slowest_exec_ms
44- total_crashes
45- saved_crashes
46- saved_hangs
47- var_byte_count
48- corpus_variable
49
50Depending on your StatsD server, you will be able to monitor, trigger alerts, or
51perform actions based on these metrics (for example: alert on slow exec/s for a
52new build, threshold of crashes, time since last crash > X, and so on).
53
54## Setting environment variables in AFL++
55
561. To enable the StatsD metrics collection on your fuzzer instances, set the
57   environment variable `AFL_STATSD=1`. By default, AFL++ will send the metrics
58   over UDP to 127.0.0.1:8125.
59
602. To enable tags for each metric based on their format (banner and
61   afl_version), set the environment variable `AFL_STATSD_TAGS_FLAVOR`. By
62   default, no tags will be added to the metrics.
63
64    The available values are the following:
65    -  `dogstatsd`
66    -  `influxdb`
67    -  `librato`
68    -  `signalfx`
69
70    For more information on environment variables, see
71    [env_variables.md](env_variables.md).
72
73    Note: When using multiple fuzzer instances with StatsD it is *strongly*
74    recommended to set up `AFL_STATSD_TAGS_FLAVOR` to match your StatsD server.
75    This will allow you to see individual fuzzer performance, detect bad ones,
76    and see the progress of each strategy.
77
783. Optional: To set the host and port of your StatsD daemon, set
79   `AFL_STATSD_HOST` and `AFL_STATSD_PORT`. The default values are `localhost`
80   and `8125`.
81
82## Installing and setting up StatsD, Prometheus, and Grafana
83
84The easiest way to install and set up the infrastructure is with Docker and
85Docker Compose.
86
87Depending on your fuzzing setup and infrastructure, you may not want to run
88these applications on your fuzzer instances. This setup may be modified before
89use in a production environment; for example, adding passwords, creating volumes
90for storage, tweaking the metrics gathering to get host metrics (CPU, RAM, and
91so on).
92
93For all your fuzzing instances, only one instance of Prometheus and Grafana is
94required. The
95[statsd exporter](https://registry.hub.docker.com/r/prom/statsd-exporter)
96converts the StatsD metrics to Prometheus. If you are using a provider that
97supports StatsD directly, you can skip this part of the setup."
98
99You can create and move the infrastructure files into a directory of your
100choice. The directory will store all the required configuration files.
101
102To install and set up Prometheus and Grafana:
103
1041. Install Docker and Docker Compose:
105
106    ```sh
107    curl -fsSL https://get.docker.com -o get-docker.sh
108    sh get-docker.sh
109    ```
110
1112. Create a `docker-compose.yml` containing the following:
112
113    ```yml
114    version: '3'
115
116    networks:
117      statsd-net:
118        driver: bridge
119
120    services:
121      prometheus:
122        image: prom/prometheus
123        container_name: prometheus
124        volumes:
125          - ./prometheus.yml:/prometheus.yml
126        command:
127          - '--config.file=/prometheus.yml'
128        restart: unless-stopped
129        ports:
130          - "9090:9090"
131        networks:
132          - statsd-net
133
134      statsd_exporter:
135        image: prom/statsd-exporter
136        container_name: statsd_exporter
137        volumes:
138          - ./statsd_mapping.yml:/statsd_mapping.yml
139        command:
140          - "--statsd.mapping-config=/statsd_mapping.yml"
141        ports:
142          - "9102:9102/tcp"
143          - "8125:9125/udp"
144        networks:
145          - statsd-net
146
147      grafana:
148        image: grafana/grafana
149        container_name: grafana
150        restart: unless-stopped
151        ports:
152            - "3000:3000"
153        networks:
154          - statsd-net
155    ```
156
1573. Create a `prometheus.yml` containing the following:
158
159    ```yml
160    global:
161      scrape_interval:      15s
162      evaluation_interval:  15s
163
164    scrape_configs:
165      - job_name: 'fuzzing_metrics'
166        static_configs:
167          - targets: ['statsd_exporter:9102']
168    ```
169
1704. Create a `statsd_mapping.yml` containing the following:
171
172    ```yml
173    mappings:
174    - match: "fuzzing.*"
175      name: "fuzzing"
176      labels:
177          type: "$1"
178    ```
179
1805. Run `docker-compose up -d`.
181
182## Running AFL++ with StatsD
183
184To run your fuzzing instances:
185
186```
187AFL_STATSD_TAGS_FLAVOR=dogstatsd AFL_STATSD=1 afl-fuzz -M test-fuzzer-1 -i i -o o [./bin/my-application] @@
188AFL_STATSD_TAGS_FLAVOR=dogstatsd AFL_STATSD=1 afl-fuzz -S test-fuzzer-2 -i i -o o [./bin/my-application] @@
189...
190```