github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/control/tlsping.go (about)

     1  package control
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"flag"
     7  	"fmt"
     8  	"net"
     9  
    10  	"v2ray.com/core/common"
    11  )
    12  
    13  type TlsPingCommand struct{}
    14  
    15  func (c *TlsPingCommand) Name() string {
    16  	return "tlsping"
    17  }
    18  
    19  func (c *TlsPingCommand) Description() Description {
    20  	return Description{
    21  		Short: "Ping the domain with TLS handshake",
    22  		Usage: []string{"v2ctl tlsping <domain> --ip <ip>"},
    23  	}
    24  }
    25  
    26  func printCertificates(certs []*x509.Certificate) {
    27  	for _, cert := range certs {
    28  		if len(cert.DNSNames) == 0 {
    29  			continue
    30  		}
    31  		fmt.Println("Allowed domains: ", cert.DNSNames)
    32  	}
    33  }
    34  
    35  func (c *TlsPingCommand) Execute(args []string) error {
    36  	fs := flag.NewFlagSet(c.Name(), flag.ContinueOnError)
    37  	ipStr := fs.String("ip", "", "IP address of the domain")
    38  
    39  	if err := fs.Parse(args); err != nil {
    40  		return newError("flag parsing").Base(err)
    41  	}
    42  
    43  	if fs.NArg() < 1 {
    44  		return newError("domain not specified")
    45  	}
    46  
    47  	domain := fs.Arg(0)
    48  	fmt.Println("Tls ping: ", domain)
    49  
    50  	var ip net.IP
    51  	if len(*ipStr) > 0 {
    52  		v := net.ParseIP(*ipStr)
    53  		if v == nil {
    54  			return newError("invalid IP: ", *ipStr)
    55  		}
    56  		ip = v
    57  	} else {
    58  		v, err := net.ResolveIPAddr("ip", domain)
    59  		if err != nil {
    60  			return newError("resolve IP").Base(err)
    61  		}
    62  		ip = v.IP
    63  	}
    64  	fmt.Println("Using IP: ", ip.String())
    65  
    66  	fmt.Println("-------------------")
    67  	fmt.Println("Pinging without SNI")
    68  	{
    69  		tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443})
    70  		if err != nil {
    71  			return newError("dial tcp").Base(err)
    72  		}
    73  		tlsConn := tls.Client(tcpConn, &tls.Config{
    74  			InsecureSkipVerify: true,
    75  			NextProtos:         []string{"http/1.1"},
    76  			MaxVersion:         tls.VersionTLS12,
    77  			MinVersion:         tls.VersionTLS12,
    78  		})
    79  		err = tlsConn.Handshake()
    80  		if err != nil {
    81  			fmt.Println("Handshake failure: ", err)
    82  		} else {
    83  			fmt.Println("Handshake succeeded")
    84  			printCertificates(tlsConn.ConnectionState().PeerCertificates)
    85  		}
    86  		tlsConn.Close()
    87  	}
    88  
    89  	fmt.Println("-------------------")
    90  	fmt.Println("Pinging with SNI")
    91  	{
    92  		tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443})
    93  		if err != nil {
    94  			return newError("dial tcp").Base(err)
    95  		}
    96  		tlsConn := tls.Client(tcpConn, &tls.Config{
    97  			ServerName: domain,
    98  			NextProtos: []string{"http/1.1"},
    99  			MaxVersion: tls.VersionTLS12,
   100  			MinVersion: tls.VersionTLS12,
   101  		})
   102  		err = tlsConn.Handshake()
   103  		if err != nil {
   104  			fmt.Println("handshake failure: ", err)
   105  		} else {
   106  			fmt.Println("handshake succeeded")
   107  			printCertificates(tlsConn.ConnectionState().PeerCertificates)
   108  		}
   109  		tlsConn.Close()
   110  	}
   111  
   112  	fmt.Println("Tls ping finished")
   113  
   114  	return nil
   115  }
   116  
   117  func init() {
   118  	common.Must(RegisterCommand(&TlsPingCommand{}))
   119  }