/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server). /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint">The transparent endpoint.</param> /// <param name="clientConnection">The client connection.</param> /// <returns></returns> private Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConnection clientConnection) { var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; return(handleClient(endPoint, clientConnection, endPoint.Port, cancellationTokenSource, cancellationToken)); }
public void StartProxy() { proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { //Exclude Https addresses you don't want to proxy //Useful for clients that use certificate pinning //for example google.com and dropbox.com ExcludedHttpsHostNameRegex = new List <string> { "dropbox.com" } //Include Https addresses you want to proxy (others will be excluded) //for example github.com //IncludedHttpsHostNameRegex = new List<string> { "github.com" } //You can set only one of the ExcludedHttpsHostNameRegex and IncludedHttpsHostNameRegex properties, otherwise ArgumentException will be thrown //Use self-issued generic certificate on all https requests //Optimizes performance by not creating a certificate for each https-enabled domain //Useful when certificate trust is not required by proxy clients //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password") }; //An explicit endpoint is where the client knows about the existence of a proxy //So client sends request in a proxy friendly manner proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); //Transparent endpoint is useful for reverse proxying (client is not aware of the existence of proxy) //A transparent endpoint usually requires a network router port forwarding HTTP(S) packets to this endpoint //Currently do not support Server Name Indication (It is not currently supported by SslStream class) //That means that the transparent endpoint will always provide the same Generic Certificate to all HTTPS requests //In this example only google.com will work for HTTPS requests //Other sites will receive a certificate mismatch warning on browser var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; proxyServer.AddEndPoint(transparentEndPoint); //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; foreach (var endPoint in proxyServer.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } //Only explicit proxies can be set as system proxy! proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); }
public void Start() { _server.CertificateManager.CreateRootCertificate(); _server.CertificateManager.TrustRootCertificate(true); _server.BeforeRequest += OnRequest; _server.BeforeResponse += OnResponse; _server.ServerCertificateValidationCallback += OnCertificateValidation; _server.ClientCertificateSelectionCallback += OnCertificateSelection; _explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { }; _explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest; _server.AddEndPoint(_explicitEndPoint); _server.Start(); _server.SetAsSystemProxy(_explicitEndPoint, ProxyProtocolType.AllHttp); var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; _server.AddEndPoint(transparentEndPoint); _server.SetAsSystemHttpProxy(_explicitEndPoint); _server.SetAsSystemHttpsProxy(_explicitEndPoint); }
public void CreateProxySrvr() { proxyServer.CertificateManager.TrustRootCertificate(true); proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true); proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; proxyServer.AddEndPoint(transparentEndPoint); foreach (var endPoint in proxyServer.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); }
public static void ServerStart() { Instance.explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8765, true) { }; Instance.proxyServer.AddEndPoint(Instance.explicitEndPoint); var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8766, true) { GenericCertificateName = "google.com" }; Instance.proxyServer.AddEndPoint(transparentEndPoint); foreach (var endPoint in Instance.proxyServer.ProxyEndPoints) { } Instance.proxyServer.Start(); //Fired when a CONNECT request is received Instance.explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest; //Only explicit proxies can be set as system proxy! Instance.proxyServer.SetAsSystemHttpProxy(Instance.explicitEndPoint); Instance.proxyServer.SetAsSystemHttpsProxy(Instance.explicitEndPoint); Instance.proxyServer.BeforeRequest += OnRequest; Instance.proxyServer.BeforeResponse += OnResponse; Instance.proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; Instance.proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; }
public bool Start(HostControl hostControl) { proxyServer = new ProxyServer(); //proxyServer.CertificateManager.TrustRootCertificate(true); proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { }; proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; proxyServer.AddEndPoint(transparentEndPoint); proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); return(true); }
public MIMServer() { ps = new ProxyServer(); ps.TrustRootCertificate = true; ps.BeforeRequest += OnRequest; ps.BeforeResponse += OnResponse; ps.ServerCertificateValidationCallback += CertificateValidation; ps.ClientCertificateSelectionCallback += CertificateSelection; var endPoint = new ExplicitProxyEndPoint(System.Net.IPAddress.Any, 8030, true) { }; ps.AddEndPoint(endPoint); ps.Start(); var transparentEndPoint = new TransparentProxyEndPoint(System.Net.IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; ps.AddEndPoint(transparentEndPoint); ps.SetAsSystemHttpProxy(endPoint); ps.SetAsSystemHttpsProxy(endPoint); foreach (var ep in ps.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", ep.GetType().Name, ep.IpAddress, ep.Port); } Console.WriteLine("Ready"); }
public void Initialize() { _proxyServer = new ProxyServer(); //locally trust root certificate used by this proxy _proxyServer.CertificateManager.TrustRootCertificate(true); //proxyServer.CertificateManager.TrustRootCertificate = true; //optionally set the Certificate Engine //Under Mono only BouncyCastle will be supported //proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle; _proxyServer.BeforeRequest += OnRequest; _proxyServer.BeforeResponse += OnResponse; _proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; _proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; _explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { //Use self-issued generic certificate on all https requests //Optimizes performance by not creating a certificate for each https-enabled domain //Useful when certificate trust is not required by proxy clients //GenericCertificate = new X509Certificate2(Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "genericcert.pfx"), "password") }; //Fired when a CONNECT request is received _explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest; //An explicit endpoint is where the client knows about the existence of a proxy //So client sends request in a proxy friendly manner _proxyServer.AddEndPoint(_explicitEndPoint); _proxyServer.Start(); //Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy) //A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS //to send data to this endPoint var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { //Generic Certificate hostname to use //when SNI is disabled by client GenericCertificateName = "google.com" }; _proxyServer.AddEndPoint(transparentEndPoint); //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; foreach (var endPoint in _proxyServer.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } //Only explicit proxies can be set as system proxy! _proxyServer.SetAsSystemHttpProxy(_explicitEndPoint); _proxyServer.SetAsSystemHttpsProxy(_explicitEndPoint); }
//This is called when this proxy acts as a reverse proxy (like a real http server) //So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) { Stream clientStream = tcpClient.GetStream(); clientStream.ReadTimeout = ConnectionTimeOutSeconds * 1000; clientStream.WriteTimeout = ConnectionTimeOutSeconds * 1000; CustomBinaryReader clientStreamReader = null; StreamWriter clientStreamWriter = null; X509Certificate2 certificate = null; if (endPoint.EnableSsl) { var sslStream = new SslStream(clientStream, true); //implement in future once SNI supported by SSL stream, for now use the same certificate certificate = certificateCacheManager.CreateCertificate(endPoint.GenericCertificateName, false); try { //Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); clientStreamReader = new CustomBinaryReader(sslStream); clientStreamWriter = new StreamWriter(sslStream) { NewLine = ProxyConstants.NewLine }; //HTTPS server created - we can now decrypt the client's traffic } catch (Exception) { sslStream.Dispose(); Dispose(sslStream, clientStreamReader, clientStreamWriter, null); return; } clientStream = sslStream; } else { clientStreamReader = new CustomBinaryReader(clientStream); clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine }; } //now read the request line var httpCmd = await clientStreamReader.ReadLineAsync(); //Now create the request await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, endPoint.EnableSsl?endPoint.GenericCertificateName : null, endPoint, null); }
//This is called when requests are routed through router to this endpoint //For ssl requests private static void HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) { Stream clientStream = tcpClient.GetStream(); CustomBinaryReader clientStreamReader = null; StreamWriter clientStreamWriter = null; X509Certificate2 certificate = null; if (endPoint.EnableSsl) { var sslStream = new SslStream(clientStream, true); //if(endPoint.UseServerNameIndication) //{ // //implement in future once SNI supported by SSL stream // certificate = CertManager.CreateCertificate(endPoint.GenericCertificateName); //} //else certificate = CertManager.CreateCertificate(endPoint.GenericCertificateName); try { //Successfully managed to authenticate the client using the fake certificate sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls, false); clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII); clientStreamWriter = new StreamWriter(sslStream); //HTTPS server created - we can now decrypt the client's traffic } catch (Exception) { if (sslStream != null) { sslStream.Dispose(); } Dispose(tcpClient, sslStream, clientStreamReader, clientStreamWriter, null); return; } clientStream = sslStream; } else { clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII); } var httpCmd = clientStreamReader.ReadLine(); //Now create the request HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, true); }
public void StartProxy() { proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; //Exclude Https addresses you don't want to proxy //Usefull for clients that use certificate pinning //for example dropbox.com var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { ExcludedHttpsHostNameRegex = new List <string>() { "google.com", "dropbox.com" } }; //An explicit endpoint is where the client knows about the existance of a proxy //So client sends request in a proxy friendly manner proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); //Transparent endpoint is usefull for reverse proxying (client is not aware of the existance of proxy) //A transparent endpoint usually requires a network router port forwarding HTTP(S) packets to this endpoint //Currently do not support Server Name Indication (It is not currently supported by SslStream class) //That means that the transparent endpoint will always provide the same Generic Certificate to all HTTPS requests //In this example only google.com will work for HTTPS requests //Other sites will receive a certificate mismatch warning on browser var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; proxyServer.AddEndPoint(transparentEndPoint); //ProxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //ProxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; foreach (var endPoint in proxyServer.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } //Only explicit proxies can be set as system proxy! proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); }
/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server) /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint"></param> /// <param name="tcpClient"></param> /// <returns></returns> private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) { bool disposed = false; var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize); CustomBinaryReader clientStreamReader = null; HttpResponseWriter clientStreamWriter = null; try { if (endPoint.EnableSsl) { var clientHelloInfo = await SslTools.PeekClientHello(clientStream); if (clientHelloInfo != null) { var sslStream = new SslStream(clientStream); clientStream = new CustomBufferedStream(sslStream, BufferSize); string sniHostName = clientHelloInfo.GetServerName(); string certName = HttpHelper.GetWildCardDomainName(sniHostName ?? endPoint.GenericCertificateName); var certificate = CertificateManager.CreateCertificate(certName, false); //Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); } //HTTPS server created - we can now decrypt the client's traffic } clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize); //now read the request line string httpCmd = await clientStreamReader.ReadLineAsync(); //Now create the request disposed = await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, endPoint.EnableSsl?endPoint.GenericCertificateName : null, endPoint, null, true); } finally { if (!disposed) { Dispose(clientStream, clientStreamReader, clientStreamWriter, null); } } }
/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server) /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint"></param> /// <param name="tcpClient"></param> /// <returns></returns> private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) { var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize); var clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize); try { if (endPoint.EnableSsl) { var clientHelloInfo = await SslTools.PeekClientHello(clientStream); if (clientHelloInfo != null) { var sslStream = new SslStream(clientStream); clientStream = new CustomBufferedStream(sslStream, BufferSize); string sniHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName; string certName = HttpHelper.GetWildCardDomainName(sniHostName); var certificate = await CertificateManager.CreateCertificateAsync(certName); try { //Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); } catch (Exception e) { ExceptionFunc(new Exception($"Could'nt authenticate client '{sniHostName}' with fake certificate.", e)); return; } } //HTTPS server created - we can now decrypt the client's traffic } //Now create the request await HandleHttpSessionRequest(tcpClient, clientStream, clientStreamReader, clientStreamWriter, endPoint.EnableSsl?endPoint.GenericCertificateName : null, endPoint, null, true); } finally { clientStreamReader.Dispose(); clientStream.Dispose(); } }
public void SnifferStart() { //locally trust root certificate used by this proxy _proxyServer.CertificateManager.TrustRootCertificate(true); //optionally set the Certificate Engine //Under Mono only BouncyCastle will be supported //proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastle; _proxyServer.BeforeRequest += OnRequest; _proxyServer.BeforeResponse += OnResponse; _proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; _proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; //Fired when a CONNECT request is received //_explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest; //An explicit endpoint is where the client knows about the existence of a proxy //So client sends request in a proxy friendly manner _proxyServer.AddEndPoint(_explicitEndPoint); _proxyServer.Start(); //Transparent endpoint is useful for reverse proxy (client is not aware of the existence of proxy) //A transparent endpoint usually requires a network router port forwarding HTTP(S) packets or DNS //to send data to this endPoint var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { //Generic Certificate hostname to use //when SNI is disabled by client GenericCertificateName = "google.com" }; _proxyServer.AddEndPoint(transparentEndPoint); //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; foreach (var endPoint in _proxyServer.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } //Only explicit proxies can be set as system proxy! // _proxyServer.SetAsSystemHttpProxy(_explicitEndPoint); // _proxyServer.SetAsSystemHttpsProxy(_explicitEndPoint); }
public void Start() { _proxyServer = new ProxyServer(); // locally trust root certificate used by this proxy _proxyServer.TrustRootCertificate = true; //optionally set the Certificate Engine //Under Mono only BouncyCastle will be supported _proxyServer.CertificateEngine = CertificateEngine.BouncyCastle; _proxyServer.BeforeRequest += OnRequest; _proxyServer.BeforeResponse += OnResponse; _proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; _proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; var startupPath = Environment.CurrentDirectory; var certPath = Path.Combine(startupPath, "FiddlerRoot.cer"); var cert = new X509Certificate2(certPath); var ep1 = new TransparentProxyEndPoint(IPAddress.Any, 80, true) { //Use self-issued generic certificate on all HTTPS requests //Optimizes performance by not creating a certificate for each HTTPS-enabled domain //Useful when certificate trust is not required by proxy clients // GenericCertificate = cert }; var ep2 = new TransparentProxyEndPoint(IPAddress.Any, 443, true) { // GenericCertificate = cert }; //An explicit endpoint is where the client knows about the existence of a proxy //So client sends request in a proxy friendly manner _proxyServer.AddEndPoint(ep1); _proxyServer.AddEndPoint(ep2); _proxyServer.Enable100ContinueBehaviour = true; foreach (var endPoint in _proxyServer.ProxyEndPoints) { Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } _proxyServer.Start(); // _proxyServer.SetAsSystemProxy(ep1, ProxyProtocolType.AllHttp); }
/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server) /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint"></param> /// <param name="tcpClient"></param> /// <returns></returns> private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) { bool disposed = false; var clientStream = new CustomBufferedStream(tcpClient.GetStream(), BufferSize); CustomBinaryReader clientStreamReader = null; StreamWriter clientStreamWriter = null; try { if (endPoint.EnableSsl) { var sslStream = new SslStream(clientStream); clientStream = new CustomBufferedStream(sslStream, BufferSize); //implement in future once SNI supported by SSL stream, for now use the same certificate var certificate = CertificateManager.CreateCertificate(endPoint.GenericCertificateName, false); //Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); //HTTPS server created - we can now decrypt the client's traffic } clientStreamReader = new CustomBinaryReader(clientStream, BufferSize); clientStreamWriter = new StreamWriter(clientStream) { NewLine = ProxyConstants.NewLine }; //now read the request line var httpCmd = await clientStreamReader.ReadLineAsync(); //Now create the request disposed = await HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, endPoint.EnableSsl?endPoint.GenericCertificateName : null, endPoint, null); } finally { if (!disposed) { Dispose(clientStream, clientStreamReader, clientStreamWriter, null); } } }
public void StartProxy() { var listenPort = _config["Proxy:ListenPort"]; var targetServer = _config["Proxy:TargetServer"]; var targetPort = _config["Proxy:TargetPort"]; _logger.LogInformation($"Proxy config - listen port: {listenPort}, target server: {targetServer}, targetPort: {targetPort}"); var endPoint = new TransparentProxyEndPoint(IPAddress.Any, int.Parse(listenPort), false); _server.AddEndPoint(endPoint); _server.BeforeRequest += OnRequest; _server.UpStreamHttpProxy = new ExternalProxy() { HostName = targetServer, Port = int.Parse(targetPort) }; _server.Start(); _logger.LogInformation("Proxy server listening"); }
/// <summary> /// Handle the client. /// </summary> /// <param name="tcpClient">The client.</param> /// <param name="endPoint">The proxy endpoint.</param> /// <returns>The task.</returns> private async Task handleClient(TcpClient tcpClient, ProxyEndPoint endPoint) { tcpClient.ReceiveTimeout = ConnectionTimeOutSeconds * 1000; tcpClient.SendTimeout = ConnectionTimeOutSeconds * 1000; tcpClient.SendBufferSize = BufferSize; tcpClient.ReceiveBufferSize = BufferSize; await InvokeConnectionCreateEvent(tcpClient, true); using (var clientConnection = new TcpClientConnection(this, tcpClient)) { if (endPoint is TransparentProxyEndPoint) { TransparentProxyEndPoint tep = endPoint as TransparentProxyEndPoint; await handleClient(tep, clientConnection); } else { await handleClient((ExplicitProxyEndPoint)endPoint, clientConnection); } } }
/// <summary> /// Fonction qui va démarrer le proxy. /// Elle va ajouter des évènement pour les requêtes et réponses HTTP /// Elle va ajouter des certificat pour le HTTPS /// </summary> public void StartProxy() { proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true) { }; proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; proxyServer.AddEndPoint(transparentEndPoint); proxyServer.SetAsSystemHttpProxy(explicitEndPoint); proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); }
/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server). /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint">The transparent endpoint.</param> /// <param name="clientConnection">The client connection.</param> /// <returns></returns> private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConnection clientConnection) { var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferPool, BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); Task <TcpServerConnection> prefetchConnectionTask = null; bool closeServerConnection = false; bool calledRequestHandler = false; try { var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); bool isHttps = clientHelloInfo != null; string httpsHostName = null; if (isHttps) { httpsHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName; var args = new BeforeSslAuthenticateEventArgs(cancellationTokenSource) { SniHostName = httpsHostName }; await endPoint.InvokeBeforeSslAuthenticate(this, args, ExceptionFunc); if (cancellationTokenSource.IsCancellationRequested) { throw new Exception("Session was terminated by user."); } if (endPoint.DecryptSsl && args.DecryptSsl) { if (EnableTcpServerConnectionPrefetch) { //don't pass cancellation token here //it could cause floating server connections when client exits prefetchConnectionTask = tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port, httpVersion: null, isHttps: true, applicationProtocols: null, isConnect: false, proxyServer: this, session: null, upStreamEndPoint: UpStreamEndPoint, externalProxy: UpStreamHttpsProxy, noCache: false, cancellationToken: CancellationToken.None); } SslStream sslStream = null; //do client authentication using fake certificate try { sslStream = new SslStream(clientStream); string certName = HttpHelper.GetWildCardDomainName(httpsHostName); var certificate = endPoint.GenericCertificate ?? await CertificateManager.CreateCertificateAsync(certName); // Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); // HTTPS server created - we can now decrypt the client's traffic clientStream = new CustomBufferedStream(sslStream, BufferPool, BufferSize); clientStreamWriter = new HttpResponseWriter(clientStream, BufferPool, BufferSize); } catch (Exception e) { sslStream?.Dispose(); throw new ProxyConnectException( $"Could'nt authenticate client '{httpsHostName}' with fake certificate.", e, null); } } else { var connection = await tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port, httpVersion : null, isHttps : false, applicationProtocols : null, isConnect : true, proxyServer : this, session : null, upStreamEndPoint : UpStreamEndPoint, externalProxy : UpStreamHttpsProxy, noCache : true, cancellationToken : cancellationToken); try { CustomBufferedStream serverStream = null; int available = clientStream.Available; if (available > 0) { // send the buffered data var data = BufferPool.GetBuffer(BufferSize); try { // clientStream.Available sbould be at most BufferSize because it is using the same buffer size await clientStream.ReadAsync(data, 0, available, cancellationToken); serverStream = connection.Stream; await serverStream.WriteAsync(data, 0, available, cancellationToken); await serverStream.FlushAsync(cancellationToken); } finally { BufferPool.ReturnBuffer(data); } } await TcpHelper.SendRaw(clientStream, serverStream, BufferPool, BufferSize, null, null, cancellationTokenSource, ExceptionFunc); } finally { await tcpConnectionFactory.Release(connection, true); } return; } } calledRequestHandler = true; // HTTPS server created - we can now decrypt the client's traffic // Now create the request await handleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, cancellationTokenSource, isHttps?httpsHostName : null, null, prefetchConnectionTask); } catch (ProxyException e) { closeServerConnection = true; onException(clientStream, e); } catch (IOException e) { closeServerConnection = true; onException(clientStream, new Exception("Connection was aborted", e)); } catch (SocketException e) { closeServerConnection = true; onException(clientStream, new Exception("Could not connect", e)); } catch (Exception e) { closeServerConnection = true; onException(clientStream, new Exception("Error occured in whilst handling the client", e)); } finally { if (!calledRequestHandler) { await tcpConnectionFactory.Release(prefetchConnectionTask, closeServerConnection); } clientStream.Dispose(); if (!cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource.Cancel(); } } }
public MainWindow() { proxyServer = new ProxyServer(); //proxyServer.EnableHttp2 = true; //proxyServer.CertificateManager.CertificateEngine = CertificateEngine.DefaultWindows; ////Set a password for the .pfx file //proxyServer.CertificateManager.PfxPassword = "******"; ////Set Name(path) of the Root certificate file //proxyServer.CertificateManager.PfxFilePath = @"C:\NameFolder\rootCert.pfx"; ////do you want Replace an existing Root certificate file(.pfx) if password is incorrect(RootCertificate=null)? yes====>true //proxyServer.CertificateManager.OverwritePfxFile = true; ////save all fake certificates in folder "crts"(will be created in proxy dll directory) ////if create new Root certificate file(.pfx) ====> delete folder "crts" //proxyServer.CertificateManager.SaveFakeCertificates = true; proxyServer.ForwardToUpstreamGateway = true; //increase the ThreadPool (for server prod) //proxyServer.ThreadPoolWorkerThread = Environment.ProcessorCount * 6; proxyServer.CertificateManager.CertificateEngine = Network.CertificateEngine.BouncyCastleFast; ////if you need Load or Create Certificate now. ////// "true" if you need Enable===> Trust the RootCertificate used by this proxy server proxyServer.CertificateManager.EnsureRootCertificate(); ////or load directly certificate(As Administrator if need this) ////and At the same time chose path and password ////if password is incorrect and (overwriteRootCert=true)(RootCertificate=null) ====> replace an existing .pfx file ////note : load now (if existed) //proxyServer.CertificateManager.LoadRootCertificate(@"C:\NameFolder\rootCert.pfx", "PfxPassword"); //var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true); //proxyServer.AddEndPoint(explicitEndPoint); var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 443, true) { GenericCertificateName = "baidu.com", }; proxyServer.AddEndPoint(transparentEndPoint); //proxyServer.UpStreamHttpProxy = new ExternalProxy //{ // HostName = "158.69.115.45", // Port = 3128, // UserName = "******", // Password = "******", //}; //var socksEndPoint = new SocksProxyEndPoint(IPAddress.Any, 1080, true) //{ // // Generic Certificate hostname to use // // When SNI is disabled by client // //GenericCertificateName = "google.com" //}; //proxyServer.AddEndPoint(socksEndPoint); proxyServer.BeforeRequest += ProxyServer_BeforeRequest; proxyServer.BeforeResponse += ProxyServer_BeforeResponse; proxyServer.AfterResponse += ProxyServer_AfterResponse; //explicitEndPoint.BeforeTunnelConnectRequest += ProxyServer_BeforeTunnelConnectRequest; //explicitEndPoint.BeforeTunnelConnectResponse += ProxyServer_BeforeTunnelConnectResponse; proxyServer.ClientConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ClientConnectionCount = proxyServer.ClientConnectionCount; }); }; proxyServer.ServerConnectionCountChanged += delegate { Dispatcher.Invoke(() => { ServerConnectionCount = proxyServer.ServerConnectionCount; }); }; proxyServer.Start(); //proxyServer.SetAsSystemProxy(explicitEndPoint, ProxyProtocolType.AllHttp); InitializeComponent(); }
/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server). /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint">The transparent endpoint.</param> /// <param name="clientConnection">The client connection.</param> /// <returns></returns> private async Task handleClient(TransparentProxyEndPoint endPoint, TcpClientConnection clientConnection) { var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; var clientStream = new HttpClientStream(clientConnection.GetStream(), BufferPool); SslStream?sslStream = null; try { var clientHelloInfo = await SslTools.PeekClientHello(clientStream, BufferPool, cancellationToken); string?httpsHostName = null; if (clientHelloInfo != null) { httpsHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName; var args = new BeforeSslAuthenticateEventArgs(cancellationTokenSource, httpsHostName); await endPoint.InvokeBeforeSslAuthenticate(this, args, ExceptionFunc); if (cancellationTokenSource.IsCancellationRequested) { throw new Exception("Session was terminated by user."); } if (endPoint.DecryptSsl && args.DecryptSsl) { clientConnection.SslProtocol = clientHelloInfo.SslProtocol; // do client authentication using certificate X509Certificate2?certificate = null; try { sslStream = new SslStream(clientStream, false); string certName = HttpHelper.GetWildCardDomainName(httpsHostName); certificate = endPoint.GenericCertificate ?? await CertificateManager.CreateServerCertificate(certName); // Successfully managed to authenticate the client using the certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); // HTTPS server created - we can now decrypt the client's traffic clientStream = new HttpClientStream(sslStream, BufferPool); sslStream = null; // clientStream was created, no need to keep SSL stream reference } catch (Exception e) { var certName = certificate?.GetNameInfo(X509NameType.SimpleName, false); var session = new SessionEventArgs(this, endPoint, clientConnection, clientStream, null, cancellationTokenSource); throw new ProxyConnectException( $"Couldn't authenticate host '{httpsHostName}' with certificate '{certName}'.", e, session); } } else { var connection = await tcpConnectionFactory.GetServerConnection(httpsHostName, endPoint.Port, HttpHeader.VersionUnknown, false, null, true, this, null, UpStreamEndPoint, UpStreamHttpsProxy, true, cancellationToken); try { int available = clientStream.Available; if (available > 0) { // send the buffered data var data = BufferPool.GetBuffer(); try { // clientStream.Available should be at most BufferSize because it is using the same buffer size await clientStream.ReadAsync(data, 0, available, cancellationToken); await connection.Stream.WriteAsync(data, 0, available, true, cancellationToken); } finally { BufferPool.ReturnBuffer(data); } } if (!clientStream.IsClosed && !connection.Stream.IsClosed) { await TcpHelper.SendRaw(clientStream, connection.Stream, BufferPool, null, null, cancellationTokenSource, ExceptionFunc); } } finally { await tcpConnectionFactory.Release(connection, true); } return; } } // HTTPS server created - we can now decrypt the client's traffic // Now create the request await handleHttpSessionRequest(endPoint, clientConnection, clientStream, cancellationTokenSource); } catch (ProxyException e) { onException(clientStream, e); } catch (IOException e) { onException(clientStream, new Exception("Connection was aborted", e)); } catch (SocketException e) { onException(clientStream, new Exception("Could not connect", e)); } catch (Exception e) { onException(clientStream, new Exception("Error occured in whilst handling the client", e)); } finally { sslStream?.Dispose(); clientStream.Dispose(); } }
/// <summary> /// This is called when this proxy acts as a reverse proxy (like a real http server). /// So for HTTPS requests we would start SSL negotiation right away without expecting a CONNECT request from client /// </summary> /// <param name="endPoint">The transparent endpoint.</param> /// <param name="clientConnection">The client connection.</param> /// <returns></returns> private async Task HandleClient(TransparentProxyEndPoint endPoint, TcpClientConnection clientConnection) { var cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = cancellationTokenSource.Token; var clientStream = new CustomBufferedStream(clientConnection.GetStream(), BufferSize); var clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize); try { var clientHelloInfo = await SslTools.PeekClientHello(clientStream, cancellationToken); bool isHttps = clientHelloInfo != null; string httpsHostName = null; if (isHttps) { httpsHostName = clientHelloInfo.GetServerName() ?? endPoint.GenericCertificateName; var args = new BeforeSslAuthenticateEventArgs(cancellationTokenSource) { SniHostName = httpsHostName }; await endPoint.InvokeBeforeSslAuthenticate(this, args, ExceptionFunc); if (cancellationTokenSource.IsCancellationRequested) { throw new Exception("Session was terminated by user."); } if (endPoint.DecryptSsl && args.DecryptSsl) { SslStream sslStream = null; try { sslStream = new SslStream(clientStream); string certName = HttpHelper.GetWildCardDomainName(httpsHostName); var certificate = await CertificateManager.CreateCertificateAsync(certName); // Successfully managed to authenticate the client using the fake certificate await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls, false); // HTTPS server created - we can now decrypt the client's traffic clientStream = new CustomBufferedStream(sslStream, BufferSize); clientStreamWriter = new HttpResponseWriter(clientStream, BufferSize); } catch (Exception e) { sslStream?.Dispose(); throw new ProxyConnectException( $"Could'nt authenticate client '{httpsHostName}' with fake certificate.", e, null); } } else { // create new connection var connection = await tcpConnectionFactory.GetClient(httpsHostName, endPoint.Port, null, false, null, true, this, UpStreamEndPoint, UpStreamHttpsProxy, cancellationToken); var serverStream = connection.Stream; int available = clientStream.Available; if (available > 0) { // send the buffered data var data = BufferPool.GetBuffer(BufferSize); try { // clientStream.Available sbould be at most BufferSize because it is using the same buffer size await clientStream.ReadAsync(data, 0, available, cancellationToken); await serverStream.WriteAsync(data, 0, available, cancellationToken); await serverStream.FlushAsync(cancellationToken); } finally { BufferPool.ReturnBuffer(data); } } await TcpHelper.SendRaw(clientStream, serverStream, BufferSize, null, null, cancellationTokenSource, ExceptionFunc); tcpConnectionFactory.Release(connection, true); return; } } // HTTPS server created - we can now decrypt the client's traffic // Now create the request await HandleHttpSessionRequest(endPoint, clientConnection, clientStream, clientStreamWriter, cancellationTokenSource, isHttps?httpsHostName : null, null); } catch (ProxyException e) { OnException(clientStream, e); } catch (IOException e) { OnException(clientStream, new Exception("Connection was aborted", e)); } catch (SocketException e) { OnException(clientStream, new Exception("Could not connect", e)); } catch (Exception e) { OnException(clientStream, new Exception("Error occured in whilst handling the client", e)); } finally { clientStream.Dispose(); if (!cancellationTokenSource.IsCancellationRequested) { cancellationTokenSource.Cancel(); } } }
public bool StartProxy(bool IsProxyGOG = false) { if (!IsCertificateInstalled(proxyServer.CertificateManager.RootCertificate)) { var isOk = SetupCertificate(); if (!isOk) { return(false); } } if (PortInUse(443)) { return(false); } if (IsProxyGOG) { WirtePemCertificateToGoGSteamPlugins(); } #region 写入Hosts var hosts = new List <(string, string)>(); foreach (var proxyDomain in ProxyDomains) { if (proxyDomain.IsEnable) { foreach (var host in proxyDomain.Hosts) { hosts.Add((IPAddress.Loopback.ToString(), host)); } } } hostsService.UpdateHosts(hosts); #endregion #region 启动代理 proxyServer.BeforeRequest += OnRequest; proxyServer.BeforeResponse += OnResponse; //proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; //proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; //var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 443, true) //{ // // 在所有https请求上使用自颁发的通用证书 // // 通过不为每个启用http的域创建证书来优化性能 // // 当代理客户端不需要证书信任时非常有用 // //GenericCertificate = new X509Certificate2(Path.Combine(AppContext.BaseDirectory, "genericcert.pfx"), "password") //}; //当接收到连接请求时触发 //explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelRequest; //explicit endpoint 是客户端知道代理存在的地方 //因此,客户端以代理友好的方式发送请求 //proxyServer.AddEndPoint(explicitEndPoint); // 透明endpoint 对于反向代理很有用(客户端不知道代理的存在) // 透明endpoint 通常需要一个网络路由器端口来转发HTTP(S)包或DNS // 发送数据到此endpoint var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 443, true) { //GenericCertificate = proxyServer.CertificateManager.RootCertificate //GenericCertificateName= "steamcommunity-a.akamaihd.net" }; proxyServer.AddEndPoint(transparentEndPoint); try { proxyServer.Start(); } catch (Exception ex) { Logger.Error(ex); return(false); } //proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; //proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 }; #endregion #if DEBUG foreach (var endPoint in proxyServer.ProxyEndPoints) { Debug.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); } #endif return(true); }