mitmproxy is an excellent console app written in Python.
It is easy to use on Linux and OS X.
Use brew install mitmproxy
to install it on OS X.
-
Run
mitmproxy
-
Set the following in
knife.rb
orclient.rb
.https_proxy "https://127.0.0.1:8080"
-
If you are using Chef 12 then you will need to copy
~/.mitmproxy/mitmproxy-ca-cert.pem
to Chef'strusted_certs
directory so chef-client and knife will trust the SSL connection to mitmproxy.cp ~/.mitmproxy/mitmproxy-ca-cert.pem .chef/trusted_certs/
-
Run knife commands or chef-client.
-
Monitor or manipulate the cleartext traffic using mitmproxy's console.
mitmproxy has a number of dependencies that need to be installed if you aren't using a prebuilt package. This can be inconvenient especially in a support situation. The stunnel
solution given below is a lightweight alternative.
Fiddler is for use on Windows platform.
stunnel is a tool that can be used as a MITM proxy for SSL encrypted protocols such as HTTPS, LDAPS and IMAPS. stunnel has minimal dependencies making it a very lightweight solution.
Installation:
- OS X -
brew install stunnel
- Most Linux distributions can easily install stunnel using their respective package management systems.
- RHEL/CentOS -
sudo yum install stunnel
- Debian/Ubuntu -
sudo apt-get install stunnel
- RHEL/CentOS -
- Windows - stunnel downloads web page has an executable binary available.
Use openssl
to create a self signed certificate server.pem.
openssl req -batch -new -x509 -days 365 -nodes -out server.pem -keyout server.pem
Download the simple configuration file stunnel-mitm-proxy.conf to the same directory as the server.pem.
This configuration causes the stunnel server to bind to the privileged port 443 so be sure to run stunnel as
either the root user or with the sudo command. Binding to port 443 simplifies usage with knife and chef-client
since some of their code will not use a port other than 443. (e.g. knife cookbook upload
sandbox API requests)
Then start stunnel. If you are running stunnel on Debian or Ubuntu then replace the stunnel
command with stunnel4
.
sudo stunnel stunnel-mitm-proxy.conf
Replace the domain name in knife.rb or client.rb chef_server_url
parameter with 127.0.0.1:443
.
Now you can use tools like tcpdump or wireshark to capture the cleartext traffic to a file or watch it in real time.
sudo tcpdump -ilo0 -s0 -w ./captured.pcap 'port 4434'
Run the following command on Linux or OS X to stop stunnel.
sudo pkill -f stunnel-mitm-proxy
As a proof of concept, the openssl
tool can be used on Linux or OS X to create a rudimentary MITM SSL proxy.
The openssl s_client
used below will terminate after an API request-response completes since the Chef API protocol closes the client-server connection after each response. That means this MITM SSL Proxy is only good for one API request-response at a time. You would have to start the openssl s_client
again to achieve another successful API request-response. Other methods could be used to automatically restart the openssl s_client
but that is out of scope for this proof of concept.
Use openssl
to create a self signed certificate server.pem.
openssl req -batch -new -x509 -days 365 -nodes -out server.pem -keyout server.pem
Create two named pipes.
mkfifo request response
Run the following command lines in separate terminal windows.
openssl s_server -quiet -cert server.pem -accept 4433 < response | tee -a request
openssl s_client -quiet -connect api.opscode.com:443 < request | tee -a response
Replace the domain name in knife.rb or client.rb chef_server_url
parameter with 127.0.0.1:4433
.
Now you can use tools like tcpdump or wireshark to capture the cleartext traffic to a file or watch it in real time.
sudo tcpdump -ilo -s0 -w ./captured.pcap 'port 4434'
When you are done you can delete the named pipes using the following command.
rm request response
Hi,
thanks for this interesting example. I trying to add SSL to the service, that has not own SSL implementation (client have it). So I just want to use stunnel to recieve SSL traffic from client, decrypt it and send to another port to the service as a plain traffic.
Could you please explain me how is it possible to tune-up this configuration to encrypt responce from the service and return it back to SSL client? As I see, there is [client] section, but uses specified hostname for the connection. Is it possible to make it for any connected client? Yes, sure, for my development purposes I can use only one client and specify it in this configuration, but I look smething more general, just to setup once and share inside the team.