Unable to get the Socks Proxy working Golang applications - go

I am running a golang application on my local laptop, which connects with the Service APIs from a kubernetes cluster. To allow the communication between my laptop and Service APIs on Kubernetes Cluster, I have setup the Socks5 proxy and Able to connect with all services over CURL command.
But I am unable to set same proxy in the Golang application. I have tried various options already
Settings env vars - tried setting these 3 at OS level, App level but it did not work
http_proxy
https_proxy
all_proxy
I am running on Ubuntu Desktop 20.X, so I tried setting Socks proxy at OS Network level as well. All other apps using proxy, but golang isnt picking that up.
I tried setting the http.transport level configs too, but it didnt helped.
func InsecureTLSTransport() *http.Transport {
// START - Only for Proxy - Dev Mode.
var dialer, err = proxy.SOCKS5("socks5", "<IP:port>", nil, proxy.Direct)
if err != nil {
fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err)
}
return &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Dial: dialer.Dial,
}
}
I want the socks5 Proxy to be used by my golang app at runtime. Any suggestions?

you should use tcp instead of socks5 in the network parameter.
package main
import (
"fmt"
"golang.org/x/net/proxy"
)
func main() {
d, err := proxy.SOCKS5("tcp", "<IP:port>", nil, proxy.Direct) // <-- here
if err != nil {
fmt.Println(err)
return
}
c, err := d.Dial("tcp", "https://google.com")
if err != nil {
fmt.Println(err)
return
}
defer c.Close()
}

Related

Go net.dial issue

I'm having some issues connecting to a local golang TLS server via tls.dial or net.dial. The server ist started with the address localhost:10001 and I am able to connect to it with netcat (simply netcat localhost 10001 ) but trying it with golangs's dial method doesn't work (connection refused). What could be the reason for this? One important thing to point out is that I'm testing it on a Debian VM where I deinstalled the network manager so I could configure the network interfaces myself (static ip). My guess is that net.dial has some issues finding the right interface but what does netcat do that golang's methods don't? I tried all different kinds of addresses on both sides (server on localhost, ::1, 127.0.0.1; client same). On my windows host system it works (so the issue is probably not with the server).
Thanks in advance.
conn, err := tls.Dial("tcp", h.IP+":"+h.Port, conf)
if err != nil {
log.Println(err)
return empty
}
// do cleanup
defer conn.Close()
d := Craft_PKG( data )
//write package
WriteChunks( conn, d )
this is the client code and this
ln, err := tls.Listen("tcp", "localhost:"+(*port), config)
if err != nil {
log.Println(err)
return err
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
// start the handler for every incoming connection
go h(conn)
}
the server code. It is all very straightforward and works with netcat and in my Host system as I mentioned.

connect to socks5 proxy with IKEv2 certificate using golang 1.10.2

I use Go 1.10.2 for my client application.
I'm trying to connect to a socks5 proxy that requires username, password and IKEv2 certificate file.
this is what I've got so far:
func socks5(proxyAdress string, url string, user string, password string) {
auth := proxy.Auth{User: user, Password: password}
if proxy, err := proxy.SOCKS5("tcp", proxyAdress, &auth, proxy.Direct); err != nil {
log.Fatalf("error: %v", proxy)
} else {
tr := &http.Transport{Dial: proxy.Dial}
// Create client
myClient := &http.Client{
Transport: tr,
}
if resp, err2 := myClient.Get(url); err2 != nil {
log.Fatalf("error: %v", err2)
} else {
if bodyBytes, err3 := ioutil.ReadAll(resp.Body); err3 != nil {
log.Fatalf("error: %v", err3)
} else {
str := string(bodyBytes)
log.Printf(str)
}
}
}
}
when I execute this function with the proper parameters
I get an error from the server that I don't have permissions to access the web page I requested. that's because I didn't specify the IKEv2 key file.
so.. first.. how do I do that ?
and 2nd... Dial is deprecated.. I'm supposed to use DialContext but has no idea how
thanks ! :)
update
the OS that I use is MacOS High Sierra 10.13.4
the problem is that for example when I execute
socks5("il7.nordvpn.com:1080", "http://ifconfig.me/ip","MY_USER","MY_PASS")
the error that I get is
2018/05/15 23:34:49 error: Get http://ifconfig.me/ip: socks connect tcp ifconfig.me:80->ifconfig.me:80: EOF
I don't know where to provide the IKEv2 certificate
I think you need to set up IPSec on your computer first.
The steps to setup IPSec
Initial configurations (only once at the first time)
Start a VPN connection
Follow here

gRPC and HTTP 1 call on single port, with out using TLS in goLang

I have recently started working in golang for a project, where I have to use gRPC for push notification on my server to connect to an Android device.
I have created a simple multiplexer mux := http.NewServeMux() which is working fine with my server code:
serverWeb := http.Server{
Addr: constants.ServerIPWeb,
//Handler: grpcHandlerFunc(grpcServer, mux),
Handler: mux,
}
serverWeb.ListenAndServe()
As from the examples on gRPC.io I have also created a simple gRPC client/server as a standalone project connected to my android device, with out any TLS configuration and its working fine.
type server struct{}
func (s *server) DeviceData(ctx context.Context,req *pb.GetDeviceRequest) (*pb.SetDeviceResponse, error){
util.P("Device is: ",req) // simple fmt.PrintF(a ... interface)
return &pb.SetDeviceResponse{Message:"Success"}, nil
}
func main(){
lis, err := net.Listen("tcp", ":8080")
if err!=nil{
log.Fatalf("Failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterDeviceInfoServer(s,&server{})
reflection.Register(s)
if err := s.Serve(lis); err != nil{
log.Fatalf("Falied to server: %v", err)
}
}
The problem is I could not connect my current gRPC server to my serverStruct above. I have tried to add Handler: grpcHandlerFunc(grpcServer, mux) that will connect my server to the following code, as explained here ( gRPC with open API )
func grpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// TODO(tamird): point to merged gRPC code rather than a PR.
// This is a partial recreation of gRPC's internal checks https://github.com/grpc/grpc-go/pull/514/files#diff-95e9a25b738459a2d3030e1e6fa2a718R61
util.P("ResponseFunction: GRPC: ",r.URL) // simple fmt.PrintF(a ... interface)
if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
grpcServer.ServeHTTP(w, r)
} else {
otherHandler.ServeHTTP(w, r)
}
})
}
The above code will run my Service running from my mux i.e connecting to http, but it won't run services from gRPC, i.e is connecting to my Android Device.
I believe it requires, TLS connection, but I don't want to get into the implementation of securing my web and Android side code, as that would require me to change all the code at my Android Side and Web, which I want to avoid.
So I am looking for a way to connect this grpcServer to my current serverStruct without using any TLS configuration.
More Over myResearcH:
I have also searched there is a repo called cmux (Connection Mux) which will do the same job, but I don't understand how would I use it with my current serverStruct, as I have a fully functional web app running on this, and I just need to add gRPC with my current code.
gRPC Service can be achieved with out the implementation of TLS by using go routines.
Create a Function, Serving your gRPC
func RunGRPC() {
grpcServer := grpc.NewServer()
pb.RegisterGlassInfoServer(grpcServer,&GlassApkBean{})
pb.RegisterDeviceInfoServer(grpcServer, &DeviceInfoBean{}) // for multiple services
lis, err := net.Listen("tcp", ":50051")
if err !=nil{
log.Fatalf("Error: %v\n" , err.Error())
}
grpcServer.Serve(lis)
}
use this function, to recive client request
func main(){
.
. // Your Code
.
go RunGRPC() // code to run grpc server in go routine.
serverWeb := http.Server{
Addr: "localhost:8080",
Handler: mux,
}
serverWeb.ListenAndServe()
}

SSH Reverse Tunnel with GO

I am trying to write a server / client that can help get around Firewalls / Nat Issues.
I noticed SSH has built into support for doing this already.
(http://rustyrazorblade.com/2010/03/ssh-reverse-tunnel-to-access-box-behind-firewall/)
I tried a few different SSH examples and none seem to be working. I found one project that says it implemented the Remote Port Fowarding -> https://godoc.org/dev.justinjudd.org/justin/easyssh
The Server says it is Listening for connections but I am unable to SSH from Server Machine To Client Machine. (ssh localhost 8080 on remote machine should forward to client machine.
Client ->
package main
import (
"log"
"dev.justinjudd.org/justin/easyssh"
"golang.org/x/crypto/ssh"
)
func main() {
config := &ssh.ClientConfig{
User: "test",
Auth: []ssh.AuthMethod{
ssh.Password("test"),
},
}
conn, err := easyssh.Dial("tcp", "*SSH-SERVER*:22", config)
if err != nil {
log.Fatalf("unable to connect: %s", err)
}
defer conn.Close()
err = conn.RemoteForward("0.0.0.0:8080", "127.0.0.1:22")
if err != nil {
log.Fatalf("unable to forward local port: %s", err)
}
}
Server ->
package main
import (
"fmt"
"io/ioutil"
"log"
"dev.justinjudd.org/justin/easyssh"
"golang.org/x/crypto/ssh"
)
func main() {
privateBytes, err := ioutil.ReadFile("id_rsa")
if err != nil {
log.Fatal("Failed to load private key (./id_rsa)")
}
private, err := ssh.ParsePrivateKey(privateBytes)
if err != nil {
log.Fatal("Failed to parse private key")
}
config := &ssh.ServerConfig{
PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
if c.User() == "test" && string(pass) == "test" {
log.Printf("User logged in: %s", c.User())
return nil, nil
}
return nil, fmt.Errorf("password rejected for %s", c.User())
},
}
config.AddHostKey(private)
easyssh.HandleChannel(easyssh.SessionRequest, easyssh.SessionHandler())
easyssh.HandleChannel(easyssh.DirectForwardRequest, easyssh.DirectPortForwardHandler())
easyssh.HandleRequestFunc(easyssh.RemoteForwardRequest, easyssh.TCPIPForwardRequest)
easyssh.ListenAndServe(":22", config, nil)
}
I found a bug related to remote port forwarding in easyssh:
https://dev.justinjudd.org/justin/easyssh/src/master/tcpip.go#L107
the ssh.DiscardRequests(reqs) should be run in a separated goroutine, or else the next data transfer will not be executed.
I'm not sure that you understand how SSH tunneling works looking on your code.
You need to have SSH connectivity to the remote (server).
Then you setup SSH tunnel so local TCP:8080 port will be forwarded to the remote server TCP:8080 port using SSH connection. Actual 8080 port can be closed via firewall.
Can you connect from your client to your server with SSH?
You need to check localhost:8080 port and you need to be sure that your server 8080 port is listened by some application too.
Take a look here for some examples and theory.

Go server not hearing remote requests

I've written a Go server that works perfectly as long as you send it requests from localhost (and addressed to localhost), but it doesn't work when you try to access it from a browser (from a different computer) or even just directed at the external IP address. I want to be able to access it as an external server, not just locally. Why can't it?
The (pared down) source code:
package main
import (
"fmt"
"net"
"os"
)
func main() {
// Listen for incoming connections.
l, err := net.Listen("tcp", "localhost:2082")
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
// Close the listener when the application closes.
defer l.Close()
for {
// Listen for an incoming connection.
_, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
fmt.Println("Incoming connection")
}
}
When you curl localhost:2082, it says "Incoming connection".
When you curl mydomain.com:2082, it does nothing.
The port is forwarded. I'm sure of this because I ran a (node.js) web server from that port, and it worked fine. If it's related, I'm running on Ubuntu 12.04 on an Amazon EC2 instance.
I'd appreciate any help. Thanks!
One way to listen to any incoming IP (not just localhost, mapped by default to 127.0.0.1) would be:
net.Listen("tcp", ":2082")
You also have the function net/http/#ListenAndServe, which allows you to trigger listen on multiple specific ip if you want.
go http.ListenAndServe("10.0.0.1:80", nil)
http.ListenAndServe("10.0.0.2:80", nil)
A good example can be seen in "A Recap of Request Handling in Go".

Resources