github.com/moqsien/xraycore@v1.8.5/main/commands/all/tls/ping.go (about) 1 package tls 2 3 import ( 4 gotls "crypto/tls" 5 "crypto/x509" 6 "encoding/base64" 7 "fmt" 8 "net" 9 10 "github.com/moqsien/xraycore/main/commands/base" 11 . "github.com/moqsien/xraycore/transport/internet/tls" 12 ) 13 14 // cmdPing is the tls ping command 15 var cmdPing = &base.Command{ 16 UsageLine: "{{.Exec}} tls ping [-ip <ip>] <domain>", 17 Short: "Ping the domain with TLS handshake", 18 Long: ` 19 Ping the domain with TLS handshake. 20 21 Arguments: 22 23 -ip 24 The IP address of the domain. 25 `, 26 } 27 28 func init() { 29 cmdPing.Run = executePing // break init loop 30 } 31 32 var pingIPStr = cmdPing.Flag.String("ip", "", "") 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 := gotls.Client(tcpConn, &gotls.Config{ 66 InsecureSkipVerify: true, 67 NextProtos: []string{"http/1.1"}, 68 MaxVersion: gotls.VersionTLS12, 69 MinVersion: gotls.VersionTLS12, 70 // Do not release tool before v5's refactor 71 // VerifyPeerCertificate: showCert(), 72 }) 73 err = tlsConn.Handshake() 74 if err != nil { 75 fmt.Println("Handshake failure: ", err) 76 } else { 77 fmt.Println("Handshake succeeded") 78 printCertificates(tlsConn.ConnectionState().PeerCertificates) 79 } 80 tlsConn.Close() 81 } 82 83 fmt.Println("-------------------") 84 fmt.Println("Pinging with SNI") 85 { 86 tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443}) 87 if err != nil { 88 base.Fatalf("Failed to dial tcp: %s", err) 89 } 90 tlsConn := gotls.Client(tcpConn, &gotls.Config{ 91 ServerName: domain, 92 NextProtos: []string{"http/1.1"}, 93 MaxVersion: gotls.VersionTLS12, 94 MinVersion: gotls.VersionTLS12, 95 // Do not release tool before v5's refactor 96 // VerifyPeerCertificate: showCert(), 97 }) 98 err = tlsConn.Handshake() 99 if err != nil { 100 fmt.Println("handshake failure: ", err) 101 } else { 102 fmt.Println("handshake succeeded") 103 printCertificates(tlsConn.ConnectionState().PeerCertificates) 104 } 105 tlsConn.Close() 106 } 107 108 fmt.Println("Tls ping finished") 109 } 110 111 func printCertificates(certs []*x509.Certificate) { 112 for _, cert := range certs { 113 if len(cert.DNSNames) == 0 { 114 continue 115 } 116 fmt.Println("Allowed domains: ", cert.DNSNames) 117 } 118 } 119 120 func showCert() func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 121 return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { 122 hash := GenerateCertChainHash(rawCerts) 123 fmt.Println("Certificate Chain Hash: ", base64.StdEncoding.EncodeToString(hash)) 124 return nil 125 } 126 }