Connect and maintain connection to socks5 proxy server with authentication - go

I'm trying to dial using credentials and maintain a connection with a socks5 proxy server in Go.
This works nicely if I have IP authorisation set up with the proxy provider, however there is no way pass any auth credentials using net.Dial function in Go:
package main
import (
"io"
"net"
)
func main() {
dst, err := net.Dial("tcp", "11.22.33.44:1111")
if err != nil {
panic("Dial Error:" + err.Error())
}
dst.Close()
}
Go has a useful proxy library and allows authenticated forward requests via proxy using this:
package main
import (
"io"
"net"
)
func main() {
var proxyAuth *proxy.Auth
if conf.Username != "" {
proxyAuth = new(proxy.Auth)
proxyAuth.User = conf.Username
proxyAuth.Password = conf.Password
}
proxyconn, _ := proxy.SOCKS5("tcp", "11.11.11.11:1111", proxyAuth, nil) //returns a Dialer with proxy that can be invoked to connect to another address
dst := proxyconn.Dial("tcp", "22.33.44.55:6666") //connects to an address via proxy
dst.Close()
}
However it returns a Dialer that then asks to connect a target/ultimate address through this authenticated proxy rather the proxy server itself:
My objective here is to return a net.conn connection with a credentials-authenticated proxy server - something like this:
package main
import (
"io"
"net"
)
func main() {
//net.Dial does not have a way to pass Auth creds
dst := net.Dial("tcp", "22.33.44.55:6666", proxyAuth)
dst.Close()
}

The net.Dial() method doesn't concerned with proxy authentication. However, If you want proxy authentication you can set it in header of the request before the call. Please refer this link
dst := net.Dial("tcp", "22.33.44.55:6666")

Related

Unable to connect with HTTP proxy

go version: go1.13.5 linux/amd64
I am using "x/net/proxy" to connect with the "http_proxy".
I have referred following proxy page:
https://godoc.org/golang.org/x/net/proxy
To get proxy information I have set environment variable "all_proxy" to the the desired proxy "http://192.130.0.10:3200", and performed the tcp connection, but following error is raised:
[Network Error : socks connect tcp 192.130.0.10:3200->mx.eu1.mico.io:8883: read tcp 172.17.0.2:48118->192.130.0.10:3200: read: connection reset by peer]
I have looked "x/net/proxy", It seems "http_proxy" support is not available instead of "SOCKS5" proxy is supported. I have similar implementation for "http_proxy", but unfortunately it does not worked.
I have created a sample code (with port 1883) which is working for the non proxy environment, Please suggest how I can enable "http_proxy" or "https_proxy" support?
package main
import (
"fmt"
"os"
"golang.org/x/net/proxy"
)
//The host address which we want to connect with the proxy
var host = "google.com:80"
func main() {
fmt.Println("Inside main...")
//Setting the proxy before starting the application
if os.Getenv("http_proxy") == "" {
os.Setenv("http_proxy", "http://192.130.0.10:3200")
}
os.Setenv("all_proxy", os.Getenv("http_proxy"))
if os.Getenv("all_proxy") != os.Getenv("http_proxy") {
fmt.Println("Environment variables are not matching...")
return
}
fmt.Println("System proxy is:", os.Getenv("all_proxy"))
proxyDialer := proxy.FromEnvironment()
fmt.Println("Connecting to...", host)
conn, err := proxyDialer.Dial("tcp", host)
if err != nil {
fmt.Println("Unable to dial...", err)
return
}
fmt.Println("Connected...", conn)
}
Output:
Inside main...
System proxy is: http://192.130.0.10:3200
Connecting to... google.com:80
Unable to dial... dial tcp 172.217.23.174:80: connect: connection timed out
What's your purpose?
If you need to use an http-proxy server for http requests, you can just configure your http-client without another package usage:
package main
import (
"fmt"
"net/http"
"net/url"
"time"
)
func main() {
proxyUrl, err := url.Parse("http://192.130.0.10:3200")
if err != nil {
// TODO handle me
panic(err)
}
cl := http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyUrl),
},
Timeout: 3000 * time.Millisecond,
}
resp, err := cl.Get("http://google.com")
if err != nil {
// TODO handle me
panic(err)
}
// TODO work with the response
fmt.Println(resp)
}

How to override default DNS

I've been working on finding a way to try and override the default DNS server for a Go program for a while but still with no success sadly.
The current solution which I had thought would work was:
package main
import (
"context"
"fmt"
"net"
"time"
)
func main() {
DNS := "1.1.1.1"
net.DefaultResolver = &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{
Timeout: time.Millisecond * time.Duration(3000),
}
return d.DialContext(ctx, "udp", fmt.Sprintf("%s:53", DNS))
},
}
resp, err := net.LookupHost("tsdfsdf.com")
if err != nil {
fmt.Printf(err.Error())
}
fmt.Printf("%+v", resp)
}
But the response from this is:
lookup tsdfsdf.com on 192.168.0.1:53: no such host[]
Which is sadly my default DNS server set in my reslov.conf
I have tried forcing to use the Go Resolver by setting export GODEBUG=netdns=go
The long term solution is to be able to over the default resolver for the HTTP Client which would, in turn be consumed by some AWS SDK stuff.
Has any faced this or knows how I can get around this?
FYI, I know "tsdfsdf.com" is not a real domain I'm just using it to spit a No such host error to see what DNS it asked.

Why client always received "transport: received the unexpected content-type" from localhost GO wrote GRPC service

I have just cloned the example code from micro/go-grpc and tried to build a grpc server in localhost.
proto file
syntax = "proto3";
package go.micro.srv.greeter;
service Say {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
server/main.go
package main
import (
"context"
"log"
"github.com/micro/go-micro"
"github.com/micro/go-grpc"
hello "github.com/micro/go-grpc/examples/greeter/server/proto/hello"
)
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp
*hello.Response) error {
log.Print("Received Say.Hello request")
rsp.Msg = "Hello " + req.Name
return nil
}
func main() {
service := grpc.NewService(
micro.Name("go.micro.srv.greeter"),
)
// optionally setup command line usage
service.Init()
// Register Handlers
hello.RegisterSayHandler(service.Server(), new(Say))
// Run server
if err := service.Run(); err != nil {
log.Fatal(err)
}
}
client/main.go
package main
import (
"context"
"fmt"
"github.com/micro/cli"
"github.com/micro/go-grpc"
hello "github.com/micro/go-grpc/examples/greeter/server/proto/hello"
"github.com/micro/go-micro"
)
var (
// service to call
serviceName string
)
func main() {
service := grpc.NewService()
service.Init(
micro.Flags(cli.StringFlag{
Name: "service_name",
Value: "go.micro.srv.greeter",
Destination: &serviceName,
}),
)
cl := hello.NewSayService(serviceName, service.Client())
rsp, err := cl.Hello(context.TODO(), &hello.Request{
Name: "John",
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(rsp.Msg)
}
My OS is MacOsX, go version is 1.11.1.
When i run the server side example code, everything looks fine:
$ go run ./main.go --server_address:localhost:9999
2018/11/18 20:08:05 Listening on 127.0.0.1:9999
2018/11/18 20:08:05 Broker Listening on [::]:62739
2018/11/18 20:08:05 Registering node: go.micro.srv.greeter-9b2818b0-eb2a-11e8-bfef-720008acb800
But if I run the client side example code, always received:
{"id":"","code":0,"detail":"transport: received the unexpected content-type "text/plain"","status":""}
I tried to remove the --server_address and still the same. I tried to add the mdns registry, not working either. I tried to use $ micro health go.micro.srv.greeter, it returned the same result.
Wonder whats wrong with my setup?
I just got this same error because I was pointing to the wrong port. I'm sure my setup is different from yours and it's a different issue, but the problem was that I was trying to make a GRPC request to an http server, which returned a 404 not found with a content-type of "text/plain" for html. If you have the same problem when removing your server address, it's likely either you aren't reading the param correctly, or the value you have set is still pointing to a place where there is an http server and not a GRPC server.

What configuration am I missing for httputil.NewSingleHostReverseProxy?

The code below produces the error further below. When I type "http://www.cnn.com/favicon.ico" straight into any browser it works without issue. I am guessing that I am missing some critical configuration for the reverse proxy. What is the minimum config needed for getting this to work?
package main
import (
"net/http"
"net/http/httputil"
"net/url"
"log"
)
func main(){
url, _ := url.Parse("http://www.cnn.com/favicon.ico")
proxy := httputil.NewSingleHostReverseProxy(url)
http.HandleFunc("/", proxy.ServeHTTP)
log.Fatal(http.ListenAndServe(":9090", nil))
}
Fastly error: unknown domain: localhost. Please check that this domain
has been added to a service.
Details: cache-lax8625-LAX
Happy 4th of July!
I made the following 2 changes to get it working:
Firstly, point the proxy at www.cnn.com instead of www.cnn.com/favicon.ico. Of course, now we must make our request to localhost:9090/favicon.ico.
Next, set the proxied request's Host field to the target host, not the host of the proxy which is localhost.
The code ends up looking like this:
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
type Director func(*http.Request)
func (f Director) Then(g Director) Director {
return func(req *http.Request) {
f(req)
g(req)
}
}
func hostDirector(host string) Director {
return func(req *http.Request) {
req.Host = host
}
}
func main() {
url, _ := url.Parse("http://www.cnn.com")
proxy := httputil.NewSingleHostReverseProxy(url)
d := proxy.Director
// sequence the default director with our host director
proxy.Director = Director(d).Then(hostDirector(url.Hostname()))
http.Handle("/", proxy)
log.Fatal(http.ListenAndServe(":9090", nil))
}

Configuring proxy settings for goproxy

I'm trying to use goproxy as an alternative to fiddler on mac OSX,
I wrote the following code, and succeeded to run it:
package main
import (
"flag"
"log"
"net/http"
"gopkg.in/elazarl/goproxy.v1"
)
func main() {
verbose := flag.Bool("v", false, "should every proxy request be logged
to stdout")
addr := flag.String("addr", ":8080", "proxy listen address")
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = *verbose
proxy.OnResponse().DoFunc(func(resp *http.Response, ctx
*goproxy.ProxyCtx) *http.Response {
contentType := resp.Header.Get("Content-Type")
if contentType == "application/javascript" || contentType == "application/x-javascript" {
// Do something...
}
return resp
})
log.Fatal(http.ListenAndServe(*addr, proxy))
}
According to goproxy documentation I need to configure web proxy & secure web proxy:
I have put multiple breakpoints and run the code in debug, tried to access a website but I can't get it to stop on the breakpoint..
I think I'm missing something in the proxy settings maybe.

Resources