mallory
Man-in-the-middle transparent HTTP/HTTPS CONNECT proxy, supports
- both HTTP and HTTPS (via CONNECT https tunneling)
- load balancing over external (unreliable) backend proxies, with some added reliability and retry policies
It is intended to be used for running test suits / scrapers. It basically shields the proxied application from low responsiveness / poor reliability of underlying proxies, while providing a full request log (both for HTTP and HTTPS). If not backends specified, requests will be performed directly.
Optional backend proxy list is fetched from Redis or flat file, and refreshed periodically. Original use case involves separate proxy-gathering daemon (out of the scope of this project).
For mallory to work properly custom CA needs to be added as trusted. Optionally client certificate validation can be turned off.
Usage
Command line
Generate keys with ./keys/keygen.sh
bundle exec ./bin/mallory -v -p 9999 #default (no proxy backend, direct requests)
bundle exec ./bin/mallory -v -b file://proxies.txt -p 9999 #start with proxy file
bundle exec ./bin/mallory -v -b redis://127.0.0.1:6379 -p 9999 #start with Redis backend
curl --insecure --proxy 127.0.0.1:9999 https://www.dropbox.com/login
phantomjs --debug=yes --ignore-ssl-errors=yes --ssl-protocol=sslv2 --proxy=127.0.0.1:9999 --proxy-type=http hello.js
Do bundle exec ./bin/mallory --help
for help.
Interface
mb = Mallory::Backend::File.new('proxies.txt')
mp = Mallory::Proxy.new()
mp.backend = mb
mp.start!
Proxy backends
Self
Just direct requests, no proxies, default
File
Text file, one http proxy per line, in proxy:port
format.
Redis
Redis key TODO
What mallory is not
- General purpose proxying daemon
- General purpose proxy load balancer
- Anything general purpose really
- For mature general purpose mitm solution (in Python) see mitmproxy
TODO
- CA support
- SOCKS5 backends (mixing http and SOCKS5 proxies)
- parallel requests
- even better response reliability