windows增加git协议的代理支持

This commit is contained in:
陈国伟 2021-11-23 16:22:30 +08:00
parent e308612b3f
commit 9e559c36fe
8 changed files with 138 additions and 31 deletions

View File

@ -15,6 +15,11 @@ namespace FastGithub.Configuration
/// </summary>
public static int Ssh { get; }
/// <summary>
/// git端口
/// </summary>
public static int Git { get; }
/// <summary>
/// http端口
/// </summary>
@ -31,7 +36,8 @@ namespace FastGithub.Configuration
static ReverseProxyPort()
{
var ports = new TcpListenerPortCollection();
Ssh = OperatingSystem.IsWindows() ? ports.GetAvailablePort(22) : ports.GetAvailablePort(3822);
Ssh = ports.GetAvailablePort(22);
Git = ports.GetAvailablePort(9418);
Http = OperatingSystem.IsWindows() ? ports.GetAvailablePort(80) : ports.GetAvailablePort(3880);
Https = OperatingSystem.IsWindows() ? ports.GetAvailablePort(443) : ports.GetAvailablePort(38443);
}

View File

@ -0,0 +1,19 @@
using FastGithub.DomainResolve;
namespace FastGithub.HttpServer
{
/// <summary>
/// github的git代理处理者
/// </summary>
sealed class GitReverseProxyHandler : TcpReverseProxyHandler
{
/// <summary>
/// github的git代理处理者
/// </summary>
/// <param name="domainResolver"></param>
public GitReverseProxyHandler(IDomainResolver domainResolver)
: base(domainResolver, new("github.com", 9418))
{
}
}
}

View File

@ -60,10 +60,23 @@ namespace FastGithub
listen.UseConnectionHandler<SshReverseProxyHandler>();
});
if (OperatingSystem.IsWindows())
kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort}github的ssh反向代理服务启动完成");
}
/// <summary>
/// 尝试监听git反向代理
/// </summary>
/// <param name="kestrel"></param>
public static void ListenGitReverseProxy(this KestrelServerOptions kestrel)
{
var gitPort = ReverseProxyPort.Git;
kestrel.ListenLocalhost(gitPort, listen =>
{
kestrel.GetLogger().LogInformation($"已监听ssh://localhost:{sshPort}github的ssh反向代理服务启动完成");
}
listen.UseFlowAnalyze();
listen.UseConnectionHandler<GitReverseProxyHandler>();
});
kestrel.GetLogger().LogInformation($"已监听git://localhost:{gitPort}github的git反向代理服务启动完成");
}
/// <summary>

View File

@ -1,44 +1,19 @@
using FastGithub.DomainResolve;
using Microsoft.AspNetCore.Connections;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace FastGithub.HttpServer
{
/// <summary>
/// github的ssh代理处理者
/// </summary>
sealed class SshReverseProxyHandler : ConnectionHandler
sealed class SshReverseProxyHandler : TcpReverseProxyHandler
{
private readonly IDomainResolver domainResolver;
private readonly DnsEndPoint sshOverHttpsEndPoint = new("ssh.github.com", 443);
/// <summary>
/// github的ssh代理处理者
/// </summary>
/// <param name="domainResolver"></param>
public SshReverseProxyHandler(IDomainResolver domainResolver)
: base(domainResolver, new("ssh.github.com", 443))
{
this.domainResolver = domainResolver;
}
/// <summary>
/// ssh连接后
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task OnConnectedAsync(ConnectionContext context)
{
var address = await this.domainResolver.ResolveAnyAsync(this.sshOverHttpsEndPoint);
using var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(address, this.sshOverHttpsEndPoint.Port);
var targetStream = new NetworkStream(socket, ownsSocket: false);
var task1 = targetStream.CopyToAsync(context.Transport.Output);
var task2 = context.Transport.Input.CopyToAsync(targetStream);
await Task.WhenAny(task1, task2);
}
}
}

View File

@ -0,0 +1,70 @@
using FastGithub.DomainResolve;
using Microsoft.AspNetCore.Connections;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace FastGithub.HttpServer
{
/// <summary>
/// tcp反射代理处理者
/// </summary>
abstract class TcpReverseProxyHandler : ConnectionHandler
{
private readonly IDomainResolver domainResolver;
private readonly DnsEndPoint endPoint;
/// <summary>
/// tcp反射代理处理者
/// </summary>
/// <param name="domainResolver"></param>
/// <param name="endPoint"></param>
public TcpReverseProxyHandler(IDomainResolver domainResolver, DnsEndPoint endPoint)
{
this.domainResolver = domainResolver;
this.endPoint = endPoint;
}
/// <summary>
/// ssh连接后
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task OnConnectedAsync(ConnectionContext context)
{
var targetStream = await this.CreateConnectionAsync();
var task1 = targetStream.CopyToAsync(context.Transport.Output);
var task2 = context.Transport.Input.CopyToAsync(targetStream);
await Task.WhenAny(task1, task2);
}
/// <summary>
/// 创建连接
/// </summary>
/// <returns></returns>
/// <exception cref="AggregateException"></exception>
private async Task<Stream> CreateConnectionAsync()
{
var innerExceptions = new List<Exception>();
await foreach (var address in this.domainResolver.ResolveAllAsync(this.endPoint))
{
var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
await socket.ConnectAsync(address, this.endPoint.Port);
return new NetworkStream(socket, ownsSocket: false);
}
catch (Exception ex)
{
socket.Dispose();
innerExceptions.Add(ex);
}
}
throw new AggregateException($"无法连接到{this.endPoint.Host}:{this.endPoint.Port}", innerExceptions);
}
}
}

View File

@ -26,6 +26,7 @@ namespace FastGithub
services.AddHostedService<DnsInterceptHostedService>();
services.AddSingleton<ITcpInterceptor, SshInterceptor>();
services.AddSingleton<ITcpInterceptor, GitInterceptor>();
services.AddSingleton<ITcpInterceptor, HttpInterceptor>();
services.AddSingleton<ITcpInterceptor, HttpsInterceptor>();
services.AddHostedService<TcpInterceptHostedService>();

View File

@ -0,0 +1,22 @@
using FastGithub.Configuration;
using Microsoft.Extensions.Logging;
using System.Runtime.Versioning;
namespace FastGithub.PacketIntercept.Tcp
{
/// <summary>
/// git拦截器
/// </summary>
[SupportedOSPlatform("windows")]
sealed class GitInterceptor : TcpInterceptor
{
/// <summary>
/// git拦截器
/// </summary>
/// <param name="logger"></param>
public GitInterceptor(ILogger<HttpInterceptor> logger)
: base(9418, ReverseProxyPort.Git, logger)
{
}
}
}

View File

@ -72,6 +72,7 @@ namespace FastGithub
if (OperatingSystem.IsWindows())
{
kestrel.ListenSshReverseProxy();
kestrel.ListenGitReverseProxy();
}
else
{