Skip to content

Commit

Permalink
合并tunnel功能
Browse files Browse the repository at this point in the history
  • Loading branch information
keminar committed Apr 17, 2021
1 parent a874452 commit 22338fe
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 155 deletions.
13 changes: 13 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

linux:
bash ./scripts/build.sh linux
mac:
bash ./scripts/build.sh mac
windows:
bash ./scripts/build.sh windows
alpine:
bash ./scripts/build.sh alpine
all:
bash ./scripts/build.sh all
clean:
rm -rf dist/*
18 changes: 7 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

anyproxy 是一个部署在Linux系统上的tcp流转发器,可以直接将本地或网络收到的请求发出,也可以将请求转到tunneld或SOCKS或charles等代理。可以代替Proxifier做Linux下的客户端, 也可以配合Proxifier当它的服务端。经过跨平台编译,如果只做网络包的转发可以在windows等平台使用。

[下载Linux包](http://cloudme.io/anyproxy)[下载Mac包](http://cloudme.io/anyproxy-darwin)
[下载Windows包](http://cloudme.io/anyproxy-windows.exe)[下载alpine包](http://cloudme.io/anyproxy-alpine)
[下载Linux包](http://cloudme.io/anyproxy)[下载Mac包](http://cloudme.io/anyproxy-darwin)[下载Windows包](http://cloudme.io/anyproxy-windows.exe)

提醒:请使用浏览器右键的“链接另存为”下载文件

Expand Down Expand Up @@ -42,8 +41,6 @@ tunneld 是一个anyproxy的服务端,部署在服务器上接收anyproxy的
`使用iptables将本用户下tcp流转到anyproxy,再进行docker pull操作`

![解决Docker pull问题](examples/docker_pull.png)

> 案例2: 解决相同域名访问网站不同测试环境的问题
`本地通过内网 anyproxy 代理上网,遇到测试服务器域名则跳到外网tunneld转发,网站的nginx根据来源IP进行转发到特定测试环境(有几个环境就需要有几个tunneld服务且IP要不同)`
Expand All @@ -68,7 +65,7 @@ go env -w GOPROXY=https://goproxy.cn,direct
```
git clone https://github.com/keminar/anyproxy.git
cd anyproxy
go build anyproxy.git
make all
```

> 本机启动
Expand All @@ -81,10 +78,10 @@ sudo -u anyproxy ./anyproxy
./anyproxy -daemon
# 示例3. 启动tunneld
./tunneld
./anyproxy -mode tunnel
# 示例4. 启动anyproxy并将请求转给tunneld
./anyproxy -p '127.0.0.1:3001'
./anyproxy -p 'tunnel://127.0.0.1:3001'
# 示例5. 启动anyproxy并将请求转给socks5
./anyproxy -p 'socks5://127.0.0.1:10000'
Expand Down Expand Up @@ -170,12 +167,11 @@ sudo iptables -t nat -D OUTPUT 2
* ~~支持windows平台使用~~
* ~~通过websocket实现内网穿透(必须为http的非CONNECT请求)~~
* ~~订阅增加邮箱标识,用于辨别在线用户~~
* TCP 增加更多协议解析支持,如rtmp,ftp, socks5, https(SNI)等
* TCP 转发的mysql的连接请求会一直卡住
* 与Tunnel的多账户认证,账户可设置有效期
* HTTP/1.1 keep-alive后端也能复用tcp
* ~~与Tunnel功能合并,使用mode区分~~
* ~~启用ws-listen后的平滑重启问题~~
* ~~监听配置文件变化重新加载路由~~
* TCP 增加更多协议解析支持,如rtmp,ftp, socks5, https(SNI)等
* TCP 转发的mysql的连接请求会一直卡住

# 感谢

Expand Down
31 changes: 20 additions & 11 deletions anyproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
_ "net/http/pprof"
"os"
"time"

"github.com/keminar/anyproxy/config"
"github.com/keminar/anyproxy/grace"
Expand All @@ -25,6 +26,7 @@ var (
gProxyServerSpec string
gWebsocketListen string
gWebsocketConn string
gMode string
gHelp bool
gDebug int
gPprof string
Expand All @@ -36,10 +38,10 @@ func init() {
flag.StringVar(&gProxyServerSpec, "p", "", "Proxy servers to use")
flag.StringVar(&gWebsocketListen, "ws-listen", "", "Websocket address and port to listen on")
flag.StringVar(&gWebsocketConn, "ws-connect", "", "Websocket Address and port to connect")
flag.StringVar(&gMode, "mode", "", "Run mode(proxy, tunnel). proxy mode default")
flag.IntVar(&gDebug, "debug", 0, "debug mode (0, 1, 2)")
flag.StringVar(&gPprof, "pprof", "", "pprof port, disable if empty")
flag.BoolVar(&gHelp, "h", false, "This usage message")

}

func main() {
Expand All @@ -57,10 +59,7 @@ func main() {
}

cmdName := "anyproxy"
logDir := "./logs/"
if conf.RouterConfig.Log.Dir != "" {
logDir = conf.RouterConfig.Log.Dir
}
logDir := config.IfEmptyThen(conf.RouterConfig.Log.Dir, "./logs/", "")
envRunMode := fmt.Sprintf("%s_run_mode", cmdName)
fd := logging.ErrlogFd(logDir, cmdName)
// 是否后台运行
Expand Down Expand Up @@ -89,23 +88,33 @@ func main() {
//浏览器访问: http://:5001/debug/pprof/
log.Println("Starting pprof debug server ...")
// 这里不要使用log.Fatal会在平滑重启时导致进程退出
// 因为http server现在没办法加入平滑重启,第一次重启会报端口冲突,可以通过重启两次来启动到pprof
log.Println(http.ListenAndServe(gPprof, nil))
// 因为http server现在没办法一次平滑重启,会报端口冲突,可以通过多次重试来启动pprof
for i := 0; i < 10; i++ {
log.Println(http.ListenAndServe(gPprof, nil))
time.Sleep(10 * time.Second)
}
}()
}

// websocket 配置
// websocket 服务端
gWebsocketListen = config.IfEmptyThen(gWebsocketListen, conf.RouterConfig.Websocket.Listen, "")
if gWebsocketListen != "" {
gWebsocketListen = tools.FillPort(gWebsocketListen)
go nat.NewServer(&gWebsocketListen)
}

// websocket 客户端
gWebsocketConn = config.IfEmptyThen(gWebsocketConn, conf.RouterConfig.Websocket.Connect, "")
if gWebsocketConn != "" {
gWebsocketConn = tools.FillPort(gWebsocketConn)
go nat.ConnectServer(&gWebsocketConn)
}
server := grace.NewServer(gListenAddrPort, proto.ClientHandler)
server.ListenAndServe()

// 运行模式
if gMode == "tunnel" {
server := grace.NewServer(gListenAddrPort, proto.ServerHandler)
server.ListenAndServe()
} else {
server := grace.NewServer(gListenAddrPort, proto.ClientHandler)
server.ListenAndServe()
}
}
2 changes: 1 addition & 1 deletion conf/router.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ log:
# 监听配置文件变化
watcher: true
# anyproxy 和 tunnel通信密钥, 必须16位长度
#token: anyproxyproxyany
token: anyproxyproxyany
# 可访问的客户端IP,为空不限制
#allowIP:

Expand Down
9 changes: 2 additions & 7 deletions nat/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,13 @@ func NewServer(addr *string) {

log.Println(fmt.Sprintf("Listening for websocket connections on %s", *addr))

i := 0
for {
for i := 0; i < 1000; i++ {
// 副服务,出错不退出并定时重试。方便主服务做平滑重启
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Println("ListenAndServe: ", err)
}
if i > 1000 {
break
log.Println(fmt.Sprintf("ListenAndServe: num=%d, err=%v ", i, err))
}
time.Sleep(10 * time.Second)
i++
}
}

Expand Down
64 changes: 35 additions & 29 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,44 @@ cd $ROOT_DIR

mkdir -p dist/

# 路径
GOCMD="go"
GITCMD="git"

# 目标文件前缀
BIN="anyproxy"

# 版本号
VER=`git describe --tags $(git rev-list --tags --max-count=1)`
GOVER=`go version`
COMMIT_SHA1=`git rev-parse HEAD`
ARCH="amd64"

#组装变量
GOBUILD="${GOCMD} build"
VER=`${GITCMD} describe --tags $(${GITCMD} rev-list --tags --max-count=1)`
GOVER=`${GOCMD} version`
COMMIT_SHA1=`${GITCMD} rev-parse HEAD`
HELP_PRE="github.com/keminar/anyproxy/utils/help"
LDFLAGS="-X '${HELP_PRE}.goVersion=${GOVER}'"
LDFLAGS="${LDFLAGS} -X '${HELP_PRE}.gitHash=${COMMIT_SHA1}'"
LDFLAGS="${LDFLAGS} -X '${HELP_PRE}.version=${VER}'"

# anyproxy
echo "build anyproxy"
# for linux
echo " for linux"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/anyproxy-${VER} anyproxy.go

# for mac
echo " for mac"
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/anyproxy-darwin-${VER} anyproxy.go

# for windows
echo " for windows"
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/anyproxy-windows-${VER}.exe anyproxy.go

# for alpine
echo " for alpine"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags netgo -ldflags "$LDFLAGS" -o dist/anyproxy-alpine-${VER} anyproxy.go

# tunneld
echo "build tunneld"
echo " for linux"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "$LDFLAGS" -o dist/tunneld-${VER} tunnel/tunneld.go

# for alpine
echo " for alpine"
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags netgo -ldflags "$LDFLAGS" -o dist/tunneld-alpine-${VER} tunnel/tunneld.go
# 编译
echo "build ..."
if [ "$1" == "all" ] || [ "$1" == "linux" ] ;then
echo " for linux"
CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} ${GOBUILD} -ldflags "$LDFLAGS" -o dist/${BIN}-${ARCH}-${VER} anyproxy.go
fi

if [ "$1" == "all" ] || [ "$1" == "mac" ] ;then
echo " for mac"
CGO_ENABLED=0 GOOS=darwin GOARCH=${ARCH} ${GOBUILD} -ldflags "$LDFLAGS" -o dist/${BIN}-darwin-${ARCH}-${VER} anyproxy.go
fi

if [ "$1" == "all" ] || [ "$1" == "windows" ] ;then
echo " for windows"
CGO_ENABLED=0 GOOS=windows GOARCH=${ARCH} ${GOBUILD} -ldflags "$LDFLAGS" -o dist/${BIN}-windows-${ARCH}-${VER}.exe anyproxy.go
fi

if [ "$1" == "all" ] || [ "$1" == "alpine" ] ;then
echo " for alpine"
CGO_ENABLED=0 GOOS=linux GOARCH=${ARCH} ${GOBUILD} -tags netgo -ldflags "$LDFLAGS" -o dist/${BIN}-alpine-${ARCH}-${VER} anyproxy.go
fi
77 changes: 0 additions & 77 deletions tunnel/tunneld.go

This file was deleted.

20 changes: 1 addition & 19 deletions utils/help/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func Usage() {
fmt.Fprintf(os.Stdout, " -ws-listen Websocket address and port to listen on\n")
fmt.Fprintf(os.Stdout, " -ws-connect Websocket Address and port to connect\n")
fmt.Fprintf(os.Stdout, " -daemon Run as a Unix daemon\n")
fmt.Fprintf(os.Stdout, " -mode Run mode(proxy, tunnel). proxy mode default\n")
fmt.Fprintf(os.Stdout, " -debug Debug mode (0, 1, 2, 3)\n")
fmt.Fprintf(os.Stdout, " -pprof Pprof port, disable if empty\n")
fmt.Fprintf(os.Stdout, " -h This usage message\n\n")
Expand Down Expand Up @@ -57,25 +58,6 @@ func Usage() {
fmt.Fprintf(os.Stdout, "Thanks to https://github.com/ryanchapman/go-any-proxy.git\n")
}

// TunnelUsage 帮助
func TunnelUsage() {
fmt.Fprintf(os.Stdout, "%s\n\n", versionString("tunneld"))
fmt.Fprintf(os.Stdout, "Usage: %s -l listenaddress -p proxies \n", os.Args[0])
fmt.Fprintf(os.Stdout, " Proxies anyproxy reqest\n\n")
fmt.Fprintf(os.Stdout, "Mandatory\n")
fmt.Fprintf(os.Stdout, " -l=ADDRPORT Address and port to listen on (e.g., :3001 or 127.0.0.1:3001)\n")
fmt.Fprintf(os.Stdout, "Optional\n")
fmt.Fprintf(os.Stdout, " -p=PROXIES Address and ports of upstream proxy servers to use\n")
fmt.Fprintf(os.Stdout, " (e.g., 10.1.1.1:80 will use http proxy, socks5://10.2.2.2:3128 use socks5 proxy,\n")
fmt.Fprintf(os.Stdout, " tunnel://10.2.2.2:3001 use tunnel proxy)\n")
fmt.Fprintf(os.Stdout, " -daemon Run as a Unix daemon\n")
fmt.Fprintf(os.Stdout, " -debug Debug mode (0, 1, 2, 3)\n")
fmt.Fprintf(os.Stdout, " -h This usage message\n\n")

fmt.Fprintf(os.Stdout, "Report bugs to https://github.com/keminar/anyproxy or <[email protected]>.\n")
fmt.Fprintf(os.Stdout, "Thanks to https://github.com/ryanchapman/go-any-proxy.git\n")
}

func versionString(name string) (v string) {
now := time.Now().Unix()
buildNum := strings.ToUpper(strconv.FormatInt(now, 36))
Expand Down

0 comments on commit 22338fe

Please sign in to comment.