Score
0
Watch 2 Star 4 Fork 1

年轮 / net-proxyGoApache-2.0

Merged
!1 合并dev代码

年轮:dev年轮:master

年轮 Created on: 2019-12-03 09:12
Reviewer: 2308377_ruchsky_1578971533   Tester: 2308377_ruchsky_1578971533

合并dev代码

0 comments, 1 participants 2308377_ruchsky_1578971533

Show action logs Hide action logs
年轮 merged Pull Request 2019-12-03 09:13
年轮 assigned tester 年轮 2019-12-03 09:12
年轮 assigned reviewer 年轮 2019-12-03 09:12

Sign in to comment

2019-12-02

(2)
Kevin Hu committed 2019-12-02 21:35
年轮 committed 2019-12-02 10:46
5 changed files ,commit stats: +109 -57
## net-proxy 网络代理服务
### 背景
     家里路由器wan口不是外网ip,或者外网ip不固定,解决家里内网穿透问题,并且支持多端口内网穿透
### 实现方式
     1. 开发服务端,服务端部署在一个配置低的阿里云服务器
     2. 开发客户端服务,部署在家里的linux服务器
     3. 客户端跟服务端通讯,上传需要映射的端口,跟服务端建立长连接
     4. 服务端接收客户端需要映射的端口开启不同的端口tpc监听
     5. 在阿里云控制台 安全规则 那里开启对应客户端需要映射的端口
     6. 每当一次远程请求过来,根据监听端口在map当中找到客户端服务服务长连接的哪个conn, 以此进行转发通讯
### 实现的功能
     1. 内网路由随便穿透(需要一台公网代理服务器,配置及低都没问题)
### 启动方式
# 项目介绍
net-proxy 网络代理工具
通过本工具可以解决"内网服务无法直接被外网访问到"的问题。
## 功能列表
1. 内网路由随便穿透(需要一台公网代理服务器,配置无要求)
## 基本原理
内网可以访问到公网,这是唯一的突破点。
首先,在公网(比如阿里云)部署一个服务端,服务端同时监听两个端口 6666 和 13306
在内网启动客户端,同时向 3306 端口及公网 6666 地址拨号,建立连接。
这样就形成了从公网 13306 - 公网 6666 - 内网客户端 - 内网 3306 数据库的 通路。
用户就可以通过 公网 13306 访问到内网的 3306 服务。
## 原理图
![proxy.png](proxy.png)
## 启动方式
```ini
服务端配置
[server]
服务端启动端口
# 服务端配置
[server]
# 服务端启动端口
port = 9200
```
```ini
客户端配置
[client] 客户端配置
配置代理客户端服务需要穿透的内网地址 这里配置内网地址和端口端口,以逗号隔开, 这里开启两个端口穿透
proxyHosts=192.168.61.240:8090,192.168.61.240:8090:6379
配置服务端地址, 比如服务端部署在阿里云中这里需要配置的地址是为了服务端跟客户端通讯
serverUrl = 192.168.61.240:9200
```
###特别注意》》 家里映射22端口需要服务器映射10022
### ====================
![Image text](proxy.png)
```ini
# 客户端配置
[client]
# 配置代理客户端服务需要穿透的内网地址,多个以逗号隔开
proxyHosts=192.168.61.240:8090,192.168.61.240:8090:6379
# 配置服务端地址
serverUrl = 192.168.61.240:9200
```
config/Pool.go 0 → 100644
package config
import (
"github.com/silenceper/pool"
"log"
"net"
"time"
)
func InitPool(addr string) pool.Pool {
poolConfig := &pool.Config{
InitialCap: 2,
MaxCap: 20,
Factory: func() (interface{}, error) {
log.Printf("dial addr = %s\n", addr)
return net.Dial("tcp", addr)
},
Close: func(v interface{}) error {
return v.(net.Conn).Close()
},
//Ping: nil,
IdleTimeout: 15 * time.Second,
}
var p pool.Pool
var err error
if p, err = pool.NewChannelPool(poolConfig); err != nil {
log.Printf("new channel pool err = %s\n", err.Error())
return nil
}
return p
}
main/GoProxyClient.go
@@ -3,6 +3,7 @@ package main
import (
"../config"
"../proxy-core"
"../util"
"bytes"
"encoding/binary"
"log"
@@ -32,6 +33,7 @@ func handleProxyPort(proxyHost string) {
log.Printf("proxy client port = %s\n ", proxyPort)
var proxyConn, serverConn net.Conn
serverUrl := config.GlobalConfig.ServerUrl
//proxyPool := config.InitPool(proxyHost)
i := 0
for {
i++
@@ -48,6 +50,7 @@ func handleProxyPort(proxyHost string) {
}
//拨号代理端口
proxyConn = dial(proxyHost)
//proxyConn = proxyPool.Get()
proxy_core.ProxySwap(serverConn, proxyConn)
}
@@ -58,12 +61,8 @@ func handleProxyPort(proxyHost string) {
*/
func write(conn net.Conn, content string) error {
_contentBytes := []byte(content)
len := int32(len(_contentBytes))
bytesBuffer := bytes.NewBuffer([]byte{})
_ = binary.Write(bytesBuffer, binary.BigEndian, len)
_lenBytes := bytesBuffer.Bytes()
var buffer bytes.Buffer
buffer.Write(_lenBytes)
buffer.Write(util.IntToBytes(len(_contentBytes)))
buffer.Write(_contentBytes)
_, err := conn.Write(buffer.Bytes())
return err
main/GoProxyServer.go
@@ -10,7 +10,6 @@ import (
"log"
"net"
"strings"
"time"
)
func main() {
@@ -21,7 +20,7 @@ func main() {
//监听服务端端口
serverListen, err := proxy_core.ListenServer(config.GlobalConfig.ServerPort)
util.PanicIfErr(err)
log.Printf("server listen port = %s\n:", config.GlobalConfig.ServerPort)
log.Printf("server listen port = %s\n", config.GlobalConfig.ServerPort)
for {
client, err := serverListen.Accept()
if err != nil {
@@ -43,7 +42,7 @@ func _pakServer(server net.Listener, v int, client net.Conn, proxyPort string) p
}
func fetchServer(proxyPort string, client net.Conn) proxy_core.Server {
server := portConnMap[proxyPort]
server := serverMap[proxyPort]
if server.Server == nil {
proxyListen, err := proxy_core.ListenServer(proxyPort)
if err != nil {
@@ -51,10 +50,10 @@ func fetchServer(proxyPort string, client net.Conn) proxy_core.Server {
return proxy_core.Server{}
}
server = _pakServer(proxyListen, 0, client, proxyPort)
portConnMap[proxyPort] = server
serverMap[proxyPort] = server
}
//替换新的结构体 新的结构体周期增加
portConnMap[proxyPort] = server.IncrCycle(client)
serverMap[proxyPort] = server.IncrCycle(client)
return server
}
@@ -72,7 +71,7 @@ func (p *ProxyAddress) toString() string {
return fmt.Sprintf("proxy id = %s proxy port = %s", p.Ip, p.Port)
}
var portConnMap = make(map[string]proxy_core.Server)
var serverMap = make(map[string]proxy_core.Server)
func firstConn(client net.Conn) ProxyAddress {
var proxyAddr ProxyAddress
@@ -112,23 +111,21 @@ func handleClient(client net.Conn) {
if server.Server == nil {
return
}
if server.Expire(2) {
return
}
//希望所有的请求进入管道
/*connChan := make(chan proxy_core.Request, 100)
go handlerConnChan(connChan, proxyPort)*/
server = portConnMap[proxyPort]
go accept(server, callback, proxyPort)
for {
//当前版本号不匹配
if server.Expire(portConnMap[server.ProxyPort].V) {
return
}
time.Sleep(2 * time.Second)
}
server = serverMap[proxyPort]
go accept(callback, proxyPort)
select {}
}
func callback(src net.Conn, dest net.Conn) {
proxy_core.ProxyIoBind(&src, dest)
//proxy_core.ProxySwap(src, dest)
}
/*func handlerConnChan(connChan chan proxy_core.Request, proxyPort string) {
@@ -139,19 +136,17 @@ func callback(src net.Conn, dest net.Conn) {
}
}*/
func accept(server proxy_core.Server, fn func(src net.Conn, dest net.Conn), proxyPort string) {
func accept(fn func(src net.Conn, dest net.Conn), proxyPort string) {
for {
if server.Expire(portConnMap[server.ProxyPort].V) {
return
}
var srcConn net.Conn
srcConn, err := server.Server.Accept()
srcConn, err := serverMap[proxyPort].Server.Accept()
if err != nil {
log.Println(err)
continue
}
go func() {
fn(srcConn, portConnMap[proxyPort].Client)
fn(srcConn, serverMap[proxyPort].Client)
}()
//connChan <- proxy_core.Request{proxyConn, nil}
}
util/Utils.go
package util
import (
"bytes"
"encoding/binary"
)
func PanicIfErr(err error) {
if err != nil {
panic(err)
@@ -11,3 +16,19 @@ func PanicIfErrMsg(err error, msg string) {
panic(msg)
}
}
//整形转换成字节
func IntToBytes(n int) []byte {
x := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
_ = binary.Write(bytesBuffer, binary.BigEndian, x)
return bytesBuffer.Bytes()
}
//字节转换成整形
func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b)
var x int32
_ = binary.Read(bytesBuffer, binary.BigEndian, &x)
return int(x)
}
Go
1
https://gitee.com/ruchsky/go-huj-net-proxy.git
git@gitee.com:ruchsky/go-huj-net-proxy.git
ruchsky
go-huj-net-proxy
net-proxy

Help Search