mirror of https://github.com/ehang-io/nps
parent
ade3bb0c71
commit
9bec5366a6
|
@ -1,3 +1,3 @@
|
|||
0,hostServer,,ts08z6vk5nc72fs8,aaa,bbb,,1,0
|
||||
0,hostServer,,7n7bxc2bm1fyjfab,a,b,,1,0
|
||||
8001,tunnelServer,127.0.0.1:88,jq5i7n0sjs1h0jje,aaa,bbb,,1,1
|
||||
8001,tunnelServer,127.0.0.1:88,jq5i7n0sjs1h0jje,aaa,bbb,,1,0,0,0,1
|
||||
0,hostServer,,ts08z6vk5nc72fs8,aaac,bbb,snappy,1,0,1,2,3
|
||||
0,hostServer,,7n7bxc2bm1fyjfab,ab,b,,1,1,1,0,1
|
||||
|
|
|
|
@ -43,10 +43,10 @@ func (s *IndexController) Host() {
|
|||
s.display("index/list")
|
||||
}
|
||||
|
||||
func (s *IndexController) GetTaskList() {
|
||||
func (s *IndexController) GetServerConfig() {
|
||||
start, length := s.GetAjaxParams()
|
||||
taskType := s.GetString("type")
|
||||
list, cnt := lib.CsvDb.GetTaskList(start, length, taskType)
|
||||
list, cnt := lib.CsvDb.GetServerConfig(start, length, taskType)
|
||||
s.AjaxTable(list, cnt, cnt)
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ func (s *IndexController) Add() {
|
|||
s.SetInfo("新增")
|
||||
s.display()
|
||||
} else {
|
||||
t := &lib.TaskList{
|
||||
t := &lib.ServerConfig{
|
||||
TcpPort: s.GetIntNoErr("port"),
|
||||
Mode: s.GetString("type"),
|
||||
Target: s.GetString("target"),
|
||||
|
@ -64,7 +64,8 @@ func (s *IndexController) Add() {
|
|||
U: s.GetString("u"),
|
||||
P: s.GetString("p"),
|
||||
Compress: s.GetString("compress"),
|
||||
Crypt: s.GetString("crypt"),
|
||||
Crypt: lib.GetBoolByStr(s.GetString("crypt")),
|
||||
Mux: lib.GetBoolByStr(s.GetString("mux")),
|
||||
IsRun: 0,
|
||||
}
|
||||
lib.CsvDb.NewTask(t)
|
||||
|
@ -97,7 +98,8 @@ func (s *IndexController) Edit() {
|
|||
t.U = s.GetString("u")
|
||||
t.P = s.GetString("p")
|
||||
t.Compress = s.GetString("compress")
|
||||
t.Crypt = s.GetString("crypt")
|
||||
t.Crypt = lib.GetBoolByStr(s.GetString("crypt"))
|
||||
t.Mux = lib.GetBoolByStr(s.GetString("mux"))
|
||||
lib.CsvDb.UpdateTask(t)
|
||||
lib.StopServer(t.VerifyKey)
|
||||
lib.StartTask(t.VerifyKey)
|
||||
|
|
|
@ -141,8 +141,8 @@ retry:
|
|||
}
|
||||
|
||||
//得到一个tcp隧道
|
||||
func (s *Tunnel) GetTunnel(cFlag string, en, de int, crypt bool) (c *Conn, err error) {
|
||||
if v, ok := s.tunnelList[cFlag]; !ok || v.Len() < 10 { //新建通道
|
||||
func (s *Tunnel) GetTunnel(cFlag string, en, de int, crypt, mux bool) (c *Conn, err error) {
|
||||
if v, ok := s.tunnelList[cFlag]; !ok || v.Len() < 3 { //新建通道
|
||||
go s.newChan(cFlag)
|
||||
}
|
||||
retry:
|
||||
|
@ -150,11 +150,11 @@ retry:
|
|||
return
|
||||
}
|
||||
c = s.tunnelList[cFlag].Pop()
|
||||
if _, err := c.wTest(); err != nil {
|
||||
if _, err = c.wTest(); err != nil {
|
||||
c.Close()
|
||||
goto retry
|
||||
}
|
||||
c.WriteConnInfo(en, de, crypt)
|
||||
c.WriteConnInfo(en, de, crypt, mux)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -175,6 +175,13 @@ func (s *Tunnel) ReturnSignal(conn *Conn, cFlag string) {
|
|||
}
|
||||
}
|
||||
|
||||
//重回slice 复用
|
||||
func (s *Tunnel) ReturnTunnel(conn *Conn, cFlag string) {
|
||||
if v, ok := s.tunnelList[cFlag]; ok {
|
||||
v.Add(conn)
|
||||
}
|
||||
}
|
||||
|
||||
//删除通信通道
|
||||
func (s *Tunnel) DelClientSignal(cFlag string) {
|
||||
s.delClient(cFlag, s.signalList)
|
|
@ -102,27 +102,43 @@ func (s *TRPClient) dealChan() error {
|
|||
c.SetAlive()
|
||||
//写标志
|
||||
c.wChan()
|
||||
re:
|
||||
//获取连接的host type(tcp or udp)
|
||||
typeStr, host, en, de, crypt, err := c.GetHostFromConn()
|
||||
typeStr, host, en, de, crypt, mux, err := c.GetHostFromConn()
|
||||
if err != nil {
|
||||
log.Println("get host info error:", err)
|
||||
return err
|
||||
}
|
||||
//与目标建立连接
|
||||
server, err := net.Dial(typeStr, host)
|
||||
//与目标建立连接,超时时间为3
|
||||
server, err := net.DialTimeout(typeStr, host, time.Second*3)
|
||||
if err != nil {
|
||||
log.Println("connect to ", host, "error:", err)
|
||||
log.Println("connect to ", host, "error:", err, mux)
|
||||
if mux {
|
||||
s.sendEof(conn, de, crypt)
|
||||
goto re
|
||||
}
|
||||
return err
|
||||
}
|
||||
go relay(NewConn(server), c, de, crypt)
|
||||
relay(c, NewConn(server), en, crypt)
|
||||
go relay(NewConn(server), c, de, crypt, mux)
|
||||
relay(c, NewConn(server), en, crypt, mux)
|
||||
if mux {
|
||||
goto re
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (s *TRPClient) sendEof(c net.Conn, de int, crypt bool) {
|
||||
switch de {
|
||||
case COMPRESS_SNAPY_DECODE:
|
||||
NewSnappyConn(c, crypt).Write([]byte(IO_EOF))
|
||||
case COMPRESS_NONE_DECODE:
|
||||
NewCryptConn(c, crypt).Write([]byte(IO_EOF))
|
||||
}
|
||||
}
|
||||
|
||||
//http模式处理
|
||||
func (s *TRPClient) dealHttp(c *Conn) error {
|
||||
buf := make([]byte, 1024*32)
|
||||
en, de, crypt := c.GetConnInfoFromConn()
|
||||
en, de, crypt, _ := c.GetConnInfoFromConn()
|
||||
n, err := c.ReadFrom(buf, de, crypt)
|
||||
if err != nil {
|
||||
c.wError()
|
||||
|
|
28
lib/conn.go
28
lib/conn.go
|
@ -45,6 +45,12 @@ func (s *CryptConn) Write(b []byte) (n int, err error) {
|
|||
|
||||
//解密读
|
||||
func (s *CryptConn) Read(b []byte) (n int, err error) {
|
||||
defer func() {
|
||||
if string(b[:n]) == IO_EOF {
|
||||
err = io.EOF
|
||||
n = 0
|
||||
}
|
||||
}()
|
||||
if s.crypt {
|
||||
var lens int
|
||||
var buf, bs []byte
|
||||
|
@ -62,7 +68,8 @@ func (s *CryptConn) Read(b []byte) (n int, err error) {
|
|||
copy(b, bs)
|
||||
return
|
||||
}
|
||||
return s.conn.Read(b)
|
||||
n, err = s.conn.Read(b)
|
||||
return
|
||||
}
|
||||
|
||||
type SnappyConn struct {
|
||||
|
@ -97,6 +104,12 @@ func (s *SnappyConn) Write(b []byte) (n int, err error) {
|
|||
|
||||
//snappy压缩读 包含解密
|
||||
func (s *SnappyConn) Read(b []byte) (n int, err error) {
|
||||
defer func() {
|
||||
if string(b[:n]) == IO_EOF {
|
||||
err = io.EOF
|
||||
n = 0
|
||||
}
|
||||
}()
|
||||
if n, err = s.r.Read(b); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -160,14 +173,14 @@ func (s *Conn) ReadFlag() (string, error) {
|
|||
}
|
||||
|
||||
//读取host 连接地址 压缩类型
|
||||
func (s *Conn) GetHostFromConn() (typeStr string, host string, en, de int, crypt bool, err error) {
|
||||
func (s *Conn) GetHostFromConn() (typeStr string, host string, en, de int, crypt, mux bool, err error) {
|
||||
retry:
|
||||
lType, err := s.ReadLen(3)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if typeStr = string(lType); typeStr == TEST_FLAG {
|
||||
en, de, crypt = s.GetConnInfoFromConn()
|
||||
en, de, crypt, mux = s.GetConnInfoFromConn()
|
||||
goto retry
|
||||
}
|
||||
cLen, err := s.GetLen()
|
||||
|
@ -245,13 +258,13 @@ func (s *Conn) WriteTo(b []byte, compress int, crypt bool) (n int, err error) {
|
|||
}
|
||||
|
||||
//写压缩方式,加密
|
||||
func (s *Conn) WriteConnInfo(en, de int, crypt bool) {
|
||||
s.Write([]byte(strconv.Itoa(en) + strconv.Itoa(de) + GetStrByBool(crypt)))
|
||||
func (s *Conn) WriteConnInfo(en, de int, crypt, mux bool) {
|
||||
s.Write([]byte(strconv.Itoa(en) + strconv.Itoa(de) + GetStrByBool(crypt) + GetStrByBool(mux)))
|
||||
}
|
||||
|
||||
//获取压缩方式,是否加密
|
||||
func (s *Conn) GetConnInfoFromConn() (en, de int, crypt bool) {
|
||||
buf, err := s.ReadLen(3)
|
||||
func (s *Conn) GetConnInfoFromConn() (en, de int, crypt, mux bool) {
|
||||
buf, err := s.ReadLen(4)
|
||||
//TODO:错误处理
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -259,6 +272,7 @@ func (s *Conn) GetConnInfoFromConn() (en, de int, crypt bool) {
|
|||
en, _ = strconv.Atoi(string(buf[0]))
|
||||
de, _ = strconv.Atoi(string(buf[1]))
|
||||
crypt = GetBoolByStr(string(buf[2]))
|
||||
mux = GetBoolByStr(string(buf[3]))
|
||||
return
|
||||
}
|
||||
|
||||
|
|
69
lib/file.go
69
lib/file.go
|
@ -10,18 +10,21 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
type TaskList struct {
|
||||
TcpPort int //服务端与客户端通信端口
|
||||
Mode string //启动方式
|
||||
Target string //目标
|
||||
VerifyKey string //flag
|
||||
U string //socks5验证用户名
|
||||
P string //socks5验证密码
|
||||
Compress string //压缩方式
|
||||
Start int //是否开启
|
||||
IsRun int //是否在运行
|
||||
ClientStatus int //客户端状态
|
||||
Crypt string //是否加密
|
||||
type ServerConfig struct {
|
||||
TcpPort int //服务端与客户端通信端口
|
||||
Mode string //启动方式
|
||||
Target string //目标
|
||||
VerifyKey string //flag
|
||||
U string //socks5验证用户名
|
||||
P string //socks5验证密码
|
||||
Compress string //压缩方式
|
||||
Start int //是否开启
|
||||
IsRun int //是否在运行
|
||||
ClientStatus int //客s户端状态
|
||||
Crypt bool //是否加密
|
||||
Mux bool //是否加密
|
||||
CompressEncode int
|
||||
CompressDecode int
|
||||
}
|
||||
|
||||
type HostList struct {
|
||||
|
@ -39,7 +42,7 @@ func NewCsv(path string, bridge *Tunnel, runList map[string]interface{}) *Csv {
|
|||
}
|
||||
|
||||
type Csv struct {
|
||||
Tasks []*TaskList
|
||||
Tasks []*ServerConfig
|
||||
Path string
|
||||
Bridge *Tunnel
|
||||
RunList map[string]interface{}
|
||||
|
@ -69,7 +72,10 @@ func (s *Csv) StoreTasksToCsv() {
|
|||
task.P,
|
||||
task.Compress,
|
||||
strconv.Itoa(task.Start),
|
||||
task.Crypt,
|
||||
GetStrByBool(task.Crypt),
|
||||
GetStrByBool(task.Mux),
|
||||
strconv.Itoa(task.CompressEncode),
|
||||
strconv.Itoa(task.CompressDecode),
|
||||
}
|
||||
err := writer.Write(record)
|
||||
if err != nil {
|
||||
|
@ -98,21 +104,24 @@ func (s *Csv) LoadTaskFromCsv() {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var tasks []*TaskList
|
||||
var tasks []*ServerConfig
|
||||
// 将每一行数据保存到内存slice中
|
||||
for _, item := range records {
|
||||
tcpPort, _ := strconv.Atoi(item[0])
|
||||
Start, _ := strconv.Atoi(item[7])
|
||||
post := &TaskList{
|
||||
TcpPort: tcpPort,
|
||||
Mode: item[1],
|
||||
Target: item[2],
|
||||
VerifyKey: item[3],
|
||||
U: item[4],
|
||||
P: item[5],
|
||||
Compress: item[6],
|
||||
Start: Start,
|
||||
Crypt: item[8],
|
||||
post := &ServerConfig{
|
||||
TcpPort: tcpPort,
|
||||
Mode: item[1],
|
||||
Target: item[2],
|
||||
VerifyKey: item[3],
|
||||
U: item[4],
|
||||
P: item[5],
|
||||
Compress: item[6],
|
||||
Start: Start,
|
||||
Crypt: GetBoolByStr(item[8]),
|
||||
Mux: GetBoolByStr(item[9]),
|
||||
CompressEncode: GetIntNoerrByStr(item[10]),
|
||||
CompressDecode: GetIntNoerrByStr(item[11]),
|
||||
}
|
||||
tasks = append(tasks, post)
|
||||
}
|
||||
|
@ -177,8 +186,8 @@ func (s *Csv) LoadHostFromCsv() {
|
|||
s.Hosts = hosts
|
||||
}
|
||||
|
||||
func (s *Csv) GetTaskList(start, length int, typeVal string) ([]*TaskList, int) {
|
||||
list := make([]*TaskList, 0)
|
||||
func (s *Csv) GetServerConfig(start, length int, typeVal string) ([]*ServerConfig, int) {
|
||||
list := make([]*ServerConfig, 0)
|
||||
var cnt int
|
||||
for _, v := range s.Tasks {
|
||||
if v.Mode != typeVal {
|
||||
|
@ -209,12 +218,12 @@ func (s *Csv) GetTaskList(start, length int, typeVal string) ([]*TaskList, int)
|
|||
return list, cnt
|
||||
}
|
||||
|
||||
func (s *Csv) NewTask(t *TaskList) {
|
||||
func (s *Csv) NewTask(t *ServerConfig) {
|
||||
s.Tasks = append(s.Tasks, t)
|
||||
s.StoreTasksToCsv()
|
||||
}
|
||||
|
||||
func (s *Csv) UpdateTask(t *TaskList) error {
|
||||
func (s *Csv) UpdateTask(t *ServerConfig) error {
|
||||
for k, v := range s.Tasks {
|
||||
if v.VerifyKey == t.VerifyKey {
|
||||
s.Tasks = append(s.Tasks[:k], s.Tasks[k+1:]...)
|
||||
|
@ -246,7 +255,7 @@ func (s *Csv) DelTask(vKey string) error {
|
|||
return errors.New("不存在")
|
||||
}
|
||||
|
||||
func (s *Csv) GetTask(vKey string) (v *TaskList, err error) {
|
||||
func (s *Csv) GetTask(vKey string) (v *ServerConfig, err error) {
|
||||
for _, v = range s.Tasks {
|
||||
if v.VerifyKey == vKey {
|
||||
return
|
||||
|
|
55
lib/init.go
55
lib/init.go
|
@ -16,11 +16,12 @@ var (
|
|||
rpMode = flag.String("mode", "client", "启动模式")
|
||||
tunnelTarget = flag.String("target", "10.1.50.203:80", "远程目标")
|
||||
verifyKey = flag.String("vkey", "", "验证密钥")
|
||||
u = flag.String("u", "", "socks5验证用户名")
|
||||
p = flag.String("p", "", "socks5验证密码")
|
||||
u = flag.String("u", "", "验证用户名(socks5和web)")
|
||||
p = flag.String("p", "", "验证密码(socks5和web)")
|
||||
compress = flag.String("compress", "", "数据压缩方式(snappy)")
|
||||
serverAddr = flag.String("server", "", "服务器地址ip:端口")
|
||||
crypt = flag.String("crypt", "", "是否加密(1|0)")
|
||||
crypt = flag.String("crypt", "false", "是否加密(true|false)")
|
||||
mux = flag.String("mux", "false", "是否TCP多路复用(true|false)")
|
||||
config Config
|
||||
err error
|
||||
RunList map[string]interface{} //运行中的任务
|
||||
|
@ -36,7 +37,6 @@ func init() {
|
|||
|
||||
func InitMode() {
|
||||
flag.Parse()
|
||||
de, en := getCompressType(*compress)
|
||||
if *rpMode == "client" {
|
||||
JsonParse := NewJsonStruct()
|
||||
if config, err = JsonParse.Load(*configPath); err != nil {
|
||||
|
@ -54,7 +54,25 @@ func InitMode() {
|
|||
log.Fatalln("服务端开启失败", err)
|
||||
}
|
||||
log.Println("服务端启动,监听tcp服务端端口:", *TcpPort)
|
||||
if svr := newMode(*rpMode, bridge, *httpPort, *tunnelTarget, *u, *p, en, de, *verifyKey, *crypt); svr != nil {
|
||||
cnf := ServerConfig{
|
||||
TcpPort: *httpPort,
|
||||
Mode: *rpMode,
|
||||
Target: *tunnelTarget,
|
||||
VerifyKey: *verifyKey,
|
||||
U: *u,
|
||||
P: *p,
|
||||
Compress: *compress,
|
||||
Start: 0,
|
||||
IsRun: 0,
|
||||
ClientStatus: 0,
|
||||
Crypt: GetBoolByStr(*crypt),
|
||||
Mux: GetBoolByStr(*mux),
|
||||
CompressEncode: 0,
|
||||
CompressDecode: 0,
|
||||
}
|
||||
cnf.CompressDecode, cnf.CompressEncode = getCompressType(cnf.Compress)
|
||||
if svr := newMode(bridge, &cnf);
|
||||
svr != nil {
|
||||
reflect.ValueOf(svr).MethodByName("Start").Call(nil)
|
||||
} else {
|
||||
log.Fatalln("启动模式不正确")
|
||||
|
@ -73,26 +91,25 @@ func InitFromCsv() {
|
|||
}
|
||||
}
|
||||
|
||||
func newMode(mode string, bridge *Tunnel, httpPort int, tunnelTarget string, u string, p string, enCompress int, deCompress int, vkey string, crypt string) interface{} {
|
||||
bCrypt := GetBoolByStr(crypt)
|
||||
switch mode {
|
||||
func newMode(bridge *Tunnel, config *ServerConfig) interface{} {
|
||||
switch config.Mode {
|
||||
case "httpServer":
|
||||
return NewHttpModeServer(httpPort, bridge, enCompress, deCompress, vkey, bCrypt)
|
||||
return NewHttpModeServer(bridge, config)
|
||||
case "tunnelServer":
|
||||
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessTunnel, bridge, enCompress, deCompress, vkey, u, p, bCrypt)
|
||||
case "sock5Server":
|
||||
return NewSock5ModeServer(httpPort, u, p, bridge, enCompress, deCompress, vkey, bCrypt)
|
||||
return NewTunnelModeServer(ProcessTunnel, bridge, config)
|
||||
case "socks5Server":
|
||||
return NewSock5ModeServer(bridge, config)
|
||||
case "httpProxyServer":
|
||||
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessHttp, bridge, enCompress, deCompress, vkey, u, p, bCrypt)
|
||||
return NewTunnelModeServer(ProcessHttp, bridge, config)
|
||||
case "udpServer":
|
||||
return NewUdpModeServer(httpPort, tunnelTarget, bridge, enCompress, deCompress, vkey, bCrypt)
|
||||
return NewUdpModeServer(bridge, config)
|
||||
case "webServer":
|
||||
InitCsvDb()
|
||||
return NewWebServer(bridge)
|
||||
case "hostServer":
|
||||
return NewHostServer(bCrypt)
|
||||
return NewHostServer(config)
|
||||
case "httpHostServer":
|
||||
return NewTunnelModeServer(httpPort, tunnelTarget, ProcessHost, bridge, enCompress, deCompress, vkey, u, p, bCrypt)
|
||||
return NewTunnelModeServer(ProcessHost, bridge, config)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -116,9 +133,9 @@ func StopServer(cFlag string) error {
|
|||
return errors.New("未在运行中")
|
||||
}
|
||||
|
||||
func AddTask(t *TaskList) error {
|
||||
de, en := getCompressType(t.Compress)
|
||||
if svr := newMode(t.Mode, bridge, t.TcpPort, t.Target, t.U, t.P, en, de, t.VerifyKey, t.Crypt); svr != nil {
|
||||
func AddTask(t *ServerConfig) error {
|
||||
t.CompressDecode, t.CompressEncode = getCompressType(t.Compress)
|
||||
if svr := newMode(bridge, t); svr != nil {
|
||||
RunList[t.VerifyKey] = svr
|
||||
go func() {
|
||||
err := reflect.ValueOf(svr).MethodByName("Start").Call(nil)[0]
|
||||
|
|
|
@ -44,16 +44,10 @@ const (
|
|||
)
|
||||
|
||||
type Sock5ModeServer struct {
|
||||
bridge *Tunnel
|
||||
httpPort int
|
||||
u string //用户名
|
||||
p string //密码
|
||||
enCompress int
|
||||
deCompress int
|
||||
isVerify bool
|
||||
listener net.Listener
|
||||
vKey string
|
||||
crypt bool
|
||||
bridge *Tunnel
|
||||
isVerify bool
|
||||
listener net.Listener
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
//req
|
||||
|
@ -140,10 +134,9 @@ func (s *Sock5ModeServer) doConnect(c net.Conn, command uint8) (proxyConn *Conn,
|
|||
binary.Read(c, binary.BigEndian, &port)
|
||||
// connect to host
|
||||
addr := net.JoinHostPort(host, strconv.Itoa(int(port)))
|
||||
client, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress, s.crypt)
|
||||
client, err := s.bridge.GetTunnel(getverifyval(s.config.VerifyKey), s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
client.Close()
|
||||
return
|
||||
}
|
||||
s.sendReply(c, succeeded)
|
||||
|
@ -164,8 +157,11 @@ func (s *Sock5ModeServer) handleConnect(c net.Conn) {
|
|||
log.Println(err)
|
||||
c.Close()
|
||||
} else {
|
||||
go relay(proxyConn, NewConn(c), s.enCompress, s.crypt)
|
||||
go relay(NewConn(c), proxyConn, s.deCompress, s.crypt)
|
||||
go relay(proxyConn, NewConn(c), s.config.CompressEncode, s.config.Crypt, s.config.Mux)
|
||||
relay(NewConn(c), proxyConn, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
|
||||
if s.config.Mux {
|
||||
s.bridge.ReturnTunnel(proxyConn, getverifyval(s.config.VerifyKey))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -198,8 +194,11 @@ func (s *Sock5ModeServer) handleUDP(c net.Conn) {
|
|||
if err != nil {
|
||||
c.Close()
|
||||
} else {
|
||||
go relay(proxyConn, NewConn(c), s.enCompress, s.crypt)
|
||||
go relay(NewConn(c), proxyConn, s.deCompress, s.crypt)
|
||||
go relay(proxyConn, NewConn(c), s.config.CompressEncode, s.config.Crypt, s.config.Mux)
|
||||
relay(NewConn(c), proxyConn, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
|
||||
if s.config.Mux {
|
||||
s.bridge.ReturnTunnel(proxyConn, getverifyval(s.config.VerifyKey))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +261,7 @@ func (s *Sock5ModeServer) Auth(c net.Conn) error {
|
|||
if _, err := io.ReadAtLeast(c, pass, passLen); err != nil {
|
||||
return err
|
||||
}
|
||||
if string(pass) == s.p && string(user) == s.u {
|
||||
if string(pass) == s.config.U && string(user) == s.config.P {
|
||||
if _, err := c.Write([]byte{userAuthVersion, authSuccess}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -278,7 +277,7 @@ func (s *Sock5ModeServer) Auth(c net.Conn) error {
|
|||
|
||||
//start
|
||||
func (s *Sock5ModeServer) Start() error {
|
||||
s.listener, err = net.Listen("tcp", ":"+strconv.Itoa(s.httpPort))
|
||||
s.listener, err = net.Listen("tcp", ":"+strconv.Itoa(s.config.TcpPort))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -301,20 +300,14 @@ func (s *Sock5ModeServer) Close() error {
|
|||
}
|
||||
|
||||
//new
|
||||
func NewSock5ModeServer(httpPort int, u, p string, brige *Tunnel, enCompress int, deCompress int, vKey string, crypt bool) *Sock5ModeServer {
|
||||
func NewSock5ModeServer(bridge *Tunnel, cnf *ServerConfig) *Sock5ModeServer {
|
||||
s := new(Sock5ModeServer)
|
||||
s.httpPort = httpPort
|
||||
s.bridge = brige
|
||||
if u != "" && p != "" {
|
||||
s.bridge = bridge
|
||||
s.config = cnf
|
||||
if s.config.U != "" && s.config.P != "" {
|
||||
s.isVerify = true
|
||||
s.u = u
|
||||
s.p = p
|
||||
} else {
|
||||
s.isVerify = false
|
||||
}
|
||||
s.enCompress = enCompress
|
||||
s.deCompress = deCompress
|
||||
s.vKey = vKey
|
||||
s.crypt = crypt
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -33,23 +33,15 @@ WWW-Authenticate: Basic realm="easyProxy"
|
|||
type process func(c *Conn, s *TunnelModeServer) error
|
||||
|
||||
type HttpModeServer struct {
|
||||
bridge *Tunnel
|
||||
httpPort int
|
||||
enCompress int
|
||||
deCompress int
|
||||
vKey string
|
||||
crypt bool
|
||||
bridge *Tunnel
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
//http
|
||||
func NewHttpModeServer(httpPort int, bridge *Tunnel, enCompress int, deCompress int, vKey string, crypt bool) *HttpModeServer {
|
||||
func NewHttpModeServer(bridge *Tunnel, cnf *ServerConfig) *HttpModeServer {
|
||||
s := new(HttpModeServer)
|
||||
s.bridge = bridge
|
||||
s.httpPort = httpPort
|
||||
s.enCompress = enCompress
|
||||
s.deCompress = deCompress
|
||||
s.vKey = vKey
|
||||
s.crypt = crypt
|
||||
s.config = cnf
|
||||
return s
|
||||
}
|
||||
|
||||
|
@ -65,7 +57,7 @@ func (s *HttpModeServer) Start() {
|
|||
w.Write([]byte("401 Unauthorized\n"))
|
||||
return
|
||||
}
|
||||
err, conn := s.bridge.GetSignal(getverifyval(s.vKey))
|
||||
err, conn := s.bridge.GetSignal(getverifyval(s.config.VerifyKey))
|
||||
if err != nil {
|
||||
BadRequest(w)
|
||||
return
|
||||
|
@ -83,9 +75,9 @@ func (s *HttpModeServer) Start() {
|
|||
goto retry
|
||||
return
|
||||
}
|
||||
s.bridge.ReturnSignal(conn, getverifyval(s.vKey))
|
||||
s.bridge.ReturnSignal(conn, getverifyval(s.config.VerifyKey))
|
||||
})
|
||||
log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%d", s.httpPort), nil))
|
||||
log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%d", s.config.TcpPort), nil))
|
||||
}
|
||||
|
||||
//req转为bytes发送给client端
|
||||
|
@ -95,8 +87,8 @@ func (s *HttpModeServer) writeRequest(r *http.Request, conn *Conn) error {
|
|||
return err
|
||||
}
|
||||
conn.wSign()
|
||||
conn.WriteConnInfo(s.enCompress, s.deCompress, s.crypt)
|
||||
c, err := conn.WriteTo(raw, s.enCompress, s.crypt)
|
||||
conn.WriteConnInfo(s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
|
||||
c, err := conn.WriteTo(raw, s.config.CompressEncode, s.config.Crypt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -115,7 +107,7 @@ func (s *HttpModeServer) writeResponse(w http.ResponseWriter, c *Conn) error {
|
|||
switch flags {
|
||||
case RES_SIGN:
|
||||
buf := make([]byte, 1024*1024*32)
|
||||
n, err := c.ReadFrom(buf, s.deCompress, s.crypt)
|
||||
n, err := c.ReadFrom(buf, s.config.CompressDecode, s.config.Crypt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -145,38 +137,24 @@ func (s *HttpModeServer) writeResponse(w http.ResponseWriter, c *Conn) error {
|
|||
}
|
||||
|
||||
type TunnelModeServer struct {
|
||||
httpPort int
|
||||
tunnelTarget string
|
||||
process process
|
||||
bridge *Tunnel
|
||||
listener *net.TCPListener
|
||||
enCompress int
|
||||
deCompress int
|
||||
basicUser string
|
||||
basicPassword string
|
||||
vKey string
|
||||
crypt bool
|
||||
process process
|
||||
bridge *Tunnel
|
||||
config *ServerConfig
|
||||
listener *net.TCPListener
|
||||
}
|
||||
|
||||
//tcp|http|host
|
||||
func NewTunnelModeServer(httpPort int, tunnelTarget string, process process, bridge *Tunnel, enCompress, deCompress int, vKey, basicUser, basicPasswd string, crypt bool) *TunnelModeServer {
|
||||
func NewTunnelModeServer(process process, bridge *Tunnel, cnf *ServerConfig) *TunnelModeServer {
|
||||
s := new(TunnelModeServer)
|
||||
s.httpPort = httpPort
|
||||
s.bridge = bridge
|
||||
s.tunnelTarget = tunnelTarget
|
||||
s.process = process
|
||||
s.enCompress = enCompress
|
||||
s.deCompress = deCompress
|
||||
s.vKey = vKey
|
||||
s.basicUser = basicUser
|
||||
s.basicPassword = basicPasswd
|
||||
s.crypt = crypt
|
||||
s.config = cnf
|
||||
return s
|
||||
}
|
||||
|
||||
//开始
|
||||
func (s *TunnelModeServer) Start() error {
|
||||
s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.httpPort, ""})
|
||||
s.listener, err = net.ListenTCP("tcp", &net.TCPAddr{net.ParseIP("0.0.0.0"), s.config.TcpPort, ""})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -205,14 +183,19 @@ func (s *TunnelModeServer) auth(r *http.Request, c *Conn, u, p string) error {
|
|||
}
|
||||
|
||||
//与客户端建立通道
|
||||
func (s *TunnelModeServer) dealClient(vKey string, en, de int, c *Conn, target string, method string, rb []byte) error {
|
||||
link, err := s.bridge.GetTunnel(getverifyval(vKey), en, de, s.crypt)
|
||||
func (s *TunnelModeServer) dealClient(c *Conn, cnf *ServerConfig, addr string, method string, rb []byte) error {
|
||||
link, err := s.bridge.GetTunnel(getverifyval(cnf.VerifyKey), cnf.CompressEncode, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
|
||||
defer func() {
|
||||
if cnf.Mux {
|
||||
s.bridge.ReturnTunnel(link, getverifyval(cnf.VerifyKey))
|
||||
}
|
||||
}()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
c.Close()
|
||||
return err
|
||||
}
|
||||
if _, err := link.WriteHost(CONN_TCP, target); err != nil {
|
||||
if _, err := link.WriteHost(CONN_TCP, addr); err != nil {
|
||||
c.Close()
|
||||
link.Close()
|
||||
log.Println(err)
|
||||
|
@ -221,10 +204,10 @@ func (s *TunnelModeServer) dealClient(vKey string, en, de int, c *Conn, target s
|
|||
if method == "CONNECT" {
|
||||
fmt.Fprint(c, "HTTP/1.1 200 Connection established\r\n")
|
||||
} else {
|
||||
link.WriteTo(rb, en, s.crypt)
|
||||
link.WriteTo(rb, cnf.CompressEncode, cnf.Crypt)
|
||||
}
|
||||
go relay(link, c, en, s.crypt)
|
||||
relay(c, link, de, s.crypt)
|
||||
go relay(link, c, cnf.CompressEncode, cnf.Crypt, cnf.Mux)
|
||||
relay(c, link, cnf.CompressDecode, cnf.Crypt, cnf.Mux)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -237,11 +220,11 @@ func (s *TunnelModeServer) Close() error {
|
|||
func ProcessTunnel(c *Conn, s *TunnelModeServer) error {
|
||||
method, _, rb, err, r := c.GetHost()
|
||||
if err == nil {
|
||||
if err := s.auth(r, c, s.basicUser, s.basicPassword); err != nil {
|
||||
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return s.dealClient(s.vKey, s.enCompress, s.deCompress, c, s.tunnelTarget, method, rb)
|
||||
return s.dealClient(c, s.config, s.config.Target, method, rb)
|
||||
}
|
||||
|
||||
//http代理模式
|
||||
|
@ -251,10 +234,11 @@ func ProcessHttp(c *Conn, s *TunnelModeServer) error {
|
|||
c.Close()
|
||||
return err
|
||||
}
|
||||
if err := s.auth(r, c, s.basicUser, s.basicPassword); err != nil {
|
||||
if err := s.auth(r, c, s.config.U, s.config.P); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.dealClient(s.vKey, s.enCompress, s.deCompress, c, addr, method, rb)
|
||||
//TODO效率问题
|
||||
return s.dealClient(c, s.config, addr, method, rb)
|
||||
}
|
||||
|
||||
//多客户端域名代理
|
||||
|
@ -272,8 +256,7 @@ func ProcessHost(c *Conn, s *TunnelModeServer) error {
|
|||
c.Close()
|
||||
return err
|
||||
}
|
||||
de, en := getCompressType(task.Compress)
|
||||
return s.dealClient(host.Vkey, en, de, c, host.Target, method, rb)
|
||||
return s.dealClient(c, task, host.Target, method, rb)
|
||||
}
|
||||
|
||||
//web管理方式
|
||||
|
@ -285,7 +268,7 @@ type WebServer struct {
|
|||
func (s *WebServer) Start() {
|
||||
InitFromCsv()
|
||||
p, _ := beego.AppConfig.Int("hostPort")
|
||||
t := &TaskList{
|
||||
t := &ServerConfig{
|
||||
TcpPort: p,
|
||||
Mode: "httpHostServer",
|
||||
Target: "",
|
||||
|
@ -312,7 +295,7 @@ func NewWebServer(bridge *Tunnel) *WebServer {
|
|||
|
||||
//host
|
||||
type HostServer struct {
|
||||
crypt bool
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
//开始
|
||||
|
@ -321,9 +304,9 @@ func (s *HostServer) Start() error {
|
|||
}
|
||||
|
||||
//TODO:host模式的客户端,无需指定和监听端口等
|
||||
func NewHostServer(crypt bool) *HostServer {
|
||||
func NewHostServer(cnf *ServerConfig) *HostServer {
|
||||
s := new(HostServer)
|
||||
s.crypt = crypt
|
||||
s.config = cnf
|
||||
return s
|
||||
}
|
||||
|
37
lib/udp.go
37
lib/udp.go
|
@ -9,33 +9,23 @@ import (
|
|||
)
|
||||
|
||||
type UdpModeServer struct {
|
||||
bridge *Tunnel
|
||||
udpPort int //监听的udp端口
|
||||
tunnelTarget string //udp目标地址
|
||||
listener *net.UDPConn
|
||||
udpMap map[string]*Conn
|
||||
enCompress int
|
||||
deCompress int
|
||||
vKey string
|
||||
crypt bool
|
||||
bridge *Tunnel
|
||||
listener *net.UDPConn
|
||||
udpMap map[string]*Conn
|
||||
config *ServerConfig
|
||||
}
|
||||
|
||||
func NewUdpModeServer(udpPort int, tunnelTarget string, bridge *Tunnel, enCompress int, deCompress int, vKey string, crypt bool) *UdpModeServer {
|
||||
func NewUdpModeServer(bridge *Tunnel, cnf *ServerConfig) *UdpModeServer {
|
||||
s := new(UdpModeServer)
|
||||
s.udpPort = udpPort
|
||||
s.tunnelTarget = tunnelTarget
|
||||
s.bridge = bridge
|
||||
s.udpMap = make(map[string]*Conn)
|
||||
s.enCompress = enCompress
|
||||
s.deCompress = deCompress
|
||||
s.vKey = vKey
|
||||
s.crypt = crypt
|
||||
s.config = cnf
|
||||
return s
|
||||
}
|
||||
|
||||
//开始
|
||||
func (s *UdpModeServer) Start() error {
|
||||
s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), s.udpPort, ""})
|
||||
s.listener, err = net.ListenUDP("udp", &net.UDPAddr{net.ParseIP("0.0.0.0"), s.config.TcpPort, ""})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -55,20 +45,25 @@ func (s *UdpModeServer) Start() error {
|
|||
|
||||
//TODO:效率问题有待解决
|
||||
func (s *UdpModeServer) process(addr *net.UDPAddr, data []byte) {
|
||||
conn, err := s.bridge.GetTunnel(getverifyval(s.vKey), s.enCompress, s.deCompress, s.crypt)
|
||||
conn, err := s.bridge.GetTunnel(getverifyval(s.config.VerifyKey), s.config.CompressEncode, s.config.CompressDecode, s.config.Crypt, s.config.Mux)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
if _, err := conn.WriteHost(CONN_UDP, s.tunnelTarget); err != nil {
|
||||
if _, err := conn.WriteHost(CONN_UDP, s.config.Target); err != nil {
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
conn.WriteTo(data, s.enCompress,s.crypt)
|
||||
conn.WriteTo(data, s.config.CompressEncode, s.config.Crypt)
|
||||
go func(addr *net.UDPAddr, conn *Conn) {
|
||||
defer func() {
|
||||
if s.config.Mux {
|
||||
s.bridge.ReturnTunnel(conn, getverifyval(s.config.VerifyKey))
|
||||
}
|
||||
}()
|
||||
buf := make([]byte, 1024)
|
||||
conn.conn.SetReadDeadline(time.Now().Add(time.Duration(time.Second * 3)))
|
||||
n, err := conn.ReadFrom(buf, s.deCompress,s.crypt)
|
||||
n, err := conn.ReadFrom(buf, s.config.CompressDecode, s.config.Crypt)
|
||||
if err != nil || err == io.EOF {
|
||||
conn.Close()
|
||||
return
|
||||
|
|
29
lib/util.go
29
lib/util.go
|
@ -27,6 +27,7 @@ const (
|
|||
COMPRESS_NONE_DECODE
|
||||
COMPRESS_SNAPY_ENCODE
|
||||
COMPRESS_SNAPY_DECODE
|
||||
IO_EOF = "EOF"
|
||||
)
|
||||
|
||||
//error
|
||||
|
@ -130,19 +131,35 @@ func replaceHost(resp []byte) []byte {
|
|||
}
|
||||
|
||||
//copy
|
||||
func relay(in, out *Conn, compressType int, crypt bool) {
|
||||
func relay(in, out *Conn, compressType int, crypt, mux bool) {
|
||||
switch compressType {
|
||||
case COMPRESS_SNAPY_ENCODE:
|
||||
copyBuffer(NewSnappyConn(in.conn, crypt), out)
|
||||
if mux {
|
||||
NewSnappyConn(in.conn, crypt).Write([]byte(IO_EOF))
|
||||
out.Close()
|
||||
}
|
||||
case COMPRESS_SNAPY_DECODE:
|
||||
copyBuffer(in, NewSnappyConn(out.conn, crypt))
|
||||
if mux {
|
||||
in.Close()
|
||||
}
|
||||
case COMPRESS_NONE_ENCODE:
|
||||
copyBuffer(NewCryptConn(in.conn, crypt), out)
|
||||
if mux {
|
||||
NewCryptConn(in.conn, crypt).Write([]byte(IO_EOF))
|
||||
out.Close()
|
||||
}
|
||||
case COMPRESS_NONE_DECODE:
|
||||
copyBuffer(in, NewCryptConn(out.conn, crypt))
|
||||
if mux {
|
||||
in.Close()
|
||||
}
|
||||
}
|
||||
if !mux {
|
||||
in.Close()
|
||||
out.Close()
|
||||
}
|
||||
out.Close()
|
||||
in.Close()
|
||||
}
|
||||
|
||||
//判断压缩方式
|
||||
|
@ -183,7 +200,7 @@ func verify(verifyKeyMd5 string) bool {
|
|||
}
|
||||
|
||||
//get key by host from x
|
||||
func getKeyByHost(host string) (h *HostList, t *TaskList, err error) {
|
||||
func getKeyByHost(host string) (h *HostList, t *ServerConfig, err error) {
|
||||
for _, v := range CsvDb.Hosts {
|
||||
if strings.Contains(host, v.Host) {
|
||||
h = v
|
||||
|
@ -258,6 +275,10 @@ func GetStrByBool(b bool) string {
|
|||
}
|
||||
return "0"
|
||||
}
|
||||
func GetIntNoerrByStr(str string) int {
|
||||
i, _ := strconv.Atoi(str)
|
||||
return i
|
||||
}
|
||||
|
||||
// io.copy的优化版,读取buffer长度原为32*1024,与snappy不同,导致读取出的内容存在差异,不利于解密,特此修改
|
||||
func copyBuffer(dst io.Writer, src io.Reader) (written int64, err error) {
|
||||
|
|
|
@ -44,6 +44,13 @@
|
|||
<option value="1">加密</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="compress">
|
||||
<label class="control-label">是否TCP复用</label>
|
||||
<select class="form-control" name="crypt">
|
||||
<option value="0">不启用</option>
|
||||
<option value="1">启用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="u">
|
||||
<label class="control-label">验证用户名(仅socks5,web穿透支持)</label>
|
||||
<input class="form-control" type="text" name="u" placeholder="不填则无需验证">
|
||||
|
|
|
@ -35,8 +35,15 @@
|
|||
<div class="form-group" id="compress">
|
||||
<label class="control-label">是否加密传输(所有模式均支持)</label>
|
||||
<select class="form-control" name="crypt">
|
||||
<option {{if eq "0" .t.Crypt}}selected{{end}} value="0">不加密</option>
|
||||
<option {{if eq "1" .t.Crypt}}selected{{end}} value="1">加密</option>
|
||||
<option {{if eq false .t.Crypt}}selected{{end}} value="0">不加密</option>
|
||||
<option {{if eq true .t.Crypt}}selected{{end}} value="1">加密</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="compress">
|
||||
<label class="control-label">是否启用TCP复用(所有模式均支持)</label>
|
||||
<select class="form-control" name="mux">
|
||||
<option {{if eq false .t.Mux}}selected{{end}} value="0">不启用</option>
|
||||
<option {{if eq true .t.Mux}}selected{{end}} value="1">启用</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group" id="u">
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<th>多客户端模式客户端执行命令</th>
|
||||
<th>压缩方式</th>
|
||||
<th>加密传输</th>
|
||||
<th>TCP多路复用</th>
|
||||
<th>用户名</th>
|
||||
<th>密码</th>
|
||||
<th>客户端状态</th>
|
||||
|
@ -97,7 +98,7 @@
|
|||
autoWidth: false,
|
||||
ordering: false,
|
||||
ajax: {
|
||||
url: '/index/gettasklist?type={{.type}}',
|
||||
url: '/index/getserverconfig?type={{.type}}',
|
||||
type: 'POST'
|
||||
},
|
||||
dom: '<"top"fl><"toolbar">rt<"bottom"ip><"clear">',
|
||||
|
@ -108,6 +109,7 @@
|
|||
{data: 'VerifyKey'},
|
||||
{data: 'Compress'},
|
||||
{data: 'Crypt'},
|
||||
{data: 'Mux'},
|
||||
{data: 'U'},
|
||||
{data: 'P'},
|
||||
{data: 'ClientStatus'},
|
||||
|
@ -149,7 +151,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
targets: -6,
|
||||
targets: -7,
|
||||
render: function (data, type, row, meta) {
|
||||
if (data == "0") {
|
||||
return "不加密"
|
||||
|
@ -158,6 +160,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: -6,
|
||||
render: function (data, type, row, meta) {
|
||||
if (data == "0") {
|
||||
return "不启用"
|
||||
} else {
|
||||
return "启用"
|
||||
}
|
||||
}
|
||||
}
|
||||
,
|
||||
{
|
||||
targets: 2,
|
||||
render: function (data, type, row, meta) {
|
||||
|
|
Loading…
Reference in New Issue