支持通过proxy连接server

This commit is contained in:
FunnyWolf
2021-09-17 17:26:51 +08:00
parent 6aef853c0e
commit d0352e10db
+102 -33
View File
@@ -1,29 +1,105 @@
package main package main
import ( import (
"bufio"
"crypto/tls" "crypto/tls"
"encoding/base64"
"flag" "flag"
"fmt" "fmt"
"github.com/armon/go-socks5" "github.com/armon/go-socks5"
"github.com/hashicorp/yamux" "github.com/hashicorp/yamux"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"io"
"net" "net"
"net/http"
"net/url"
"time" "time"
"golang.org/x/net/proxy"
) )
var tlsFingerprint string type ProxyAuth struct {
Enable bool
Username string
Passwd string
}
var ( func DialTcpByProxy(proxyStr string, addr string) (c net.Conn, err error) {
ErrInvalidServerCert = fmt.Errorf("invalid TLS server certificate") var proxyUrl *url.URL
ErrInvalidPinnedCert = fmt.Errorf("invalid TLS pinned certificate") if proxyUrl, err = url.Parse(proxyStr); err != nil {
) return
}
auth := &ProxyAuth{}
if proxyUrl.User != nil {
auth.Enable = true
auth.Username = proxyUrl.User.Username()
auth.Passwd, _ = proxyUrl.User.Password()
}
switch proxyUrl.Scheme {
case "http":
return DialTcpByHttpProxy(proxyUrl.Host, addr, auth)
case "socks5":
return DialTcpBySocks5Proxy(proxyUrl.Host, addr, auth)
default:
err = fmt.Errorf("Proxy URL scheme must be http or socks5, not [%s]", proxyUrl.Scheme)
return
}
}
func DialTcpByHttpProxy(proxyHost string, dstAddr string, auth *ProxyAuth) (c net.Conn, err error) {
if c, err = net.Dial("tcp", proxyHost); err != nil {
return
}
req, err := http.NewRequest("CONNECT", "http://"+dstAddr, nil)
if err != nil {
return
}
if auth.Enable {
req.Header.Set("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(auth.Username+":"+auth.Passwd)))
}
req.Header.Set("User-Agent", "Mozilla/5.0")
req.Write(c)
resp, err := http.ReadResponse(bufio.NewReader(c), req)
if err != nil {
return nil, err
}
resp.Body.Close()
if resp.StatusCode != 200 {
err = fmt.Errorf("DialTcpByHttpProxy error, StatusCode [%d]", resp.StatusCode)
return
}
return
}
func DialTcpBySocks5Proxy(proxyHost string, dstAddr string, auth *ProxyAuth) (c net.Conn, err error) {
var s5Auth *proxy.Auth
if auth.Enable {
s5Auth = &proxy.Auth{
User: auth.Username,
Password: auth.Passwd,
}
}
dialer, err := proxy.SOCKS5("tcp", proxyHost, s5Auth, nil)
if err != nil {
return nil, err
}
if c, err = dialer.Dial("tcp", dstAddr); err != nil {
return
}
return
}
func main() { func main() {
relayServer := flag.String("s", "example.com:443", "The ligolo server (the connect-back address)") relayServer := flag.String("s", "", "The ligolo server (the connect-back address)(e.g. example.com:443)")
proxyStr := flag.String("proxy", "", "Use proxy to connect ligolo server(e.g. http://user:[email protected]:8080 socks5://user:[email protected]:1080)")
flag.Parse() flag.Parse()
for { for {
err := StartLigolo(*relayServer) err := StartLigolo(*relayServer, *proxyStr)
if err != nil { if err != nil {
logrus.Error(err) logrus.Error(err)
} }
@@ -32,14 +108,26 @@ func main() {
} }
} }
func StartLigolo(relayServer string) error { func StartLigolo(relayServer string, proxyStr string) error {
var socks *socks5.Server var socks *socks5.Server
logrus.Infoln("Connecting to ligolo server...") logrus.Infoln("Connecting to ligolo server...")
config := &tls.Config{InsecureSkipVerify: true} config := &tls.Config{InsecureSkipVerify: true}
conn, err := tls.Dial("tcp", relayServer, config) var conn net.Conn
if err != nil { var err error
return err
if proxyStr == "" {
conn, err = tls.Dial("tcp", relayServer, config)
if err != nil {
return err
}
} else {
logrus.Infoln("Using proxy")
conn, err = DialTcpByProxy(proxyStr, relayServer)
if err != nil {
return err
}
conn = tls.Client(conn, config)
} }
socks, err = startSocksProxy() socks, err = startSocksProxy()
if err != nil { if err != nil {
@@ -63,6 +151,7 @@ func StartLigolo(relayServer string) error {
// When no targetServer are specified, starts a socks5 proxy // When no targetServer are specified, starts a socks5 proxy
go socks.ServeConn(stream) go socks.ServeConn(stream)
} }
} }
func startSocksProxy() (*socks5.Server, error) { func startSocksProxy() (*socks5.Server, error) {
@@ -74,23 +163,3 @@ func startSocksProxy() (*socks5.Server, error) {
} }
return socks, nil return socks, nil
} }
func handleRelay(src net.Conn, dst net.Conn) {
stop := make(chan bool, 2)
go relay(src, dst, stop)
go relay(dst, src, stop)
select {
case <-stop:
return
}
}
func relay(src net.Conn, dst net.Conn, stop chan bool) {
io.Copy(dst, src)
dst.Close()
src.Close()
stop <- true
return
}