SSL man in the middle in Ruby?


#1

Guys,

I’m interested in implementing a simple SSL man-in-the-middle proxy
(intercepting traffic by offering my own certificate, then transparently
proxying the request out to whatever host was requested and the response
back to the client) using Ruby. This project is for research purposes
only…mainly helping me better understand SSL traffic, and also because
I
may potentially need to do the same thing for work in Java (ugh) and
would
prefer to prototype it using something lighter (like my fav language).

Does anyone know if there are any specific limitations that would
prevent me
from doing this in ruby? Can you offer any pointers/suggestions in
getting
started? I’m new to SSL in a programmatic sense, and even newer to SSL
with
Ruby.

Thanks!
Jake


#2

On 1/28/07, Jake C. removed_email_address@domain.invalid wrote:

Does anyone know if there are any specific limitations that would prevent
me from doing this in ruby? Can you offer any pointers/suggestions in
getting started? I’m new to SSL in a programmatic sense, and even newer to
SSL with Ruby.

Bumping early (sorry :wink: ), as I was hoping to get started on this
today. Is
it a mistake for me to give it a go in Ruby? Does just going Java out
of
the box make more sense? I’m just unsure what facilities exist in Ruby
for
doing an ssl proxy (offering certs, etc). Anyone know of any other
projects
that may already do something similar?

Thanks guys.

Jake


#3

On 1/28/07, Jake C. removed_email_address@domain.invalid wrote:

On 1/28/07, Jake C. removed_email_address@domain.invalid wrote:

Bumping early (sorry :wink: ), as I was hoping to get started on this today. Is
it a mistake for me to give it a go in Ruby? Does just going Java out of
the box make more sense? I’m just unsure what facilities exist in Ruby for
doing an ssl proxy (offering certs, etc). Anyone know of any other projects
that may already do something similar?

What have you already looked at?


#4

On 1/28/07, Jeff B. removed_email_address@domain.invalid wrote:

Maybe you could hook into it more easily than writing your own. If you are
simply wanting logging, then it certainly has that already built in (as do
most web servers or load balancers). It is a nice easy to configure server
that does its job well.

Jeff,

Thanks very much for the info. What my company wants is a way to monitor
ssl
traffic for its customers to any site. So, it would be like using
something
like Squid, except running some intelligent parsers on any traffic that
goes
through including SSL decrypted traffic. This is where nginx would fail,
I
believe, because you have to specifically configure it to point to a set
of
hosts, whereas the tool I would hope to write would simply decrypt and
forward traffic to any host. Is this the case?

Thanks!
Jake


#5

On 1/28/07, Jake C. removed_email_address@domain.invalid wrote:

I would offer that it takes a decent amount of CPU to perform SSL even
using
machine optimized code so depending on how much concurrent traffic you
are
expecting this could be an issue if you decided to use pure Ruby.

You might look into using something that already does SSL and reverse
proxying and modifying it. For instance I simply love nginx which is an
open
source lightweight reverse proxy with web server capabilities. We run it
in
front of our mongrel cluster and it works really well. It has SSL
capabilities so that it decrypts and then forwards a normal http request
onto the mongrel cluster.

Maybe you could hook into it more easily than writing your own. If you
are
simply wanting logging, then it certainly has that already built in (as
do
most web servers or load balancers). It is a nice easy to configure
server
that does its job well.

Here is some information on nginx.

http://nginx.net/
http://zh.stikipad.com/notes/show/nginx
http://blog.kovyrin.net/2006/04/04/nginx-small-powerful-web-server/
http://blog.kovyrin.net/2006/05/18/nginx-as-reverse-proxy/

Hope this helps,

Jeff


#6

On 1/28/07, Jake C. removed_email_address@domain.invalid wrote:

of
hosts, whereas the tool I would hope to write would simply decrypt and
forward traffic to any host. Is this the case?

Yes you are correct, nginx will work as a reverse proxy not a proxy. So
you
are wanting more like a regular proxy to be able to monitor traffic to
external sites. However, other than knowing the IP address they are
trying
to go to, note that SSL will not allow you to decrypt the traffic in the
middle, this is by design (to prevent the man in the middle attack). The
key
negotiation is between the client and the final destination. So you
won’t be
able to know anything other than the IP address that the client is
connecting to and maybe a rough idea of traffic volume, you won’t have
any
specifics about the what kind of data or exact site name.

Knowing all this, it sounds like you could get this same level of
information from your firewall or a standard proxy. You won’t be able to
decrypt the traffic, nor gather any additional information no matter
what
you put in the middle.

Jeff


#7

On 1/28/07, Jake C. removed_email_address@domain.invalid wrote:

key

I do note this. However, the plan is to offer our own certificate for
every connection from the client, and then have the proxy engine itself
create the SSL connection to the server on the backend. delegate (
www.delegate.org) and WebScarab operate in this fashion, and are able to
decrypt all traffic that way.

I see. Well the users will get a warning that the certificate does not
match
the domain they are trying to reach (warning of a man in the middle
attack)
(your certificate will not match the one from the certificate
authority).
Normally users are supposed to know not to continue in such a
circumstance.

So I guess if all of this is acceptable, I guess what you are proposing
is
technically possible.

Of course in this situation, you are incurring the overhead of two SSL
connection (terminating and originating) for every outbound connection,
so
your load will be signifigant if you have any number of concurrent
users.

I think you will indeed need some optimized code to handle such load, so
you
could use ruby but you will very likely need to use some native library
(openssl) to get decent performance in the processor intensive SSL
operations. Java might work for light loads, but I wouldn’t want to use
it
for heavy loads.

However there are hardware SSL accelerators that can help, the kind that
load balancers can optionally add in. You then offload the heavy lifting
to
them.

Hope this helps in your endeavor.

Jeff


#8

On 1/28/07, Jeff B. removed_email_address@domain.invalid wrote:

able to know anything other than the IP address that the client is
connecting to and maybe a rough idea of traffic volume, you won’t have any
specifics about the what kind of data or exact site name.

Jeff,

I do note this. However, the plan is to offer our own certificate for
every connection from the client, and then have the proxy engine
itself
create the SSL connection to the server on the backend. delegate (
www.delegate.org) and WebScarab operate in this fashion, and are able to
decrypt all traffic that way.

Thanks,
John