Create a SOCKS5 client using "net" module - go

I am working on creating my own SOCKS5 proxy client. I'm trying to make it without any 3rd modules (Only use "net", I have made a HTTP proxy client with it). Can anyone help me?
The SOCKS5 client function is looks like this:
func NewSocks(socks5Address string, websiteAddress string) (net.Conn, err)

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.

Go: Send websocket requests to a proxy port

I have an Envoy proxy instance configured to proxy http and websocket requests. Note that this is not a CONNECT proxy. I want my websocket client to create a websocket request as if it was sending it to the original destination and then deliver the payload to the proxy's listener instead.
What's the recommended way to connect to the local proxy? I believe this is dependent on the specific Go websocket package being used. I can see packages that allow overriding the http.Client used, but the destination address is determined using the websocket URL specified. The only alternative I have is to send the request to ws://proxy_ip:proxy_port/path directly, and specify the destination using some custom HTTP header that the proxy is configured to use for routing. I am not a big fan of this approach.
I want to dial an address different from that in the request
Use Gorilla's Dialer.NetDialContext to dial an address different from the request:
d := websocket.Dialer{
NetDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return net.DialContext(ctx, network, "proxy_ip:proxy_port")
},
}
c, r, err := d.Dial("ws://example.com/path", nil)
if err != nil {
// handle error
}

socks5 proxy client with context support

Is it possible to use a context with the Dialer returned by the SOCKS5 function from net/proxy library?
If a SOCKS5 proxy Dialer blocks while establishing the connection, an HTTP client using the proxy Dialer could get stuck without a way to abort the connection.
Under the hood of golang.org/x/net/proxy.SOCKS5 it uses golang.org/x/net/internal/socks.Dialer, which has an exported method DialContext, and since Go 1.7, http.Transport supports a custom DialContext as a field. So you can cast the dialer to an interface with method DialContext and set it to a custom transport.
dc := dialer.(interface {
DialContext(ctx context.Context, network, addr string) (net.Conn, error)
})
httpTransport.DialContext = dc.DialContext
playground: https://play.golang.org/p/tSi9IZ-2Zqg
Note: while this is valid Go code, some would argue it relies on implementation details that the package does not want to export (hidden in internal). I think it is best to send an issue to Go team to ask for export it; if it is too much an issue for you, you can either copy the code and preserve it from changing, or use http.Client.Timeout or write start every http.Do concurrently and wraps a select over it for context like dealing with any blocking operation.

TLS handshake error from xx.xx.xx.xx:14333: EOF

I am running a HTTPS server in Linux (RHEL 7). I am getting the below error as soon as I start the server.
2019/09/04 15:46:16 http: TLS handshake error from xx.xx.xx.xx:60206: EOF
2019/09/04 15:46:21 http: TLS handshake error from xx.xx.xx.xx:31824: EOF
This error is coming automatically and continuously in the terminal.
Below is the go code for creating https server -
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
fmt.Println("Starting webserver")
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"success": true,
})
})
router.RunTLS(":9001", "server.pem", "server.key")
}
We have purchased and combined the server certificate, intermidate certificate and root certificate into a single file to make the server.pem file.
As this error is coming continuously and in the terminal as soon as I start the server, I think there is some configuration problem in the VM?
Please suggest what are the things I can check here.
NOTE: This error is specific to the Go. I have tested on the same server on the same port with same certificates in Node JS. And it works fine.
Also the IP in the error message is of the reverse proxy server (WAF) which is continuosly doing health monitoring of the web application server.
I would attack the problem from two angles:
What is this xx.xx.xx.xx address? I'd expect that when I start some random piece of software, there is nothing to connect to it all by itself, right?
Is there anything special about that 9001 port? Try running nc -l -p 9001 and see whether those unidentified connections happen as well.
Run tcpdump and see whether there is any incoming traffic from the clients making those connections: those EOFs (that's "end of file") reported by the TLS mchinery most probably mean those clients—whatever they are—close their side of the connection somewhere amidst the TLS handshake—while the server is expecting to read some data from them.
This hints at that those clients do not actually expect to see TLS protocol in the connection they open; and they pretty much may send some plaintext in it, so you'll be able to peek at it.
Googling for "9001 port" hints at that it's used for some "ETL service manager" protocol—whatever it is. This hints at that traffic on 9001 might be related to VoIP.
I have no idea what to do with this, but it might give you some lead for further research.

How to multiplex requests for different domains to different servers using Go?

I want to host multiple domains on the same machine, with multiple servers running on the same machine and different ports. I am trying to write a multiplexer which will redirect requests for domain "A" to the server running locally on "portA", and requests for domain "B" to the server running on "portB". How can I route those requests, while making this redirect transparent to the user and search-engine bots?
Currently, I use something like this:
package main
import (
"net/http"
"log"
)
func main() {
mux := http.NewServeMux()
mux.Handle("mydomainA.com", http.RedirectHandler("http://localhost:1234", 302))
mux.Handle("mydomainB.com", http.RedirectHandler("http://localhost:4567", 302))
log.Fatal(http.ListenAndServe(":8080", mux))
}
(just posting #james-odoherty's comment as an answer since he hasn't)
You want to use the httputil.ReverseProxy type from the net/http/httputil package.

Resources