/// <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));
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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");
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        //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);
        }
Ejemplo n.º 10
0
        //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);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        /// <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);
        }
Ejemplo n.º 15
0
        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");
        }
Ejemplo n.º 18
0
        /// <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);
                }
            }
        }
Ejemplo n.º 19
0
        /// <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();
                }
            }
        }
Ejemplo n.º 24
0
        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);
        }