mirror of https://github.com/v2ray/v2ray-core
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
2.6 KiB
119 lines
2.6 KiB
package control |
|
|
|
import ( |
|
"crypto/tls" |
|
"crypto/x509" |
|
"flag" |
|
"fmt" |
|
"net" |
|
|
|
"v2ray.com/core/common" |
|
) |
|
|
|
type TlsPingCommand struct{} |
|
|
|
func (c *TlsPingCommand) Name() string { |
|
return "tlsping" |
|
} |
|
|
|
func (c *TlsPingCommand) Description() Description { |
|
return Description{ |
|
Short: "Ping the domain with TLS handshake", |
|
Usage: []string{"v2ctl tlsping <domain> --ip <ip>"}, |
|
} |
|
} |
|
|
|
func printCertificates(certs []*x509.Certificate) { |
|
for _, cert := range certs { |
|
if len(cert.DNSNames) == 0 { |
|
continue |
|
} |
|
fmt.Println("Allowed domains: ", cert.DNSNames) |
|
} |
|
} |
|
|
|
func (c *TlsPingCommand) Execute(args []string) error { |
|
fs := flag.NewFlagSet(c.Name(), flag.ContinueOnError) |
|
ipStr := fs.String("ip", "", "IP address of the domain") |
|
|
|
if err := fs.Parse(args); err != nil { |
|
return newError("flag parsing").Base(err) |
|
} |
|
|
|
if fs.NArg() < 1 { |
|
return newError("domain not specified") |
|
} |
|
|
|
domain := fs.Arg(0) |
|
fmt.Println("Tls ping: ", domain) |
|
|
|
var ip net.IP |
|
if len(*ipStr) > 0 { |
|
v := net.ParseIP(*ipStr) |
|
if v == nil { |
|
return newError("invalid IP: ", *ipStr) |
|
} |
|
ip = v |
|
} else { |
|
v, err := net.ResolveIPAddr("ip", domain) |
|
if err != nil { |
|
return newError("resolve IP").Base(err) |
|
} |
|
ip = v.IP |
|
} |
|
fmt.Println("Using IP: ", ip.String()) |
|
|
|
fmt.Println("-------------------") |
|
fmt.Println("Pinging without SNI") |
|
{ |
|
tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443}) |
|
if err != nil { |
|
return newError("dial tcp").Base(err) |
|
} |
|
tlsConn := tls.Client(tcpConn, &tls.Config{ |
|
InsecureSkipVerify: true, |
|
NextProtos: []string{"http/1.1"}, |
|
MaxVersion: tls.VersionTLS12, |
|
MinVersion: tls.VersionTLS12, |
|
}) |
|
err = tlsConn.Handshake() |
|
if err != nil { |
|
fmt.Println("Handshake failure: ", err) |
|
} else { |
|
fmt.Println("Handshake succeeded") |
|
printCertificates(tlsConn.ConnectionState().PeerCertificates) |
|
} |
|
tlsConn.Close() |
|
} |
|
|
|
fmt.Println("-------------------") |
|
fmt.Println("Pinging with SNI") |
|
{ |
|
tcpConn, err := net.DialTCP("tcp", nil, &net.TCPAddr{IP: ip, Port: 443}) |
|
if err != nil { |
|
return newError("dial tcp").Base(err) |
|
} |
|
tlsConn := tls.Client(tcpConn, &tls.Config{ |
|
ServerName: domain, |
|
NextProtos: []string{"http/1.1"}, |
|
MaxVersion: tls.VersionTLS12, |
|
MinVersion: tls.VersionTLS12, |
|
}) |
|
err = tlsConn.Handshake() |
|
if err != nil { |
|
fmt.Println("handshake failure: ", err) |
|
} else { |
|
fmt.Println("handshake succeeded") |
|
printCertificates(tlsConn.ConnectionState().PeerCertificates) |
|
} |
|
tlsConn.Close() |
|
} |
|
|
|
fmt.Println("Tls ping finished") |
|
|
|
return nil |
|
} |
|
|
|
func init() { |
|
common.Must(RegisterCommand(&TlsPingCommand{})) |
|
}
|
|
|