SNI control

This commit is contained in:
Vladislav Yarmak 2024-12-21 20:47:28 +02:00
parent 7b2b1cb562
commit 62628c8606
2 changed files with 20 additions and 4 deletions

View file

@ -65,16 +65,18 @@ type ContextDialer interface {
type ProxyDialer struct {
address stringCb
tlsServerName stringCb
fakeSNI stringCb
auth stringCb
next ContextDialer
intermediateWorkaround bool
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{
address: address,
tlsServerName: tlsServerName,
fakeSNI: fakeSNI,
auth: auth,
next: nextDialer,
intermediateWorkaround: intermediateWorkaround,
@ -109,7 +111,14 @@ func ProxyDialerFromURL(u *url.URL, next ContextDialer) (*ProxyDialer, error) {
password, _ := u.User.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) {
@ -132,12 +141,16 @@ func (d *ProxyDialer) DialContext(ctx context.Context, network, address string)
if err != nil {
return nil, err
}
fakeSNI, err := d.fakeSNI()
if err != nil {
return nil, err
}
if uTLSServerName != "" {
// Custom cert verification logic:
// DO NOT send SNI extension of TLS ClientHello
// DO peer certificate verification against specified servername
conn = tls.Client(conn, &tls.Config{
ServerName: "",
ServerName: fakeSNI,
InsecureSkipVerify: true,
VerifyConnection: func(cs tls.ConnectionState) error {
opts := x509.VerifyOptions{

View file

@ -102,6 +102,7 @@ type CLIArgs struct {
initRetryInterval time.Duration
certChainWorkaround bool
caFile string
fakeSNI string
}
func parse_args() *CLIArgs {
@ -147,6 +148,7 @@ func parse_args() *CLIArgs {
flag.BoolVar(&args.certChainWorkaround, "certchain-workaround", true,
"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.fakeSNI, "fake-SNI", "", "domain name to use as SNI in communications with servers")
flag.Parse()
if args.country == "" {
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.
// Either way we'll validate certificate of actual proxy server.
tlsConfig := &tls.Config{
ServerName: "",
ServerName: args.fakeSNI,
InsecureSkipVerify: true,
}
seclient, err := se.NewSEClient(args.apiLogin, args.apiPassword, &http.Transport{
@ -337,6 +339,7 @@ func run() int {
handlerDialer := dialer.NewProxyDialer(
dialer.WrapStringToCb(endpoint.NetAddr()),
dialer.WrapStringToCb(fmt.Sprintf("%s0.%s", args.country, PROXY_SUFFIX)),
dialer.WrapStringToCb(args.fakeSNI),
func() (string, error) {
return dialer.BasicAuthHeader(seclient.GetProxyCredentials()), nil
},