bui-monitor¶
The bui-monitor is a Burp client monitor processes pool.
This pool only supports the burp2 backend.
The goal of this pool is to have a consistent amount of burp client processes related to your Burp-UI stack.
Before this pool, you could have 1 process per Burp-UI instance (so if you use gunicorn with several workers, that would multiply the amount of processes), you also had 1 process per celery worker instance (which is one per CPU core available on your machine by default). In the end, it could be difficult to anticipate the resources to provision beforehand. Also, this wasn’t very scalable.
If you choose to use the bui-monitor pool with the appropriate backend (the parallel one), you can now take advantage of some requests parallelisation.
Cherry on the cake, the parallel backend is available within both the local Burp-UI process but also within the bui-agent!
Architecture¶
The architecture is described bellow:
+---------------------+
| |
| celery |
| |
+---------------------+
| +-----------------+ | +----------------------+
| | | | | |
| | worker 1 +----------------+------------------> bui-monitor |
| | | | | | |
| +-----------------+ | | +----------------------+
| +-----------------+ | | | +------------------+ |
| | | | | | | | |
| | worker n +----------------+ | | burp -a m (1) | |
| | | | | | | | |
| +-----------------+ | | | +------------------+ |
+---------------------+ | | +------------------+ |
| | | | |
+---------------------+ | | | burp -a m (2) | |
| | | | | | |
| burp-ui | | | +------------------+ |
| | | | +------------------+ |
+---------------------+ | | | | |
| +-----------------+ | | | | burp -a m (n) | |
| | | | | | | | |
| | worker 1 +----------------+ | +------------------+ |
| | | | | +----------------------+
| +-----------------+ | |
| +-----------------+ | |
| | | | |
| | worker n +----------------+
| | | |
| +-----------------+ |
+---------------------+
Installation¶
There is a dedicated Pypi package: burp-ui-monitor
that you can install
with pip install burp-ui-monitor
if you want the bare minimun that you can
use alongside with the bui-agent.
Alternatively, the bui-monitor command is also part of the full burp-ui
installation.
Presentation¶
The monitor pool is powered by asyncio through trio.
It is part of the Burp-UI package.
You can launch it with the bui-monitor
command.
Configuration¶
There is a specific buimonitor.cfg configuration file with a [Global]
section as below:
# Burp-UI monitor configuration file
[Global]
# On which port is the application listening
port = 11111
# On which address is the application listening
# '::1' is the default for local IPv6
# set it to '127.0.0.1' if you want to listen on local IPv4 address
bind = ::1
# Pool size: number of 'burp -a m' process to load
pool = 2
# enable SSL
ssl = true
# ssl cert
sslcert = /var/lib/burp/ssl/server/ssl_cert-server.pem
# ssl key
sslkey = /var/lib/burp/ssl/server/ssl_cert-server.key
# monitor password
password = password123456
## burp backend specific options
#[Burp]
## burp binary
#burpbin = /usr/sbin/burp
## burp client configuration file used for the restoration
#bconfcli = /etc/burp/burp.conf
## how many time to wait for the monitor to answer (in seconds)
#timeout = 15
Each option is commented, but here is a more detailed documentation:
port: On which port is bui-monitor listening.
bind: On which address is bui-monitor listening.
pool: Number of burp client processes to launch.
ssl: Whether to communicate with the Burp-UI server over SSL or not.
sslcert: What SSL certificate to use when SSL is enabled.
sslkey: What SSL key to use when SSL is enabled.
password: The shared secret between the Burp-UI server and bui-monitor.
As with Burp-UI, you need the [Burp]
section to specify Burp client
options. There are fewer options because we only launch client processes.
Warning
Please note there was a bug in burp versions prior 2.2.12 that is easily triggered by this new asynchronous workload.
Benchmark¶
On my development VM which has 2 vCPUs I noticed the parallel backend which interacts with the bui-monitor was twice faster than the burp2 backend.
The test script was something like:
#!/bin/bash
for client in client1 client2 client3 client4 client6 client6
do
echo "----------------------------$client--------------------------"
(time curl -u user:password burp-ui.server:5000/api/client/stats/$client) &
(time curl -u user:password burp-ui.server:5000/api/client/stats/$client) &
done
The server was launched with gunicorn:
# for the parallel backend
gunicorn -b 0.0.0.0:5000 -w 2 'burpui:create_app(conf="path/to/burpui.cfg")'
# for the burp2 backend
gunicorn -k gevent -b 0.0.0.0:5000 -w 2 'burpui:create_app(conf="path/to/burpui.cfg")'
Note
The parallel backend is not compatible with gevent hence the different launching command.
Here are the results:
# with burp2 backend
bash /tmp/bench.sh 0.10s user 0.06s system 0% cpu 20.377 total
bash /tmp/bench.sh 0.11s user 0.04s system 0% cpu 21.447 total
# with parallel backend
bash /tmp/bench.sh 0.12s user 0.04s system 1% cpu 10.267 total
bash /tmp/bench.sh 0.11s user 0.05s system 1% cpu 9.735 total
My feeling is, the more you have CPU cores, the more performance improvements you’ll notice over the burp2 backend because we let the kernel handle the I/O parallelization with the parallel backend and bui-monitor.
I also ran similar tests on a production environment with more than 100 clients and here are the results:
# Tests agains the *parallel* backend with 16 processes in the pool
➜ ~ ab -A user:password -H "X-No-Cache:True" -n 100 -c 10 https://backup1.example.org/api/client/stats/client1
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking backup1.example.org (be patient).....done
Server Software: nginx
Server Hostname: backup1.example.org
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,4096,256
TLS Server Name: backup1.example.org
Document Path: /api/client/stats/client1
Document Length: 2713 bytes
Concurrency Level: 10
Time taken for tests: 18.832 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 313100 bytes
HTML transferred: 271300 bytes
Requests per second: 5.31 [#/sec] (mean)
Time per request: 1883.233 [ms] (mean)
Time per request: 188.323 [ms] (mean, across all concurrent requests)
Transfer rate: 16.24 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 9 16 13.0 12 72
Processing: 75 1862 3347.6 222 13963
Waiting: 75 1862 3347.6 222 13963
Total: 86 1878 3358.2 237 14009
Percentage of the requests served within a certain time (ms)
50% 237
66% 679
75% 2355
80% 2930
90% 8556
95% 11619
98% 11878
99% 14009
100% 14009 (longest request)
# Tests against gunicorn+gevent with the plain *burp2* backend
➜ ~ ab -A user:password -H "X-No-Cache:True" -n 100 -c 10 https://backup1.example.org/api/client/stats/client1
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking backup1.example.org (be patient).....done
Server Software: nginx
Server Hostname: backup1.example.org
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,4096,256
TLS Server Name: backup1.example.org
Document Path: /api/client/stats/client1
Document Length: 2713 bytes
Concurrency Level: 10
Time taken for tests: 54.601 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 313100 bytes
HTML transferred: 271300 bytes
Requests per second: 1.83 [#/sec] (mean)
Time per request: 5460.086 [ms] (mean)
Time per request: 546.009 [ms] (mean, across all concurrent requests)
Transfer rate: 5.60 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 9 18 11.1 13 52
Processing: 27 5357 4021.1 4380 18894
Waiting: 27 5357 4021.0 4380 18894
Total: 40 5375 4024.5 4402 18940
Percentage of the requests served within a certain time (ms)
50% 4402
66% 6048
75% 7412
80% 8114
90% 11077
95% 12767
98% 18916
99% 18940
100% 18940 (longest request)
What’s interesting with the parallel backend is it can handle even more requests with a low overhead as you can see here:
➜ ~ ab -A user:password -H "X-No-Cache:True" -n 500 -c 10 https://backup1.example.org/api/client/stats/client1
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking backup1.example.org (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests
Server Software: nginx
Server Hostname: backup1.example.org
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,4096,256
TLS Server Name: backup1.example.org
Document Path: /api/client/stats/client1
Document Length: 2713 bytes
Concurrency Level: 10
Time taken for tests: 28.073 seconds
Complete requests: 500
Failed requests: 0
Total transferred: 1565500 bytes
HTML transferred: 1356500 bytes
Requests per second: 17.81 [#/sec] (mean)
Time per request: 561.454 [ms] (mean)
Time per request: 56.145 [ms] (mean, across all concurrent requests)
Transfer rate: 54.46 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 8 15 8.8 13 72
Processing: 101 546 856.5 209 3589
Waiting: 101 546 856.5 209 3589
Total: 114 561 860.3 223 3661
Percentage of the requests served within a certain time (ms)
50% 223
66% 241
75% 264
80% 298
90% 2221
95% 2963
98% 3316
99% 3585
100% 3661 (longest request)
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
➜ ~ ab -A user:password -H "X-No-Cache:True" -n 1000 -c 10 https://backup1.example.org/api/client/stats/client1
Benchmarking backup1.example.org (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests
Server Software: nginx
Server Hostname: backup1.example.org
Server Port: 443
SSL/TLS Protocol: TLSv1/SSLv3,ECDHE-RSA-AES256-GCM-SHA384,4096,256
Document Path: /api/client/stats/client1
Document Length: 2708 bytes
Concurrency Level: 10
Time taken for tests: 69.908 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 3126000 bytes
HTML transferred: 2708000 bytes
Requests per second: 14.30 [#/sec] (mean)
Time per request: 699.081 [ms] (mean)
Time per request: 69.908 [ms] (mean, across all concurrent requests)
Transfer rate: 43.67 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 8 12 5.1 10 65
Processing: 77 687 1070.7 245 5122
Waiting: 77 687 1070.7 245 5122
Total: 86 698 1072.4 256 5149
Percentage of the requests served within a certain time (ms)
50% 256
66% 290
75% 329
80% 367
90% 2938
95% 3408
98% 3827
99% 4693
100% 5149 (longest request)
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
In comparison, this is the result for 500 requests against gunicorn+gevent:
➜ ~ ab -A user:password -H "X-No-Cache:True" -n 500 -c 10 https://backup1.example.org/api/client/stats/client1
Benchmarking backup1.example.org (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests
Server Software: nginx
Server Hostname: backup1.example.org
Server Port: 443
SSL/TLS Protocol: TLSv1/SSLv3,ECDHE-RSA-AES256-GCM-SHA384,4096,256
Document Path: /api/client/stats/client1
Document Length: 2708 bytes
Concurrency Level: 10
Time taken for tests: 232.800 seconds
Complete requests: 500
Failed requests: 0
Write errors: 0
Total transferred: 1563000 bytes
HTML transferred: 1354000 bytes
Requests per second: 2.15 [#/sec] (mean)
Time per request: 4655.994 [ms] (mean)
Time per request: 465.599 [ms] (mean, across all concurrent requests)
Transfer rate: 6.56 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 8 14 10.3 10 69
Processing: 25 4628 3601.4 4219 28806
Waiting: 25 4627 3601.4 4219 28806
Total: 34 4642 3602.4 4233 28815
Percentage of the requests served within a certain time (ms)
50% 4233
66% 5306
75% 6131
80% 6505
90% 8856
95% 10798
98% 14538
99% 18397
100% 28815 (longest request)
In conclusion, if you have several users using burp-ui you will probably notice a nice performance improvement when using the new bui-monitor with the parallel backend.
Service¶
I have no plan to implement daemon features, but there are a lot of tools available to help you achieve such a behavior.
To run bui-monitor as a service, a systemd file is provided. You can use it like this:
cp /usr/local/share/burpui/contrib/systemd/bui-monitor.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable bui-monitor.service
systemctl start bui-monitor.service