mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
tls, trojan: use 443 as default port if not specified
This commit is contained in:
parent
e7ebcbcde5
commit
8495f16a76
@ -53,7 +53,7 @@ we can set up local listeners as proxy servers, and forward requests to internet
|
||||
|ssr | | |√| |client only
|
||||
|ssh | | |√| |client only
|
||||
|trojan | | |√|√|client only
|
||||
|vless |√|√|√|√|client only
|
||||
|vless |√|√|√|√|client & server
|
||||
|vmess | | |√| |client only
|
||||
|redir |√| | | |linux only
|
||||
|redir6 |√| | | |linux only(ipv6)
|
||||
|
5
go.mod
5
go.mod
@ -11,8 +11,9 @@ require (
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/xtaci/kcp-go/v5 v5.5.17
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
|
||||
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c // indirect
|
||||
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d // indirect
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 // indirect
|
||||
golang.org/x/sys v0.0.0-20201007082116-8445cc04cbdf // indirect
|
||||
golang.org/x/tools v0.0.0-20201007032633-0806396f153e // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
|
||||
)
|
||||
|
||||
|
12
go.sum
12
go.sum
@ -141,8 +141,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgN
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c h1:dk0ukUIHmGHqASjP0iue2261isepFCC6XRCSd1nHgDw=
|
||||
golang.org/x/net v0.0.0-20201002202402-0a1ea396d57c/go.mod h1:iQL9McJNjoIa5mjH6nYTCTZXUN6RP+XW3eib7Ya3XcI=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M=
|
||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -167,14 +167,18 @@ golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201007082116-8445cc04cbdf h1:AvBTl0xbF/KtHyvm61X4gSPF7/dKJ/xQqJwKr1Qu9no=
|
||||
golang.org/x/sys v0.0.0-20201007082116-8445cc04cbdf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d h1:vWQvJ/Z0Lu+9/8oQ/pAYXNzbc7CMnBl+tULGVHOy3oE=
|
||||
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201007032633-0806396f153e h1:FJA2W4BQfMGZ+CD/tiAc39HXecuRsJl3EuczaSUu/Yk=
|
||||
golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
|
2
main.go
2
main.go
@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
version = "0.11.1"
|
||||
version = "0.11.2"
|
||||
config = parseConfig()
|
||||
)
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
package redir
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
@ -13,14 +12,6 @@ import (
|
||||
|
||||
"github.com/nadoo/glider/log"
|
||||
"github.com/nadoo/glider/proxy"
|
||||
"github.com/nadoo/glider/proxy/socks"
|
||||
)
|
||||
|
||||
const (
|
||||
// SO_ORIGINAL_DST from linux/include/uapi/linux/netfilter_ipv4.h
|
||||
SO_ORIGINAL_DST = 80
|
||||
// IP6T_SO_ORIGINAL_DST from linux/include/uapi/linux/netfilter_ipv6/ip6_tables.h
|
||||
IP6T_SO_ORIGINAL_DST = 80
|
||||
)
|
||||
|
||||
// RedirProxy struct.
|
||||
@ -85,13 +76,16 @@ func (s *RedirProxy) ListenAndServe() {
|
||||
}
|
||||
|
||||
// Serve serves connections.
|
||||
func (s *RedirProxy) Serve(c net.Conn) {
|
||||
defer c.Close()
|
||||
func (s *RedirProxy) Serve(cc net.Conn) {
|
||||
defer cc.Close()
|
||||
|
||||
if c, ok := c.(*net.TCPConn); ok {
|
||||
c.SetKeepAlive(true)
|
||||
c, ok := cc.(*net.TCPConn)
|
||||
if !ok {
|
||||
log.F("[redir] not a tcp connection, can not chain redir proxy")
|
||||
return
|
||||
}
|
||||
|
||||
c.SetKeepAlive(true)
|
||||
tgt, err := getOrigDst(c, s.ipv6)
|
||||
if err != nil {
|
||||
log.F("[redir] failed to get target address: %v", err)
|
||||
@ -123,61 +117,49 @@ func (s *RedirProxy) Serve(c net.Conn) {
|
||||
}
|
||||
|
||||
// Get the original destination of a TCP connection.
|
||||
func getOrigDst(conn net.Conn, ipv6 bool) (socks.Addr, error) {
|
||||
c, ok := conn.(*net.TCPConn)
|
||||
if !ok {
|
||||
return nil, errors.New("only work with TCP connection")
|
||||
}
|
||||
f, err := c.File()
|
||||
func getOrigDst(c *net.TCPConn, ipv6 bool) (*net.TCPAddr, error) {
|
||||
rc, err := c.SyscallConn()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
fd := f.Fd()
|
||||
|
||||
// The File() call above puts both the original socket fd and the file fd in blocking mode.
|
||||
// Set the file fd back to non-blocking mode and the original socket fd will become non-blocking as well.
|
||||
// Otherwise blocking I/O will waste OS threads.
|
||||
if err := syscall.SetNonblock(int(fd), true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ipv6 {
|
||||
return getorigdstIPv6(fd)
|
||||
}
|
||||
|
||||
return getorigdst(fd)
|
||||
var addr *net.TCPAddr
|
||||
rc.Control(func(fd uintptr) {
|
||||
if ipv6 {
|
||||
addr, err = ipv6_getorigdst(fd)
|
||||
} else {
|
||||
addr, err = getorigdst(fd)
|
||||
}
|
||||
})
|
||||
return addr, err
|
||||
}
|
||||
|
||||
// Call getorigdst() from linux/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
|
||||
func getorigdst(fd uintptr) (socks.Addr, error) {
|
||||
raw := syscall.RawSockaddrInet4{}
|
||||
func getorigdst(fd uintptr) (*net.TCPAddr, error) {
|
||||
const _SO_ORIGINAL_DST = 80 // from linux/include/uapi/linux/netfilter_ipv4.h
|
||||
var raw syscall.RawSockaddrInet4
|
||||
siz := unsafe.Sizeof(raw)
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IP, _SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := make([]byte, 1+net.IPv4len+2)
|
||||
addr[0] = socks.ATypIP4
|
||||
copy(addr[1:1+net.IPv4len], raw.Addr[:])
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // big-endian
|
||||
addr[1+net.IPv4len], addr[1+net.IPv4len+1] = port[0], port[1]
|
||||
return addr, nil
|
||||
var addr net.TCPAddr
|
||||
addr.IP = raw.Addr[:]
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // raw.Port is big-endian
|
||||
addr.Port = int(port[0])<<8 | int(port[1])
|
||||
return &addr, nil
|
||||
}
|
||||
|
||||
// Call ipv6_getorigdst() from linux/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
|
||||
func getorigdstIPv6(fd uintptr) (socks.Addr, error) {
|
||||
raw := syscall.RawSockaddrInet6{}
|
||||
// NOTE: I haven't tried yet but it should work since Linux 3.8.
|
||||
func ipv6_getorigdst(fd uintptr) (*net.TCPAddr, error) {
|
||||
const _IP6T_SO_ORIGINAL_DST = 80 // from linux/include/uapi/linux/netfilter_ipv6/ip6_tables.h
|
||||
var raw syscall.RawSockaddrInet6
|
||||
siz := unsafe.Sizeof(raw)
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
if err := socketcall(GETSOCKOPT, fd, syscall.IPPROTO_IPV6, _IP6T_SO_ORIGINAL_DST, uintptr(unsafe.Pointer(&raw)), uintptr(unsafe.Pointer(&siz)), 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := make([]byte, 1+net.IPv6len+2)
|
||||
addr[0] = socks.ATypIP6
|
||||
copy(addr[1:1+net.IPv6len], raw.Addr[:])
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // big-endian
|
||||
addr[1+net.IPv6len], addr[1+net.IPv6len+1] = port[0], port[1]
|
||||
return addr, nil
|
||||
var addr net.TCPAddr
|
||||
addr.IP = raw.Addr[:]
|
||||
port := (*[2]byte)(unsafe.Pointer(&raw.Port)) // raw.Port is big-endian
|
||||
addr.Port = int(port[0])<<8 | int(port[1])
|
||||
return &addr, nil
|
||||
}
|
||||
|
@ -5,8 +5,7 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// https://github.com/golang/go/blob/9e6b79a5dfb2f6fe4301ced956419a0da83bd025/src/syscall/syscall_linux_386.go#L196
|
||||
const GETSOCKOPT = 15
|
||||
const GETSOCKOPT = 15 // https://golang.org/src/syscall/syscall_linux_386.go#L183
|
||||
|
||||
func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) error {
|
||||
var a [6]uintptr
|
||||
|
@ -4,7 +4,6 @@ package redir
|
||||
|
||||
import "syscall"
|
||||
|
||||
// GETSOCKOPT from syscall
|
||||
const GETSOCKOPT = syscall.SYS_GETSOCKOPT
|
||||
|
||||
func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) error {
|
||||
|
@ -38,39 +38,27 @@ func init() {
|
||||
func NewTLS(s string, d proxy.Dialer, p proxy.Proxy) (*TLS, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
log.F("parse url err: %s", err)
|
||||
log.F("[tls] parse url err: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addr := u.Host
|
||||
|
||||
colonPos := strings.LastIndex(addr, ":")
|
||||
if colonPos == -1 {
|
||||
colonPos = len(addr)
|
||||
}
|
||||
serverName := addr[:colonPos]
|
||||
|
||||
query := u.Query()
|
||||
skipVerify := query.Get("skipVerify")
|
||||
certFile := query.Get("cert")
|
||||
keyFile := query.Get("key")
|
||||
|
||||
if customServer := query.Get("serverName"); customServer != "" {
|
||||
serverName = customServer
|
||||
}
|
||||
|
||||
t := &TLS{
|
||||
dialer: d,
|
||||
proxy: p,
|
||||
addr: addr,
|
||||
serverName: serverName,
|
||||
skipVerify: false,
|
||||
certFile: certFile,
|
||||
keyFile: keyFile,
|
||||
addr: u.Host,
|
||||
serverName: query.Get("serverName"),
|
||||
skipVerify: query.Get("skipVerify") == "true",
|
||||
certFile: query.Get("cert"),
|
||||
keyFile: query.Get("key"),
|
||||
}
|
||||
|
||||
if skipVerify == "true" {
|
||||
t.skipVerify = true
|
||||
if t.serverName == "" {
|
||||
host, port, _ := net.SplitHostPort(t.addr)
|
||||
if port == "" {
|
||||
t.addr = net.JoinHostPort(t.addr, "443")
|
||||
}
|
||||
t.serverName = host
|
||||
}
|
||||
|
||||
return t, nil
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/nadoo/glider/log"
|
||||
"github.com/nadoo/glider/pool"
|
||||
@ -37,14 +36,25 @@ func init() {
|
||||
func NewTrojan(s string, d proxy.Dialer, p proxy.Proxy) (*Trojan, error) {
|
||||
u, err := url.Parse(s)
|
||||
if err != nil {
|
||||
log.F("[trojan] parse err: %s", err)
|
||||
log.F("[trojan] parse url err: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := u.Query()
|
||||
t := &Trojan{
|
||||
dialer: d,
|
||||
proxy: p,
|
||||
addr: u.Host,
|
||||
dialer: d,
|
||||
proxy: p,
|
||||
addr: u.Host,
|
||||
skipVerify: query.Get("skipVerify") == "true",
|
||||
serverName: query.Get("serverName"),
|
||||
}
|
||||
|
||||
if t.serverName == "" {
|
||||
host, port, _ := net.SplitHostPort(t.addr)
|
||||
if port == "" {
|
||||
t.addr = net.JoinHostPort(t.addr, "443")
|
||||
}
|
||||
t.serverName = host
|
||||
}
|
||||
|
||||
// pass
|
||||
@ -52,24 +62,12 @@ func NewTrojan(s string, d proxy.Dialer, p proxy.Proxy) (*Trojan, error) {
|
||||
hash.Write([]byte(u.User.Username()))
|
||||
hex.Encode(t.pass[:], hash.Sum(nil))
|
||||
|
||||
// serverName
|
||||
colonPos := strings.LastIndex(t.addr, ":")
|
||||
if colonPos == -1 {
|
||||
colonPos = len(t.addr)
|
||||
}
|
||||
t.serverName = t.addr[:colonPos]
|
||||
|
||||
// skipVerify
|
||||
if u.Query().Get("skipVerify") == "true" {
|
||||
t.skipVerify = true
|
||||
}
|
||||
|
||||
t.tlsConfig = &tls.Config{
|
||||
ServerName: t.serverName,
|
||||
InsecureSkipVerify: t.skipVerify,
|
||||
NextProtos: []string{"http/1.1"},
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(64),
|
||||
MinVersion: tls.VersionTLS10,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
}
|
||||
|
||||
return t, nil
|
||||
|
@ -117,7 +117,7 @@ func ReadAddrString(r io.Reader) (string, error) {
|
||||
return AddrString(atyp, host, port), nil
|
||||
}
|
||||
|
||||
// AddrString returns a addr string inf format "host:port".
|
||||
// AddrString returns a addr string in format of "host:port".
|
||||
func AddrString(atyp Atyp, addr Addr, port Port) string {
|
||||
var host string
|
||||
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/nadoo/glider/log"
|
||||
"github.com/nadoo/glider/proxy"
|
||||
@ -39,26 +38,20 @@ func NewWS(s string, d proxy.Dialer) (*WS, error) {
|
||||
addr = d.Addr()
|
||||
}
|
||||
|
||||
host := u.Query().Get("host")
|
||||
if host == "" {
|
||||
colonPos := strings.LastIndex(addr, ":")
|
||||
if colonPos == -1 {
|
||||
colonPos = len(addr)
|
||||
}
|
||||
host = addr[:colonPos]
|
||||
}
|
||||
|
||||
client, err := NewClient(host, u.Path)
|
||||
if err != nil {
|
||||
log.F("[ws] create ws client error: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := &WS{
|
||||
dialer: d,
|
||||
addr: addr,
|
||||
host: host,
|
||||
client: client,
|
||||
host: u.Query().Get("host"),
|
||||
}
|
||||
|
||||
if p.host == "" {
|
||||
p.host, _, _ = net.SplitHostPort(addr)
|
||||
}
|
||||
|
||||
p.client, err = NewClient(p.host, u.Path)
|
||||
if err != nil {
|
||||
log.F("[ws] create ws client error: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
|
Loading…
Reference in New Issue
Block a user