tlsping.go 2.6 KB

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