支持通过proxy连接server
This commit is contained in:
+102
-33
@@ -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
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user