mirror of
https://github.com/Snawoot/opera-proxy.git
synced 2025-09-02 02:30:21 +00:00
SNI control
This commit is contained in:
parent
7b2b1cb562
commit
62628c8606
2 changed files with 20 additions and 4 deletions
|
@ -65,16 +65,18 @@ type ContextDialer interface {
|
||||||
type ProxyDialer struct {
|
type ProxyDialer struct {
|
||||||
address stringCb
|
address stringCb
|
||||||
tlsServerName stringCb
|
tlsServerName stringCb
|
||||||
|
fakeSNI stringCb
|
||||||
auth stringCb
|
auth stringCb
|
||||||
next ContextDialer
|
next ContextDialer
|
||||||
intermediateWorkaround bool
|
intermediateWorkaround bool
|
||||||
caPool *x509.CertPool
|
caPool *x509.CertPool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProxyDialer(address, tlsServerName, auth stringCb, intermediateWorkaround bool, caPool *x509.CertPool, nextDialer ContextDialer) *ProxyDialer {
|
func NewProxyDialer(address, tlsServerName, fakeSNI, auth stringCb, intermediateWorkaround bool, caPool *x509.CertPool, nextDialer ContextDialer) *ProxyDialer {
|
||||||
return &ProxyDialer{
|
return &ProxyDialer{
|
||||||
address: address,
|
address: address,
|
||||||
tlsServerName: tlsServerName,
|
tlsServerName: tlsServerName,
|
||||||
|
fakeSNI: fakeSNI,
|
||||||
auth: auth,
|
auth: auth,
|
||||||
next: nextDialer,
|
next: nextDialer,
|
||||||
intermediateWorkaround: intermediateWorkaround,
|
intermediateWorkaround: intermediateWorkaround,
|
||||||
|
@ -109,7 +111,14 @@ func ProxyDialerFromURL(u *url.URL, next ContextDialer) (*ProxyDialer, error) {
|
||||||
password, _ := u.User.Password()
|
password, _ := u.User.Password()
|
||||||
auth = WrapStringToCb(BasicAuthHeader(username, password))
|
auth = WrapStringToCb(BasicAuthHeader(username, password))
|
||||||
}
|
}
|
||||||
return NewProxyDialer(WrapStringToCb(address), WrapStringToCb(tlsServerName), auth, false, nil, next), nil
|
return NewProxyDialer(
|
||||||
|
WrapStringToCb(address),
|
||||||
|
WrapStringToCb(tlsServerName),
|
||||||
|
WrapStringToCb(tlsServerName),
|
||||||
|
auth,
|
||||||
|
false,
|
||||||
|
nil,
|
||||||
|
next), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ProxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
func (d *ProxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
@ -132,12 +141,16 @@ func (d *ProxyDialer) DialContext(ctx context.Context, network, address string)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
fakeSNI, err := d.fakeSNI()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
if uTLSServerName != "" {
|
if uTLSServerName != "" {
|
||||||
// Custom cert verification logic:
|
// Custom cert verification logic:
|
||||||
// DO NOT send SNI extension of TLS ClientHello
|
// DO NOT send SNI extension of TLS ClientHello
|
||||||
// DO peer certificate verification against specified servername
|
// DO peer certificate verification against specified servername
|
||||||
conn = tls.Client(conn, &tls.Config{
|
conn = tls.Client(conn, &tls.Config{
|
||||||
ServerName: "",
|
ServerName: fakeSNI,
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
VerifyConnection: func(cs tls.ConnectionState) error {
|
VerifyConnection: func(cs tls.ConnectionState) error {
|
||||||
opts := x509.VerifyOptions{
|
opts := x509.VerifyOptions{
|
||||||
|
|
5
main.go
5
main.go
|
@ -102,6 +102,7 @@ type CLIArgs struct {
|
||||||
initRetryInterval time.Duration
|
initRetryInterval time.Duration
|
||||||
certChainWorkaround bool
|
certChainWorkaround bool
|
||||||
caFile string
|
caFile string
|
||||||
|
fakeSNI string
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse_args() *CLIArgs {
|
func parse_args() *CLIArgs {
|
||||||
|
@ -147,6 +148,7 @@ func parse_args() *CLIArgs {
|
||||||
flag.BoolVar(&args.certChainWorkaround, "certchain-workaround", true,
|
flag.BoolVar(&args.certChainWorkaround, "certchain-workaround", true,
|
||||||
"add bundled cross-signed intermediate cert to certchain to make it check out on old systems")
|
"add bundled cross-signed intermediate cert to certchain to make it check out on old systems")
|
||||||
flag.StringVar(&args.caFile, "cafile", "", "use custom CA certificate bundle file")
|
flag.StringVar(&args.caFile, "cafile", "", "use custom CA certificate bundle file")
|
||||||
|
flag.StringVar(&args.fakeSNI, "fake-SNI", "", "domain name to use as SNI in communications with servers")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if args.country == "" {
|
if args.country == "" {
|
||||||
arg_fail("Country can't be empty string.")
|
arg_fail("Country can't be empty string.")
|
||||||
|
@ -223,7 +225,7 @@ func run() int {
|
||||||
// Dialing w/o SNI, receiving self-signed certificate, so skip verification.
|
// Dialing w/o SNI, receiving self-signed certificate, so skip verification.
|
||||||
// Either way we'll validate certificate of actual proxy server.
|
// Either way we'll validate certificate of actual proxy server.
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
ServerName: "",
|
ServerName: args.fakeSNI,
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
}
|
}
|
||||||
seclient, err := se.NewSEClient(args.apiLogin, args.apiPassword, &http.Transport{
|
seclient, err := se.NewSEClient(args.apiLogin, args.apiPassword, &http.Transport{
|
||||||
|
@ -337,6 +339,7 @@ func run() int {
|
||||||
handlerDialer := dialer.NewProxyDialer(
|
handlerDialer := dialer.NewProxyDialer(
|
||||||
dialer.WrapStringToCb(endpoint.NetAddr()),
|
dialer.WrapStringToCb(endpoint.NetAddr()),
|
||||||
dialer.WrapStringToCb(fmt.Sprintf("%s0.%s", args.country, PROXY_SUFFIX)),
|
dialer.WrapStringToCb(fmt.Sprintf("%s0.%s", args.country, PROXY_SUFFIX)),
|
||||||
|
dialer.WrapStringToCb(args.fakeSNI),
|
||||||
func() (string, error) {
|
func() (string, error) {
|
||||||
return dialer.BasicAuthHeader(seclient.GetProxyCredentials()), nil
|
return dialer.BasicAuthHeader(seclient.GetProxyCredentials()), nil
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue