using Serilog; using System.Text.RegularExpressions; using Titanium.Web.Proxy; using Titanium.Web.Proxy.EventArguments; using Titanium.Web.Proxy.Models; namespace Elisa.GameServer; public class ProxyControl { static readonly Regex HostFilter = new Regex("(.*).(girlfrontline\\.co\\.kr|ppgame\\.com|txwy\\.tw|sunborngame\\.com|aihelp\\.net).*"); static readonly Regex AWSFilter = new Regex(@"s3.*.amazonaws.com"); static readonly Regex DLlistFilter = new Regex(@"dl.listdl.com"); readonly string forwardIpAddress; readonly ProxyServer proxyServer; readonly ExplicitProxyEndPoint explicitEndPoint; public ProxyControl(string forwardIpAddress, int port = 9000) { this.forwardIpAddress = forwardIpAddress; proxyServer = new ProxyServer(); explicitEndPoint = new ExplicitProxyEndPoint(System.Net.IPAddress.Any, port, true); proxyServer.BeforeRequest += OnRequest; //Ssl handling explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelConnectRequest; proxyServer.ServerCertificateValidationCallback += OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback += OnCertificateSelection; } public void Start() { proxyServer.AddEndPoint(explicitEndPoint); proxyServer.Start(); //proxyServer.SetAsSystemHttpProxy(explicitEndPoint); //proxyServer.SetAsSystemHttpsProxy(explicitEndPoint); } public void Stop() { proxyServer.BeforeRequest -= OnRequest; //Ssl Handling proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation; proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection; explicitEndPoint.BeforeTunnelConnectRequest -= OnBeforeTunnelConnectRequest; //proxyServer.DisableAllSystemProxies(); proxyServer.Stop(); } private async Task OnBeforeTunnelConnectRequest(object sender, TunnelConnectSessionEventArgs e) { string hostname = e.HttpClient.Request.RequestUri.Host; //show the hostname Log.Information($"Tunnel Connect Request for {hostname}"); //Forward to our domain --this doesn't work if (HostFilter.IsMatch(hostname) || AWSFilter.IsMatch(hostname) || DLlistFilter.IsMatch(hostname)) { Log.Information($"Forwarding tunnel connect request for {hostname} to {forwardIpAddress}"); e.DecryptSsl = true; e.HttpClient.Request.RequestUri = new Uri("https://" + forwardIpAddress + e.HttpClient.Request.RequestUri.PathAndQuery, UriKind.Absolute); return; } if (hostname.Contains("gf-passport.sunborngame.com")) { // Exclude Https addresses you don't want to proxy // Useful for clients that use certificate pinning // for example dropbox.com e.DecryptSsl = false; } } public Task OnCertificateValidation(object sender, CertificateValidationEventArgs e) { // set IsValid to true/false based on Certificate Errors //if (e.SslPolicyErrors == System.Net.Security.SslPolicyErrors.None) e.IsValid = true; return Task.CompletedTask; } // Allows overriding default client certificate selection logic during mutual authentication public Task OnCertificateSelection(object sender, CertificateSelectionEventArgs e) { // set e.clientCertificate to override return Task.CompletedTask; } private async Task OnRequest(object sender, SessionEventArgs e) { if (e.IsHttps) { Log.Information("HTTPS request detected, skipping"); return; } Uri requestUri = e.HttpClient.Request.RequestUri; if (HostFilter.IsMatch(requestUri.Host)) { Log.Information($"Forwarding request for {requestUri} to {forwardIpAddress}"); Uri newUri = new Uri("http://" + forwardIpAddress + requestUri.PathAndQuery, UriKind.Absolute); Log.Information($"Forwarded request to {newUri}"); e.HttpClient.Request.RequestUri = newUri; // Bubble it out to user } //Test for aws else if (AWSFilter.IsMatch(requestUri.Host)) { Log.Information($"Forwarding AWS request for {requestUri} to {forwardIpAddress}"); Uri newUri = new Uri("http://" + forwardIpAddress + requestUri.PathAndQuery, UriKind.Absolute); Log.Information($"Forwarded request to {newUri}"); e.HttpClient.Request.RequestUri = newUri; } else if (DLlistFilter.IsMatch(requestUri.Host)) { Log.Information($"Forwarding DLList request for {requestUri} to {forwardIpAddress}"); Uri newUri = new Uri("http://" + forwardIpAddress + requestUri.PathAndQuery, UriKind.Absolute); Log.Information($"Forwarded request to {newUri}"); e.HttpClient.Request.RequestUri = newUri; } } }