我正在尝试开发一个透明代理,它将来自客户端的不安全的http流量作为安全的https流量转发到服务器,然后再返回。为了更好地说明我的观点,请看下面的图像。
假设由于各种原因客户端将仅使用HTTP,他们不能将端口443用于HTTPS。由于某些服务器不接受来自端口80的流量,因此我的代理需要将它们重新路由到端口443.这是一种可能的情况:
由于这是一个透明的代理,客户端(在我的情况下很多)不需要任何额外的配置。已配置网络,以便其流量通过我的节点。目前,我的节点只是重新路由数据,并阻止一些包含病毒的数据。这是使用WinPcap来完成对低网络层的访问,但如果使用原始数据包(主要是关于握手)太难以完成,我愿意改变我的方法。
我尝试了什么: 注意:www.google.com可以是网络上的任何网站。它只是用作一个例子。
开发此类代理的最佳方式是什么?
编辑:TcpListener或HttpListener是否可以充当透明代理? (无需在客户端计算机上进行配置)。什么时候HttpListener确实认识到客户端正在尝试连接?
答案 0 :(得分:0)
我真的不明白为什么你需要从SslStream
读取加密数据。如果我正确阅读您的描述,您只需要:
NetworkStream
和SslStream
AuthenticateAsClient
SslStream
SslStream
读取数据并将其写入客户端我不会在此过程中看到您需要查看来自SslStream
的加密数据。
以下是一个非常基本的样本(虽然完全未经测试):
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);
}