I'm trying to develop a transparent proxy which forwards unsecured http traffic from the clients as secured https traffic to the server, and back again. To better illustrate my point, take a look at the following image.
Let's suppose that for various reasons the clients will be using HTTP only, they can't use port 443 for HTTPS. Since some servers don't accept traffic from port 80, my proxy needs to reroute them to port 443. This is a possible scenario:
Since this is a transparent proxy, the clients (in my case lots of them) shouldn't need any extra configuration. The network is already configured so that their traffic go through my node. Currently my node simply reroutes the data and blocks some if they contain viruses. This is done using WinPcap to get access to low networking layers but I'm willing to change my approach if it's too hard to be done using raw packets (mainly concerned about the handshake).
What I've tried: Note: www.google.com could be any site on the web. It's merely used as an example.
What would be the best way to go into developing such a proxy?
Edit: Is there ANY way that TcpListener or HttpListener can act as a transparent proxy? (Without configuration on the clients' computers). When exactly does HttpListener recognize that a client is trying to connect?
I don't really understand why you need to read the encrypted data from the SslStream
. If I'm reading your description correctly, you should simply need to:
NetworkStream
in an SslStream
and AuthenticateAsClient
SslStream
SslStream
and write it to the client I don't see anywhere in this process that you'd need to see the encrypted data from the SslStream
.
The following is a very basic sample (though completely untested):
static void Main(string[] args)
{
var listener = new TcpListener(IPAddress.Any, 11180);
var clientConnection = listener.AcceptTcpClient();
// When we get here, the client has connected, initiate the server connection
var serverConnection = new TcpClient("your.server.name", 443);
var serverStream = serverConnection.GetStream();
var secureStream = new SslStream(serverStream);
secureStream.AuthenticateAsClient("your.server.name");
ConnectStreams(clientConnection.GetStream(), secureStream);
}
private static void ConnectStreams(Stream streamA, Stream streamB)
{
ForwardStream(streamA, streamB, new byte[1024]);
ForwardStream(streamB, streamA, new byte[1024]);
}
private static void ForwardStream(Stream source, Stream destination, byte[] buffer)
{
source.BeginRead(buffer, 0, buffer.Length, r => Forward(source, destination, r, buffer), null);
}
private static void Forward(Stream source, Stream destination, IAsyncResult asyncResult, byte[] buffer)
{
var bytesRead = source.EndRead(asyncResult);
if (bytesRead == 0)
{
destination.Close();
return;
}
destination.Write(buffer, 0, bytesRead);
ForwardStream(source, destination, buffer);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.