Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto/tls: DialWithDialer using "server name" or "IP literal" provide different results #29474

Closed
andymacau853 opened this issue Dec 31, 2018 · 6 comments

Comments

@andymacau853
Copy link

andymacau853 commented Dec 31, 2018

What version of Go are you using (go version)?

$ go version
go version go1.11.4 windows/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Administrator\AppData\Local\go-build
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Project\Go\maas
set GOPROXY=
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=
0 -fdebug-prefix-map=C:\Users\Administrator\AppData\Local\Temp\go-build757481154=/tmp/go-
build -gno-record-gcc-switches

What did you do?

The below code response: Connection success: 118.163.120.170:443

	dialer := &net.Dialer{
		Timeout: time.Millisecond * time.Duration(1000),
	}
	config := &tls.Config{
		InsecureSkipVerify: true,
	}
	conn, err := tls.DialWithDialer(dialer, "tcp", "www.globaltrust.com.tw:443", config)
	if err != nil {
		log.Println("Connection error: " + err.Error())
	} else {
		log.Println("Connection success: " + conn.RemoteAddr().String())
	}
	if conn != nil {
		_ = conn.Close()
	}

The below code response: Connection error: read tcp 192.168.220.222:57388->118.163.120.170:443: wsarecv: An existing connection was forcibly closed by the remote host.

	dialer := &net.Dialer{
		Timeout: time.Millisecond * time.Duration(1000),
	}
	config := &tls.Config{
		InsecureSkipVerify: true,
	}
	conn, err := tls.DialWithDialer(dialer, "tcp", "118.163.120.170:443", config)
	if err != nil {
		log.Println("Connection error: " + err.Error())
	} else {
		log.Println("Connection success: " + conn.RemoteAddr().String())
	}
	if conn != nil {
		_ = conn.Close()
	}

In fact, www.globaltrust.com.tw is 118.163.120.170, why different results if using domain or real IP?

What did you expect to see?

the both code should connect to remote successfully, no matter using domain or real IP.

What did you see instead?

Only this web site has the issue that failed to connect to remote if using an real IP.

@odeke-em odeke-em changed the title tls.DialWithDialer using "domain" or "real IP" has different results. crypto/tls: DialWithDialer using "domain" or "real IP" provide different results Jan 2, 2019
@fraenkel
Copy link
Contributor

fraenkel commented Jan 2, 2019

If you try the same with curl, you will get the same error.

@odeke-em
Copy link
Member

odeke-em commented Jan 2, 2019

Hello @andymacau853, thank you for filing this issue and welcome to the Go project!

Indeed, as @fraenkel beat me to (was boarding a plane and had to shutdown), you'll get the same error using curl

$ curl -i https://118.163.120.170
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to 118.163.120.170:443 

while with the name

$ curl -i https://www.globaltrust.com.tw
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/8.5
Set-Cookie: ASPSESSIONIDASHRRDAR=NNDNBNHBDBCNPOJMNILMEIOM; secure; path=/
Date: Wed, 02 Jan 2019 09:59:58 GMT
Content-Length: 87391

I could speculate about what's going on but I am not an expert at TLS so I'll page @FiloSottile @bradfitz @agl to help out.

@FiloSottile
Copy link
Contributor

The server is rejecting connections without Server Name Indication, which is set automatically when you use a hostname, but can't be when you use an IP. If you add ServerName: "www.globaltrust.com.tw" to the tls.Config the connection to the IP will succeed.

@andymacau853
Copy link
Author

Because I must use IP to dial with tls, anyone has above solution to solve it? or golang bugs?

@mikioh
Copy link
Contributor

mikioh commented Jan 8, 2019

You can use a pack of net.Dialer.DialContext, tls.Client add tls.Conn.Handshake instead of tls.DialWithDialer. If you need more help, please use more appropriate forums, e.g., https://github.com/golang/go/wiki/Questions, thanks.

@mikioh mikioh changed the title crypto/tls: DialWithDialer using "domain" or "real IP" provide different results crypto/tls: DialWithDialer using "server name" or "IP literal" provide different results Jan 8, 2019
@FiloSottile
Copy link
Contributor

@andymacau853 apparently you need to set ServerName in tls.Config for this server.

@golang golang locked and limited conversation to collaborators Jan 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants