Golang tcp-tls over socks5 proxy client - go

I create a dialer via
dialer := &net.Dialer{}
and a TLS dialer via
tlsDialer := &tls.Dialer{
NetDialer: dialer,
Config: &tls.Config{InsecureSkipVerify: true},
}
Then I create a socks5 proxy dialer by using
proxyDialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct)
How can I connect remote server though the socks5 proxy?
In other way, how to nest three dialer in the order of net.Dialer->tls.Dialer->proxy.Dialer and finally using proxyDialer.Dial("tcp", "remote:port") to connect the server?
My Env:
OS: Windows 10 x64
Golang: 1.16 (no CGO)
Any help would be greatly appreciated :)
First time asking question in SOF, if I missed sth to say pls tell me :)

Thanks for #Steffen Ullrich
A Dialer is used to establish a connection - but there is only a single connection to establish. Create the connection using proxyDialer, then use tls.Client on the connection given by proxyDialer to "upgrade" it to a tls.Conn.
Just "upgrade" proxy connection to tls
proxyDialer, err := proxy.SOCKS5("tcp", "proxyserver:1080", nil, proxy.Direct)
conn, err = proxyDialer.Dial("tcp", "server:port")
conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true})

Related

Create SOCKS5 Proxy in go

I want to create a tor like clone in Go, where I have a local socks5 proxy server from which I get the request, encrypt it and send it via tcp to the network. To work with proxies in go I found the golang.org/x/net/proxy package. By searching how to create a server with it and getting the request data I only find something like this Creating a go socks5 client where people use it to only forward the traffic to another server.
Currently I have this implementation.
dialer, err := proxy.SOCKS5("tcp", "127.0.0.1:31415", nil, proxy.Direct)
if err != nil {
panic(err)
}
My question now is how I can get the data which the computer send via socks5 to this local proxy.

Why is tls.Client failing with message:first record does not look like a TLS handshake

I'm trying to run the buildlet at https://github.com/golang/build/tree/master/cmd/coordinator
There is a locally hosted server connection that keeps failing to connect giving the error:
first record does not look like a TLS handshake
The piece of code that fails is from build/cmd/buildlet/reverse.go and it is:
tcpConn.SetDeadline(time.Now().Add(30 * time.Second))
config := &tls.Config{
ServerName: serverName,
InsecureSkipVerify: devMode,
}
conn := tls.Client(tcpConn, config)
if err := conn.Handshake(); err != nil {
return nil, fmt.Errorf("failed to handshake with coordinator: %v", err)
}
I've gathered that the connection should be established while ignoring TLS issues because the server is at localhost
I can't seem to figure out how to fix this issue.
Instructions on recreating my problem are at the above link. The only change I recommend is using
go run . -mode=dev -listen-http=localhost:8119
for the first command
InsecureSkipVerify just means that TLS certificate validation constraints are relaxed (to a point where your connection is insecure and prone to MITM attacks)
From the documentation:
If InsecureSkipVerify is true, crypto/tls accepts any certificate presented by the server and any host name in that certificate.
You still need to have a connection that uses TLS at the other end. The error that you're getting means that the other side of the connect doesn't speak TLS.
If you don't want to use TLS in devMode, then you should use the tcpConn directly while in dev mode, without wrapping it with a *tls.Conn. *tls.Conn implements net.Conn so after the handshake there shouldn't be any difference in how you use the connection, whether it has TLS or not.

How does Golang's LDAP client library work with certificates?

I'm trying to connect to G Suite's LDAPS server with Golang's LDAP library.
However, in the example, I don't really understand two things.
It seems like it connects via non-encrypted LDAP first? Then it upgrades? Is that true, if so, can't I just start out by connecting encrypted?
Google supplies a .cer & .key file to connect to their ldap server. I don't see where it use these files. I do see in their docs that a lot of LDAP clients require the files to be combined into a .p12. Is that necessary for Go?
If the person that answers this could supply an example, that would really help. Thank you.
StartTLS, as you've noted, allows one to upgrade a connection to use a TLS later on in the connections lifecycle.
If you want to connect via TLS immediately, then use the well known ldaps port 636 (instead of 389) - and use DialTLS:
// l, err := ldap.Dial("tcp", "ldap.example.com:389"))
var tlsConf *tls.Config
ldaps, err := ldap.DialTLS("tcp", "gsuite.google.com:636", tlsConf)
You may also use DialURL which infers TLS or non-TLS by the schema e.g.
conn, err := ldap.DialURL("ldap://ldap.example.com") // non-TLS on default port 389
conn, err := ldap.DialURL("ldaps://ldap.example.com") // TLS on default port 636
conn, err := ldap.DialURL("ldaps://myserver.com:1234") // TLS on custom port 1234
// Note: there is no way to add a custom tls.Config with this method
So if using, DialTLS: since you are using a Google service, it's trust cert should already be in your keychain, so a simple tls.Config should suffice:
tlsConf = &tls.Config{ServerName:"gsuite.google.com"} // <- ensure this matches the hostname provided by the server
If you want to get things up an running for testing:
// DONT EVER USE THIS IN PRODUCTION...
tlsConf = &tls.Config{InsecureSkipVerify: true} // DO NOT USE EVER
To add a client cert for client-side authentication:
// Load cer & key files into a pair of []byte
cert, err := tls.X509KeyPair(cer, key)
if err != nil {
log.Fatal(err)
}
tlsCong := &tls.Config{Certificates: []tls.Certificate{cert}}

Debug Connectivity Issue in gRPC Dial

I'm trying to make a gRPC connection to a server. In my client code (go version: go1.13 darwin/amd64), I have
conn, err = grpc.DialContext(ctx, c.tiProxyURL, grpc.WithInsecure(), grpc.WithBlock(), grpc.WithBackoffMaxDelay(10*time.Second))
This blocks the code as the connection is for some reason not established. Is there any way to debug this further and figure out what is the issue with the connection?
The connection is established when I'm running the server code on my local machine, but is blocked when trying to connect to a service deployed in the cloud through the ingress URL.

Does redigo reconnects to the server?

I am using Redigo to connect to redis server through golang.
redisConnection, err = redis.Dial("tcp", "...")
redisConnection.Do(..., ...)
If I restart my server, I am unable to execute any command using the same redisConnection. Shouldn't it reconnect when I execute Do again?
No, your assumption is not correct. Using the Dial function it returns a single connection when the server terminates the connection, the client is not able to reconnect.
You should use redis.Pool and it should be able to auto-reconnect when you ask for a new connection, the function is: pool.Get()
redisConnection.Err() returns a non nil value if the connection is not usable. We can Dial again in that case.

Resources