prepare for sps
Signed-off-by: arraykeys@gmail.com <arraykeys@gmail.com>
This commit is contained in:
@ -5,6 +5,8 @@ v4.3
|
|||||||
用于自己指定proxy访问域名的时候使用的dns(--dns-address)以及解析结果缓存时间(--dns-ttl)秒数,
|
用于自己指定proxy访问域名的时候使用的dns(--dns-address)以及解析结果缓存时间(--dns-ttl)秒数,
|
||||||
避免系统dns对proxy的干扰,另外缓存功能还能减少dns解析时间提高访问速度。
|
避免系统dns对proxy的干扰,另外缓存功能还能减少dns解析时间提高访问速度。
|
||||||
3.优化了http代理的basic认证逻辑。
|
3.优化了http代理的basic认证逻辑。
|
||||||
|
提示:
|
||||||
|
v4.3生成的证书不适用于v4.2及以下版本。
|
||||||
|
|
||||||
v4.2
|
v4.2
|
||||||
1.优化了内网穿透,避免了client意外下线,导致链接信息残留的问题.
|
1.优化了内网穿透,避免了client意外下线,导致链接信息残留的问题.
|
||||||
|
|||||||
@ -132,7 +132,7 @@ If the installation fails or your VPS is not a linux64 system, please follow the
|
|||||||
Download address: https://github.com/snail007/goproxy/releases
|
Download address: https://github.com/snail007/goproxy/releases
|
||||||
```shell
|
```shell
|
||||||
cd /root/proxy/
|
cd /root/proxy/
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v4.3/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v4.4/proxy-linux-amd64.tar.gz
|
||||||
```
|
```
|
||||||
#### **2.Download the automatic installation script**
|
#### **2.Download the automatic installation script**
|
||||||
```shell
|
```shell
|
||||||
|
|||||||
@ -134,7 +134,7 @@ curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.s
|
|||||||
下载地址:https://github.com/snail007/goproxy/releases
|
下载地址:https://github.com/snail007/goproxy/releases
|
||||||
```shell
|
```shell
|
||||||
cd /root/proxy/
|
cd /root/proxy/
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v4.3/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v4.4/proxy-linux-amd64.tar.gz
|
||||||
```
|
```
|
||||||
#### **2.下载自动安装脚本**
|
#### **2.下载自动安装脚本**
|
||||||
```shell
|
```shell
|
||||||
|
|||||||
12
config.go
12
config.go
@ -39,6 +39,7 @@ func initConfig() (err error) {
|
|||||||
muxBridgeArgs := services.MuxBridgeArgs{}
|
muxBridgeArgs := services.MuxBridgeArgs{}
|
||||||
udpArgs := services.UDPArgs{}
|
udpArgs := services.UDPArgs{}
|
||||||
socksArgs := services.SocksArgs{}
|
socksArgs := services.SocksArgs{}
|
||||||
|
spsArgs := services.SPSArgs{}
|
||||||
//build srvice args
|
//build srvice args
|
||||||
app = kingpin.New("proxy", "happy with proxy")
|
app = kingpin.New("proxy", "happy with proxy")
|
||||||
app.Author("snail").Version(APP_VERSION)
|
app.Author("snail").Version(APP_VERSION)
|
||||||
@ -186,6 +187,16 @@ func initConfig() (err error) {
|
|||||||
socksArgs.AuthURLRetry = socks.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int()
|
socksArgs.AuthURLRetry = socks.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int()
|
||||||
socksArgs.DNSAddress = socks.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
|
socksArgs.DNSAddress = socks.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
|
||||||
socksArgs.DNSTTL = socks.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
|
socksArgs.DNSTTL = socks.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
|
||||||
|
//########socks+http(s)#########
|
||||||
|
sps := app.Command("sps", "proxy on socks+http(s) mode")
|
||||||
|
spsArgs.Parent = sps.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
|
||||||
|
spsArgs.CertFile = sps.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
|
||||||
|
spsArgs.KeyFile = sps.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
|
||||||
|
spsArgs.Timeout = sps.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('e').Default("2000").Int()
|
||||||
|
spsArgs.ParentServiceType = sps.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks")
|
||||||
|
spsArgs.ParentType = sps.Flag("parent-type", "parent protocol type <tls|tcp>").Short('T').Enum("tls", "tcp")
|
||||||
|
spsArgs.LocalType = sps.Flag("local-type", "local protocol type <tls|tcp>").Default("tcp").Short('t').Enum("tls", "tcp")
|
||||||
|
spsArgs.Local = sps.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
|
||||||
|
|
||||||
//parse args
|
//parse args
|
||||||
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
serviceName := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
@ -285,6 +296,7 @@ func initConfig() (err error) {
|
|||||||
services.Regist("client", services.NewMuxClient(), muxClientArgs)
|
services.Regist("client", services.NewMuxClient(), muxClientArgs)
|
||||||
services.Regist("bridge", services.NewMuxBridge(), muxBridgeArgs)
|
services.Regist("bridge", services.NewMuxBridge(), muxBridgeArgs)
|
||||||
services.Regist("socks", services.NewSocks(), socksArgs)
|
services.Regist("socks", services.NewSocks(), socksArgs)
|
||||||
|
services.Regist("sps", services.NewSPS(), spsArgs)
|
||||||
service, err = services.Run(serviceName)
|
service, err = services.Run(serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err)
|
log.Fatalf("run service [%s] fail, ERR:%s", serviceName, err)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ if [ -e /tmp/proxy ]; then
|
|||||||
fi
|
fi
|
||||||
mkdir /tmp/proxy
|
mkdir /tmp/proxy
|
||||||
cd /tmp/proxy
|
cd /tmp/proxy
|
||||||
wget https://github.com/snail007/goproxy/releases/download/v4.3/proxy-linux-amd64.tar.gz
|
wget https://github.com/snail007/goproxy/releases/download/v4.4/proxy-linux-amd64.tar.gz
|
||||||
|
|
||||||
# #install proxy
|
# #install proxy
|
||||||
tar zxvf proxy-linux-amd64.tar.gz
|
tar zxvf proxy-linux-amd64.tar.gz
|
||||||
|
|||||||
2
main.go
2
main.go
@ -8,7 +8,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APP_VERSION = "4.3"
|
const APP_VERSION = "4.4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := initConfig()
|
err := initConfig()
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
VER="4.3"
|
VER="4.4"
|
||||||
RELEASE="release-${VER}"
|
RELEASE="release-${VER}"
|
||||||
rm -rf .cert
|
rm -rf .cert
|
||||||
mkdir .cert
|
mkdir .cert
|
||||||
|
|||||||
@ -187,7 +187,28 @@ type SocksArgs struct {
|
|||||||
DNSAddress *string
|
DNSAddress *string
|
||||||
DNSTTL *int
|
DNSTTL *int
|
||||||
}
|
}
|
||||||
|
type SPSArgs struct {
|
||||||
|
Parent *string
|
||||||
|
CertFile *string
|
||||||
|
KeyFile *string
|
||||||
|
CertBytes []byte
|
||||||
|
KeyBytes []byte
|
||||||
|
Local *string
|
||||||
|
ParentType *string
|
||||||
|
LocalType *string
|
||||||
|
Timeout *int
|
||||||
|
ParentServiceType *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *SPSArgs) Protocol() string {
|
||||||
|
switch *a.LocalType {
|
||||||
|
case TYPE_TLS:
|
||||||
|
return TYPE_TLS
|
||||||
|
case TYPE_TCP:
|
||||||
|
return TYPE_TCP
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
func (a *TCPArgs) Protocol() string {
|
func (a *TCPArgs) Protocol() string {
|
||||||
switch *a.LocalType {
|
switch *a.LocalType {
|
||||||
case TYPE_TLS:
|
case TYPE_TLS:
|
||||||
|
|||||||
110
services/sps.go
Normal file
110
services/sps.go
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"runtime/debug"
|
||||||
|
"snail007/proxy/utils"
|
||||||
|
"snail007/proxy/utils/socks"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SPS struct {
|
||||||
|
outPool utils.OutPool
|
||||||
|
cfg SPSArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSPS() Service {
|
||||||
|
return &SPS{
|
||||||
|
outPool: utils.OutPool{},
|
||||||
|
cfg: SPSArgs{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *SPS) CheckArgs() {
|
||||||
|
if *s.cfg.Parent == "" {
|
||||||
|
log.Fatalf("parent required for %s %s", s.cfg.Protocol(), *s.cfg.Local)
|
||||||
|
}
|
||||||
|
if *s.cfg.ParentType == "" {
|
||||||
|
log.Fatalf("parent type unkown,use -T <tls|tcp>")
|
||||||
|
}
|
||||||
|
if *s.cfg.ParentType == TYPE_TLS || *s.cfg.LocalType == TYPE_TLS {
|
||||||
|
s.cfg.CertBytes, s.cfg.KeyBytes = utils.TlsBytes(*s.cfg.CertFile, *s.cfg.KeyFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *SPS) InitService() {
|
||||||
|
|
||||||
|
}
|
||||||
|
func (s *SPS) StopService() {
|
||||||
|
if s.outPool.Pool != nil {
|
||||||
|
s.outPool.Pool.ReleaseAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *SPS) Start(args interface{}) (err error) {
|
||||||
|
s.cfg = args.(SPSArgs)
|
||||||
|
s.CheckArgs()
|
||||||
|
log.Printf("use %s %s parent %s", *s.cfg.ParentType, *s.cfg.ParentServiceType, *s.cfg.Parent)
|
||||||
|
s.InitService()
|
||||||
|
|
||||||
|
host, port, _ := net.SplitHostPort(*s.cfg.Local)
|
||||||
|
p, _ := strconv.Atoi(port)
|
||||||
|
sc := utils.NewServerChannel(host, p)
|
||||||
|
|
||||||
|
if *s.cfg.LocalType == TYPE_TCP {
|
||||||
|
err = sc.ListenTCP(s.callback)
|
||||||
|
} else if *s.cfg.LocalType == TYPE_TLS {
|
||||||
|
err = sc.ListenTls(s.cfg.CertBytes, s.cfg.KeyBytes, s.callback)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("%s http(s)+socks proxy on %s", s.cfg.Protocol(), (*sc.Listener).Addr())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SPS) Clean() {
|
||||||
|
s.StopService()
|
||||||
|
}
|
||||||
|
func (s *SPS) callback(inConn net.Conn) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
log.Printf("%s conn handler crashed with err : %s \nstack: %s", s.cfg.Protocol(), err, string(debug.Stack()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
var err error
|
||||||
|
switch *s.cfg.ParentType {
|
||||||
|
case TYPE_TCP:
|
||||||
|
fallthrough
|
||||||
|
case TYPE_TLS:
|
||||||
|
err = s.OutToTCP(&inConn)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unkown parent type %s", *s.cfg.ParentType)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("connect to %s parent %s fail, ERR:%s", *s.cfg.ParentType, *s.cfg.Parent, err)
|
||||||
|
utils.CloseConn(&inConn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *SPS) OutToTCP(inConn *net.Conn) (err error) {
|
||||||
|
buf := make([]byte, 1024)
|
||||||
|
n, err := (*inConn).Read(buf)
|
||||||
|
header := buf[:n]
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("ERR:%s", err)
|
||||||
|
utils.CloseConn(inConn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%v", header[0])
|
||||||
|
|
||||||
|
if header[0] == socks.VERSION_V5 {
|
||||||
|
req, e := socks.NewMethodsRequest(*inConn, header)
|
||||||
|
if e != nil {
|
||||||
|
log.Printf("ERR:%s", e)
|
||||||
|
utils.CloseConn(inConn)
|
||||||
|
err = e.(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("address:%v", req.Version())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -53,15 +53,20 @@ type Request struct {
|
|||||||
rw io.ReadWriter
|
rw io.ReadWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRequest(rw io.ReadWriter) (req Request, err interface{}) {
|
func NewRequest(rw io.ReadWriter, header ...[]byte) (req Request, err interface{}) {
|
||||||
var b [1024]byte
|
var b = make([]byte, 1024)
|
||||||
var n int
|
var n int
|
||||||
req = Request{rw: rw}
|
req = Request{rw: rw}
|
||||||
|
if len(header) == 1 {
|
||||||
|
b = header[0]
|
||||||
|
n = len(header[0])
|
||||||
|
} else {
|
||||||
n, err = rw.Read(b[:])
|
n, err = rw.Read(b[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("read req data fail,ERR: %s", err)
|
err = fmt.Errorf("read req data fail,ERR: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
req.ver = uint8(b[0])
|
req.ver = uint8(b[0])
|
||||||
req.cmd = uint8(b[1])
|
req.cmd = uint8(b[1])
|
||||||
req.reserve = uint8(b[2])
|
req.reserve = uint8(b[2])
|
||||||
@ -150,7 +155,7 @@ type MethodsRequest struct {
|
|||||||
rw *io.ReadWriter
|
rw *io.ReadWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMethodsRequest(r io.ReadWriter) (s MethodsRequest, err interface{}) {
|
func NewMethodsRequest(r io.ReadWriter, header ...[]byte) (s MethodsRequest, err interface{}) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = recover()
|
err = recover()
|
||||||
@ -160,10 +165,15 @@ func NewMethodsRequest(r io.ReadWriter) (s MethodsRequest, err interface{}) {
|
|||||||
s.rw = &r
|
s.rw = &r
|
||||||
var buf = make([]byte, 300)
|
var buf = make([]byte, 300)
|
||||||
var n int
|
var n int
|
||||||
|
if len(header) == 1 {
|
||||||
|
buf = header[0]
|
||||||
|
n = len(header[0])
|
||||||
|
} else {
|
||||||
n, err = r.Read(buf)
|
n, err = r.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if buf[0] != 0x05 {
|
if buf[0] != 0x05 {
|
||||||
err = fmt.Errorf("socks version not supported")
|
err = fmt.Errorf("socks version not supported")
|
||||||
return
|
return
|
||||||
|
|||||||
@ -309,13 +309,17 @@ type HTTPRequest struct {
|
|||||||
basicAuth *BasicAuth
|
basicAuth *BasicAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPRequest(inConn *net.Conn, bufSize int, isBasicAuth bool, basicAuth *BasicAuth) (req HTTPRequest, err error) {
|
func NewHTTPRequest(inConn *net.Conn, bufSize int, isBasicAuth bool, basicAuth *BasicAuth, header ...[]byte) (req HTTPRequest, err error) {
|
||||||
buf := make([]byte, bufSize)
|
buf := make([]byte, bufSize)
|
||||||
len := 0
|
n := 0
|
||||||
req = HTTPRequest{
|
req = HTTPRequest{
|
||||||
conn: inConn,
|
conn: inConn,
|
||||||
}
|
}
|
||||||
len, err = (*inConn).Read(buf[:])
|
if len(header) == 1 {
|
||||||
|
buf = header[0]
|
||||||
|
n = len(header[0])
|
||||||
|
} else {
|
||||||
|
n, err = (*inConn).Read(buf[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
err = fmt.Errorf("http decoder read err:%s", err)
|
err = fmt.Errorf("http decoder read err:%s", err)
|
||||||
@ -323,7 +327,9 @@ func NewHTTPRequest(inConn *net.Conn, bufSize int, isBasicAuth bool, basicAuth *
|
|||||||
CloseConn(inConn)
|
CloseConn(inConn)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.HeadBuf = buf[:len]
|
}
|
||||||
|
|
||||||
|
req.HeadBuf = buf[:n]
|
||||||
//fmt.Println(string(req.HeadBuf))
|
//fmt.Println(string(req.HeadBuf))
|
||||||
//try sni
|
//try sni
|
||||||
serverName, err0 := sni.ServerNameFromBytes(req.HeadBuf)
|
serverName, err0 := sni.ServerNameFromBytes(req.HeadBuf)
|
||||||
|
|||||||
Reference in New Issue
Block a user