github.com/eagleql/xray-core@v1.4.4/main/commands/all/tls/ping.go (about)

     1  package tls
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"fmt"
     7  	"net"
     8  
     9  	"github.com/eagleql/xray-core/main/commands/base"
    10  )
    11  
    12  // cmdPing is the tls ping command
    13  var cmdPing = &base.Command{
    14  	UsageLine: "{{.Exec}} tls ping [-ip <ip>] <domain>",
    15  	Short:     "Ping the domain with TLS handshake",
    16  	Long: `
    17  Ping the domain with TLS handshake.
    18  
    19  Arguments:
    20  
    21  	-ip
    22  		The IP address of the domain.
    23  `,
    24  }
    25  
    26  func init() {
    27  	cmdPing.Run = executePing // break init loop
    28  }
    29  
    30  var (
    31  	pingIPStr = cmdPing.Flag.String("ip", "", "")
    32  )
    33  
    34  func executePing(cmd *base.Command, args []string) {
    35  	if cmdPing.Flag.NArg() < 1 {
    36  		base.Fatalf("domain not specified")
    37  	}
    38  
    39  	domain := cmdPing.Flag.Arg(0)
    40  	fmt.Println("Tls ping: ", domain)
    41  
    42  	var ip net.IP
    43  	if len(*pingIPStr) > 0 {
    44  		v := net.ParseIP(*pingIPStr)
    45  		if v == nil {
    46  			base.Fatalf("invalid IP: %s", *pingIPStr)
    47  		}
    48  		ip = v
    49  	} else {
    50  		v, err := net.ResolveIPAddr("ip", domain)
    51  		if err != nil {
    52  			base.Fatalf("Failed to resolve IP: %s", err)
    53  		}
    54  		ip = v.IP
    55  	}
    56  	fmt.Println("Using IP: ", ip.String())
    57  
    58  	fmt.Println("-------------------")
    59  	fmt.Println("Pinging without SNI")
    60  	{
    61  		tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443})
    62  		if err != nil {
    63  			base.Fatalf("Failed to dial tcp: %s", err)
    64  		}
    65  		tlsConn := tls.Client(tcpConn, &tls.Config{
    66  			InsecureSkipVerify: true,
    67  			NextProtos:         []string{"http/1.1"},
    68  			MaxVersion:         tls.VersionTLS12,
    69  			MinVersion:         tls.VersionTLS12,
    70  		})
    71  		err = tlsConn.Handshake()
    72  		if err != nil {
    73  			fmt.Println("Handshake failure: ", err)
    74  		} else {
    75  			fmt.Println("Handshake succeeded")
    76  			printCertificates(tlsConn.ConnectionState().PeerCertificates)
    77  		}
    78  		tlsConn.Close()
    79  	}
    80  
    81  	fmt.Println("-------------------")
    82  	fmt.Println("Pinging with SNI")
    83  	{
    84  		tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443})
    85  		if err != nil {
    86  			base.Fatalf("Failed to dial tcp: %s", err)
    87  		}
    88  		tlsConn := tls.Client(tcpConn, &tls.Config{
    89  			ServerName: domain,
    90  			NextProtos: []string{"http/1.1"},
    91  			MaxVersion: tls.VersionTLS12,
    92  			MinVersion: tls.VersionTLS12,
    93  		})
    94  		err = tlsConn.Handshake()
    95  		if err != nil {
    96  			fmt.Println("handshake failure: ", err)
    97  		} else {
    98  			fmt.Println("handshake succeeded")
    99  			printCertificates(tlsConn.ConnectionState().PeerCertificates)
   100  		}
   101  		tlsConn.Close()
   102  	}
   103  
   104  	fmt.Println("Tls ping finished")
   105  }
   106  
   107  func printCertificates(certs []*x509.Certificate) {
   108  	for _, cert := range certs {
   109  		if len(cert.DNSNames) == 0 {
   110  			continue
   111  		}
   112  		fmt.Println("Allowed domains: ", cert.DNSNames)
   113  	}
   114  }