mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 17:35:40 +08:00
listener with tls transport layer
This commit is contained in:
parent
5383ac4fc0
commit
e27601f648
2
main.go
2
main.go
@ -81,7 +81,7 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
go local.ListenAndServe()
|
||||
go local.ListenAndServe(nil)
|
||||
}
|
||||
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
|
@ -6,7 +6,6 @@ package http
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -28,17 +27,12 @@ type HTTP struct {
|
||||
addr string
|
||||
user string
|
||||
password string
|
||||
}
|
||||
|
||||
type HTTPS struct {
|
||||
HTTP
|
||||
tlsConfig *tls.Config
|
||||
pretendAsWebServer bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
proxy.RegisterDialer("http", NewHTTPDialer)
|
||||
proxy.RegisterServer("http", NewHTTPServer)
|
||||
proxy.RegisterServer("https", NewHTTPSServer)
|
||||
}
|
||||
|
||||
// NewHTTP returns a http proxy.
|
||||
@ -58,40 +52,17 @@ func NewHTTP(s string, dialer proxy.Dialer) (*HTTP, error) {
|
||||
addr: addr,
|
||||
user: user,
|
||||
password: pass,
|
||||
pretendAsWebServer: false,
|
||||
}
|
||||
|
||||
pretend := u.Query().Get("pretend")
|
||||
if pretend != "" {
|
||||
h.pretendAsWebServer = true
|
||||
}
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func NewHTTPS(s string, dialer proxy.Dialer) (*HTTPS, error) {
|
||||
u, _ := url.Parse(s)
|
||||
// TODO: cert=&key=
|
||||
certFile := u.Query().Get("cert")
|
||||
keyFile := u.Query().Get("key")
|
||||
|
||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||
if err != nil {
|
||||
log.F("unabled load cert: %s, key %s", certFile, keyFile)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsConfig := tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
}
|
||||
|
||||
http, err := NewHTTP(s, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
https := &HTTPS{
|
||||
HTTP: *http,
|
||||
tlsConfig: &tlsConfig,
|
||||
}
|
||||
|
||||
return https, nil
|
||||
}
|
||||
|
||||
// NewHTTPDialer returns a http proxy dialer.
|
||||
func NewHTTPDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
|
||||
return NewHTTP(s, dialer)
|
||||
@ -102,34 +73,9 @@ func NewHTTPServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
return NewHTTP(s, dialer)
|
||||
}
|
||||
|
||||
// NewHTTPSServer returns a https proxy server
|
||||
func NewHTTPSServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
return NewHTTPS(s, dialer)
|
||||
}
|
||||
|
||||
// ListenAndServe serves tls http proxy
|
||||
func (s *HTTPS) ListenAndServe() {
|
||||
l, err := tls.Listen("tcp", s.addr, s.tlsConfig)
|
||||
if err != nil {
|
||||
log.F("failed to listen on tls %s: %v", s.addr, err)
|
||||
return
|
||||
}
|
||||
|
||||
defer l.Close()
|
||||
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
log.F("[https] failed to accept: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
go s.HTTP.Serve(c)
|
||||
}
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *HTTP) ListenAndServe() {
|
||||
func (s *HTTP) ListenAndServe(c net.Conn) {
|
||||
if c == nil {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.F("failed to listen on %s: %v", s.addr, err)
|
||||
@ -146,10 +92,12 @@ func (s *HTTP) ListenAndServe() {
|
||||
continue
|
||||
}
|
||||
|
||||
go s.Serve(c)
|
||||
}
|
||||
} else {
|
||||
go s.Serve(c)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Serve .
|
||||
func (s *HTTP) Serve(c net.Conn) {
|
||||
@ -166,8 +114,15 @@ func (s *HTTP) Serve(c net.Conn) {
|
||||
return
|
||||
}
|
||||
|
||||
if s.pretendAsWebServer {
|
||||
fmt.Fprintf(c, "%s 404 Not Found\r\nServer: nginx\r\n\r\n", proto)
|
||||
log.F("[http pretender] being accessed as web server from %s", c.RemoteAddr().String())
|
||||
return
|
||||
}
|
||||
|
||||
if method == "CONNECT" {
|
||||
s.servHTTPS(method, requestURI, proto, c)
|
||||
//c.Write([]byte("HTTP/1.1 405\nAllow: GET, POST, HEAD, OPTION, PATCH\nServer: vsps/1.2\nContent-Type: \n\n"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ type MixedProxy struct {
|
||||
|
||||
http *http.HTTP
|
||||
socks5 *socks5.SOCKS5
|
||||
|
||||
pretendAsWebServer bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -45,9 +47,16 @@ func NewMixedProxy(s string, dialer proxy.Dialer) (*MixedProxy, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pretend := u.Query().Get("pretend")
|
||||
|
||||
p := &MixedProxy{
|
||||
dialer: dialer,
|
||||
addr: u.Host,
|
||||
pretendAsWebServer: false,
|
||||
}
|
||||
|
||||
if pretend == "true" {
|
||||
p.pretendAsWebServer = true
|
||||
}
|
||||
|
||||
p.http, _ = http.NewHTTP(s, dialer)
|
||||
@ -62,18 +71,18 @@ func NewMixedProxyServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (p *MixedProxy) ListenAndServe() {
|
||||
func (p *MixedProxy) ListenAndServe(c net.Conn) {
|
||||
|
||||
if c == nil {
|
||||
go p.socks5.ListenAndServeUDP()
|
||||
|
||||
l, err := net.Listen("tcp", p.addr)
|
||||
|
||||
//l, err := net.Listen("tcp", p.addr)
|
||||
if err != nil {
|
||||
log.F("[mixed] failed to listen on %s: %v", p.addr, err)
|
||||
return
|
||||
}
|
||||
|
||||
log.F("[mixed] listening TCP on %s", p.addr)
|
||||
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
@ -81,6 +90,9 @@ func (p *MixedProxy) ListenAndServe() {
|
||||
continue
|
||||
}
|
||||
|
||||
go p.Serve(c)
|
||||
}
|
||||
} else {
|
||||
go p.Serve(c)
|
||||
}
|
||||
}
|
||||
@ -98,7 +110,7 @@ func (p *MixedProxy) Serve(c net.Conn) {
|
||||
if p.socks5 != nil {
|
||||
head, err := cc.Peek(1)
|
||||
if err != nil {
|
||||
log.F("[mixed] peek error: %s", err)
|
||||
log.F("[mixed] socks5 peek error: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -112,7 +124,7 @@ func (p *MixedProxy) Serve(c net.Conn) {
|
||||
if p.http != nil {
|
||||
head, err := cc.Peek(8)
|
||||
if err != nil {
|
||||
log.F("[mixed] peek error: %s", err)
|
||||
log.F("[mixed] http peek error: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ func NewRedir6Server(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *RedirProxy) ListenAndServe() {
|
||||
func (s *RedirProxy) ListenAndServe(_ net.Conn) {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.F("[redir] failed to listen on %s: %v", s.addr, err)
|
||||
|
@ -2,6 +2,7 @@ package proxy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
@ -11,7 +12,7 @@ import (
|
||||
// Server interface
|
||||
type Server interface {
|
||||
// ListenAndServe as proxy server, use only in server mode.
|
||||
ListenAndServe()
|
||||
ListenAndServe(net.Conn)
|
||||
}
|
||||
|
||||
// ServerCreator is a function to create proxy servers.
|
||||
|
@ -76,13 +76,14 @@ func NewSocks5Server(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe serves socks5 requests.
|
||||
func (s *SOCKS5) ListenAndServe() {
|
||||
func (s *SOCKS5) ListenAndServe(c net.Conn) {
|
||||
go s.ListenAndServeUDP()
|
||||
s.ListenAndServeTCP()
|
||||
s.ListenAndServeTCP(c)
|
||||
}
|
||||
|
||||
// ListenAndServeTCP .
|
||||
func (s *SOCKS5) ListenAndServeTCP() {
|
||||
func (s *SOCKS5) ListenAndServeTCP(c net.Conn) {
|
||||
if c == nil {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.F("[socks5] failed to listen on %s: %v", s.addr, err)
|
||||
@ -98,6 +99,9 @@ func (s *SOCKS5) ListenAndServeTCP() {
|
||||
continue
|
||||
}
|
||||
|
||||
go s.ServeTCP(c)
|
||||
}
|
||||
} else {
|
||||
go s.ServeTCP(c)
|
||||
}
|
||||
}
|
||||
|
@ -66,13 +66,14 @@ func NewSSServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe serves ss requests.
|
||||
func (s *SS) ListenAndServe() {
|
||||
func (s *SS) ListenAndServe(c net.Conn) {
|
||||
go s.ListenAndServeUDP()
|
||||
s.ListenAndServeTCP()
|
||||
s.ListenAndServeTCP(c)
|
||||
}
|
||||
|
||||
// ListenAndServeTCP serves tcp ss requests.
|
||||
func (s *SS) ListenAndServeTCP() {
|
||||
func (s *SS) ListenAndServeTCP(c net.Conn) {
|
||||
if c == nil {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.F("[ss] failed to listen on %s: %v", s.addr, err)
|
||||
@ -89,6 +90,9 @@ func (s *SS) ListenAndServeTCP() {
|
||||
}
|
||||
go s.ServeTCP(c)
|
||||
}
|
||||
} else {
|
||||
go s.ServeTCP(c)
|
||||
}
|
||||
}
|
||||
|
||||
// ServeTCP serves tcp ss requests.
|
||||
|
@ -48,7 +48,7 @@ func NewTCPTunServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *TCPTun) ListenAndServe() {
|
||||
func (s *TCPTun) ListenAndServe(_ net.Conn) {
|
||||
l, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
log.F("failed to listen on %s: %v", s.addr, err)
|
||||
|
107
proxy/tls/tls.go
107
proxy/tls/tls.go
@ -3,6 +3,7 @@ package tls
|
||||
import (
|
||||
stdtls "crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
@ -18,10 +19,17 @@ type TLS struct {
|
||||
|
||||
serverName string
|
||||
skipVerify bool
|
||||
|
||||
certFile string
|
||||
keyFile string
|
||||
|
||||
server proxy.Server
|
||||
serverProto string
|
||||
}
|
||||
|
||||
func init() {
|
||||
proxy.RegisterDialer("tls", NewTLSDialer)
|
||||
proxy.RegisterServer("tls", NewTLSTransport)
|
||||
}
|
||||
|
||||
// NewTLS returns a tls proxy.
|
||||
@ -48,6 +56,8 @@ func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
|
||||
addr: addr,
|
||||
serverName: serverName,
|
||||
skipVerify: false,
|
||||
certFile: "",
|
||||
keyFile: "",
|
||||
}
|
||||
|
||||
if skipVerify == "true" {
|
||||
@ -57,6 +67,100 @@ func NewTLS(s string, dialer proxy.Dialer) (*TLS, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// NewTLSServerTransport returns a tls transport layer before the real server
|
||||
func NewTLSTransport(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
transport := strings.Split(s, ",")
|
||||
|
||||
// prepare transport listener
|
||||
if len(transport) != 2 {
|
||||
err := fmt.Errorf("malformd listener: %s", s)
|
||||
log.F(err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u, err := url.Parse(transport[0])
|
||||
if err != nil {
|
||||
log.F("parse url err: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO: cert=&key=
|
||||
query := u.Query()
|
||||
|
||||
certFile := query.Get("cert")
|
||||
keyFile := query.Get("key")
|
||||
|
||||
addr := u.Host
|
||||
colonPos := strings.LastIndex(addr, ":")
|
||||
if colonPos == -1 {
|
||||
colonPos = len(addr)
|
||||
}
|
||||
serverName := addr[:colonPos]
|
||||
|
||||
p := &TLS{
|
||||
dialer: dialer,
|
||||
addr: addr,
|
||||
serverName: serverName,
|
||||
skipVerify: false,
|
||||
certFile: certFile,
|
||||
keyFile: keyFile,
|
||||
serverProto: transport[1],
|
||||
}
|
||||
|
||||
// prepare layer 7 server
|
||||
p.server, err = proxy.ServerFromURL(transport[1], dialer)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (s *TLS) ListenAndServe(c net.Conn) {
|
||||
// c for TCP_FAST_OPEN
|
||||
|
||||
var tlsConfig *stdtls.Config
|
||||
|
||||
var ticketKey [32]byte
|
||||
copy(ticketKey[:], "f8710951c1f6d0d95a95eed5e99b51f1")
|
||||
|
||||
if s.certFile != "" && s.keyFile != "" {
|
||||
cert, err := stdtls.LoadX509KeyPair(s.certFile, s.keyFile)
|
||||
if err != nil {
|
||||
log.F("unabled load cert: %s, key %s", s.certFile, s.keyFile)
|
||||
return
|
||||
}
|
||||
|
||||
tlsConfig = &stdtls.Config{
|
||||
Certificates: []stdtls.Certificate{cert},
|
||||
MinVersion: stdtls.VersionTLS12,
|
||||
MaxVersion: stdtls.VersionTLS13,
|
||||
SessionTicketKey: ticketKey,
|
||||
Accept0RTTData: true,
|
||||
}
|
||||
} else {
|
||||
tlsConfig = nil
|
||||
}
|
||||
|
||||
l, err := stdtls.Listen("tcp", s.addr, tlsConfig)
|
||||
if err != nil {
|
||||
log.F("failed to listen on tls %s: %v", s.addr, err)
|
||||
return
|
||||
}
|
||||
|
||||
defer l.Close()
|
||||
|
||||
log.F("listening TCP on %s with TLS", s.addr)
|
||||
|
||||
for {
|
||||
c, err := l.Accept()
|
||||
if err != nil {
|
||||
log.F("[https] failed to accept: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// it's callee's response to decide process request in sync/async mode.
|
||||
s.server.ListenAndServe(c)
|
||||
}
|
||||
}
|
||||
|
||||
// NewTLSDialer returns a tls proxy dialer.
|
||||
func NewTLSDialer(s string, dialer proxy.Dialer) (proxy.Dialer, error) {
|
||||
return NewTLS(s, dialer)
|
||||
@ -79,6 +183,9 @@ func (s *TLS) Dial(network, addr string) (net.Conn, error) {
|
||||
conf := &stdtls.Config{
|
||||
ServerName: s.serverName,
|
||||
InsecureSkipVerify: s.skipVerify,
|
||||
ClientSessionCache: stdtls.NewLRUClientSessionCache(64),
|
||||
MinVersion: stdtls.VersionTLS12,
|
||||
MaxVersion: stdtls.VersionTLS13,
|
||||
}
|
||||
|
||||
c := stdtls.Client(cc, conf)
|
||||
|
@ -51,7 +51,7 @@ func NewTProxyServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *TProxy) ListenAndServe() {
|
||||
func (s *TProxy) ListenAndServe(_ net.Conn) {
|
||||
// go s.ListenAndServeTCP()
|
||||
s.ListenAndServeUDP()
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ func NewUDPTunServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *UDPTun) ListenAndServe() {
|
||||
func (s *UDPTun) ListenAndServe(_ net.Conn) {
|
||||
c, err := net.ListenPacket("udp", s.addr)
|
||||
if err != nil {
|
||||
log.F("[udptun] failed to listen on %s: %v", s.addr, err)
|
||||
|
@ -50,7 +50,7 @@ func NewUoTTunServer(s string, dialer proxy.Dialer) (proxy.Server, error) {
|
||||
}
|
||||
|
||||
// ListenAndServe .
|
||||
func (s *UoTTun) ListenAndServe() {
|
||||
func (s *UoTTun) ListenAndServe(_ net.Conn) {
|
||||
c, err := net.ListenPacket("udp", s.addr)
|
||||
if err != nil {
|
||||
log.F("[uottun] failed to listen on %s: %v", s.addr, err)
|
||||
|
Loading…
Reference in New Issue
Block a user