mirror of
https://github.com/FastTunnel/FastTunnel.git
synced 2025-02-08 02:39:29 +08:00
新增特性:ssh访问内网主机
This commit is contained in:
parent
95b91548ef
commit
60ed66e961
|
@ -9,6 +9,8 @@
|
|||
"ClientSettings": {
|
||||
"Common": {
|
||||
// 服务端公网ip, 对应服务端配置文件的 BindAddr
|
||||
// "ServerAddr": "144.202.109.110",
|
||||
|
||||
"ServerAddr": "127.0.0.1",
|
||||
|
||||
// 服务端通信端口,对应服务端配置文件的 BindPort
|
||||
|
@ -23,17 +25,30 @@
|
|||
"LocalPort": 80,
|
||||
|
||||
// 子域名, 访问本站点时的url为 http://{SubDomain}.{Domain}:{ProxyPort_HTTP}/
|
||||
"SubDomain": "yz"
|
||||
},
|
||||
{
|
||||
"LocalIp": "127.0.0.1",
|
||||
"LocalPort": 80,
|
||||
"SubDomain": "test"
|
||||
},
|
||||
{
|
||||
"LocalIp": "127.0.0.1",
|
||||
"LocalPort": 80,
|
||||
"SubDomain": "test1"
|
||||
},
|
||||
"SubDomain": "tgjmini"
|
||||
}
|
||||
],
|
||||
|
||||
/**
|
||||
* ssh穿透,ssh访问内网主机
|
||||
* 访问方式 #ssh -oPort=12701 {root}@{ServerAddr}
|
||||
* ServerAddr 填入服务端ip,root对应内网用户名
|
||||
*/
|
||||
"SSH": [
|
||||
{
|
||||
"LocalIp": "127.0.0.1",
|
||||
"LocalPort": 80,
|
||||
"SubDomain": "test2"
|
||||
"LocalPort": 22,
|
||||
"RemotePort": 12701
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace FastTunnel.Core.Client
|
|||
connecter.Connect();
|
||||
|
||||
// 登录
|
||||
connecter.Send(new Message<LogInRequest> { MessageType = MessageType.C_LogIn, Content = new LogInRequest { WebList = _clientConfig.Webs } });
|
||||
connecter.Send(new Message<LogInRequest> { MessageType = MessageType.C_LogIn, Content = new LogInRequest { ClientConfig = _clientConfig } });
|
||||
|
||||
_logger.Debug("登录成功");
|
||||
ReceiveServer(connecter.Client);
|
||||
|
@ -108,14 +108,25 @@ namespace FastTunnel.Core.Client
|
|||
var request = (Msg.Content as JObject).ToObject<NewCustomerRequest>();
|
||||
var connecter = new Connecter(_clientConfig.Common.ServerAddr, _clientConfig.Common.ServerPort);
|
||||
connecter.Connect();
|
||||
connecter.Send(new Message<string> { MessageType = MessageType.C_NewRequest, Content = request.MsgId });
|
||||
connecter.Send(new Message<string> { MessageType = MessageType.C_SwapMsg, Content = request.MsgId });
|
||||
|
||||
var localConnecter = new Connecter(request.WebConfig.LocalIp, request.WebConfig.LocalPort);
|
||||
localConnecter.Connect();
|
||||
|
||||
new SocketSwap(connecter.Client, localConnecter.Client).StartSwap();
|
||||
break;
|
||||
case MessageType.C_NewRequest:
|
||||
case MessageType.S_NewSSH:
|
||||
var request_ssh = (Msg.Content as JObject).ToObject<NewSSHRequest>();
|
||||
var connecter_ssh = new Connecter(_clientConfig.Common.ServerAddr, _clientConfig.Common.ServerPort);
|
||||
connecter_ssh.Connect();
|
||||
connecter_ssh.Send(new Message<string> { MessageType = MessageType.C_SwapMsg, Content = request_ssh.MsgId });
|
||||
|
||||
var localConnecter_ssh = new Connecter(request_ssh.SSHConfig.LocalIp, request_ssh.SSHConfig.LocalPort);
|
||||
localConnecter_ssh.Connect();
|
||||
|
||||
new SocketSwap(connecter_ssh.Client, localConnecter_ssh.Client).StartSwap();
|
||||
break;
|
||||
case MessageType.C_SwapMsg:
|
||||
case MessageType.C_LogIn:
|
||||
default:
|
||||
throw new Exception("参数异常");
|
||||
|
|
|
@ -10,6 +10,8 @@ namespace FastTunnel.Core.Config
|
|||
public ServerCommon Common { get; set; }
|
||||
|
||||
public IEnumerable<WebConfig> Webs { get; set; }
|
||||
|
||||
public IEnumerable<SSHConfig> SSH { get; set; }
|
||||
}
|
||||
|
||||
public class ServerCommon
|
||||
|
|
|
@ -7,26 +7,26 @@ using System.Threading;
|
|||
|
||||
namespace FastTunnel.Core
|
||||
{
|
||||
public class Listener
|
||||
public class Listener<T>
|
||||
{
|
||||
private string _ip;
|
||||
private int _port;
|
||||
Action<Socket> handler;
|
||||
Action<Socket, T> handler;
|
||||
Socket socket;
|
||||
T _data;
|
||||
|
||||
public Listener(string ip, int port, Action<Socket> acceptCustomerHandler)
|
||||
public Listener(string ip, int port, Action<Socket, T> acceptCustomerHandler, T data)
|
||||
{
|
||||
_data = data;
|
||||
this._ip = ip;
|
||||
this._port = port;
|
||||
handler = acceptCustomerHandler;
|
||||
|
||||
|
||||
IPAddress ipa = IPAddress.Parse(_ip);
|
||||
IPEndPoint ipe = new IPEndPoint(ipa, _port);
|
||||
|
||||
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
socket.Bind(ipe);
|
||||
|
||||
}
|
||||
|
||||
public void Listen()
|
||||
|
@ -50,7 +50,7 @@ namespace FastTunnel.Core
|
|||
private void ReceiveCustomer(object state)
|
||||
{
|
||||
var client = state as Socket;
|
||||
handler.Invoke(client);
|
||||
handler.Invoke(client, _data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using FastTunnel.Core.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
@ -6,6 +7,6 @@ namespace FastTunnel.Core.Models
|
|||
{
|
||||
public class LogInRequest
|
||||
{
|
||||
public IEnumerable<WebConfig> WebList { get; set; }
|
||||
public ClientConfig ClientConfig { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,10 @@ namespace FastTunnel.Core.Models
|
|||
// client use below
|
||||
C_LogIn,
|
||||
C_Heart,
|
||||
C_NewRequest,
|
||||
C_SwapMsg,
|
||||
|
||||
// server use below
|
||||
S_NewCustomer,
|
||||
S_NewSSH,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace FastTunnel.Core.Server
|
|||
public class FastTunnelServer
|
||||
{
|
||||
Dictionary<string, WebInfo> WebList = new Dictionary<string, WebInfo>();
|
||||
Dictionary<int, SSHInfo<SSHHandlerArg>> SSHList = new Dictionary<int, SSHInfo<SSHHandlerArg>>();
|
||||
Dictionary<string, NewRequest> newRequest = new Dictionary<string, NewRequest>();
|
||||
|
||||
private ServerConfig serverSettings;
|
||||
|
@ -37,23 +38,22 @@ namespace FastTunnel.Core.Server
|
|||
|
||||
private void ListenFastTunnelClient()
|
||||
{
|
||||
var listener = new Listener(serverSettings.BindAddr, serverSettings.BindPort, ReceiveClient);
|
||||
var listener = new Listener<object>(serverSettings.BindAddr, serverSettings.BindPort, ReceiveClient, null);
|
||||
listener.Listen();
|
||||
_logger.Debug($"监听客户端 -> {serverSettings.BindAddr}:{serverSettings.BindPort}");
|
||||
}
|
||||
|
||||
private void ListenCustomer()
|
||||
{
|
||||
var listener = new Listener(serverSettings.BindAddr, serverSettings.ProxyPort_HTTP, ReceiveCustomer);
|
||||
var listener = new Listener<object>(serverSettings.BindAddr, serverSettings.ProxyPort_HTTP, ReceiveCustomer, null);
|
||||
listener.Listen();
|
||||
|
||||
_logger.Debug($"监听HTTP -> {serverSettings.BindAddr}:{serverSettings.ProxyPort_HTTP}");
|
||||
}
|
||||
|
||||
//接收消息
|
||||
void ReceiveCustomer(object o)
|
||||
void ReceiveCustomer(Socket client, object _)
|
||||
{
|
||||
Socket client = o as Socket;
|
||||
_logger.Debug("新的HTTP请求");
|
||||
|
||||
try
|
||||
|
@ -132,13 +132,12 @@ namespace FastTunnel.Core.Server
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
_logger.Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceiveClient(object obj)
|
||||
private void ReceiveClient(Socket client, object _)
|
||||
{
|
||||
Socket client = obj as Socket;
|
||||
//定义byte数组存放从客户端接收过来的数据
|
||||
byte[] buffer = new byte[1024 * 1024];
|
||||
|
||||
|
@ -156,7 +155,7 @@ namespace FastTunnel.Core.Server
|
|||
return;
|
||||
}
|
||||
|
||||
//将字节转换成字符串
|
||||
// 将字节转换成字符串
|
||||
string words = Encoding.UTF8.GetString(buffer, 0, length);
|
||||
var msg = JsonConvert.DeserializeObject<Message<object>>(words);
|
||||
|
||||
|
@ -165,9 +164,9 @@ namespace FastTunnel.Core.Server
|
|||
{
|
||||
case MessageType.C_LogIn:
|
||||
var requet = (msg.Content as JObject).ToObject<LogInRequest>();
|
||||
if (requet.WebList != null && requet.WebList.Count() > 0)
|
||||
if (requet.ClientConfig.Webs != null && requet.ClientConfig.Webs.Count() > 0)
|
||||
{
|
||||
foreach (var item in requet.WebList)
|
||||
foreach (var item in requet.ClientConfig.Webs)
|
||||
{
|
||||
var key = $"{item.SubDomain}.{serverSettings.Domain}".Trim();
|
||||
if (WebList.ContainsKey(key))
|
||||
|
@ -184,26 +183,52 @@ namespace FastTunnel.Core.Server
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (requet.ClientConfig.SSH != null && requet.ClientConfig.SSH.Count() > 0)
|
||||
{
|
||||
foreach (var item in requet.ClientConfig.SSH)
|
||||
{
|
||||
if (SSHList.ContainsKey(item.RemotePort))
|
||||
SSHList.Remove(item.RemotePort);
|
||||
|
||||
try
|
||||
{
|
||||
var ls = new Listener<SSHHandlerArg>("0.0.0.0", item.RemotePort, SSHHandler, new SSHHandlerArg { LocalClient = client, SSHConfig = item });
|
||||
ls.Listen();
|
||||
|
||||
// listen success
|
||||
SSHList.Add(item.RemotePort, new SSHInfo<SSHHandlerArg> { Listener = ls, Socket = client, SSHConfig = item });
|
||||
_logger.Debug($"SSH proxy success on {item.RemotePort} -> {item.LocalIp}:{item.LocalPort}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error($"SSH proxy error on {item.RemotePort} -> {item.LocalIp}:{item.LocalPort}");
|
||||
_logger.Error(ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MessageType.C_Heart:
|
||||
break;
|
||||
case MessageType.C_NewRequest:
|
||||
case MessageType.C_SwapMsg:
|
||||
var msgId = (msg.Content as string);
|
||||
NewRequest request;
|
||||
if (newRequest.TryGetValue(msgId, out request))
|
||||
|
||||
if (!string.IsNullOrEmpty(msgId) && newRequest.TryGetValue(msgId, out request))
|
||||
{
|
||||
// Join
|
||||
Task.Run(() =>
|
||||
{
|
||||
(new SocketSwap(request.CustomerClient, client))
|
||||
.BeforeSwap(() => { client.Send(request.Buffer); })
|
||||
.BeforeSwap(() => { if (request.Buffer != null) client.Send(request.Buffer); })
|
||||
.StartSwap();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// 未找到,关闭连接
|
||||
throw new Exception($"未找到请求:{msgId}");
|
||||
_logger.Error($"未找到请求:{msgId}");
|
||||
}
|
||||
break;
|
||||
case MessageType.S_NewCustomer:
|
||||
|
@ -211,5 +236,16 @@ namespace FastTunnel.Core.Server
|
|||
throw new Exception("参数异常");
|
||||
}
|
||||
}
|
||||
|
||||
private void SSHHandler(Socket client, SSHHandlerArg local)
|
||||
{
|
||||
var msgid = Guid.NewGuid().ToString();
|
||||
local.LocalClient.Send(new Message<NewSSHRequest> { MessageType = MessageType.S_NewSSH, Content = new NewSSHRequest { MsgId = msgid, SSHConfig = local.SSHConfig } });
|
||||
|
||||
newRequest.Add(msgid, new NewRequest
|
||||
{
|
||||
CustomerClient = client,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user