Enforce use of resolver and disable fallback - go

I want to achieve resolving a given domain by the DNS Server I provide.
The code below I've grabbed from https://play.golang.org/p/s2KtkFrQs7R
The result is giving the correct results - but unfortunately even when I'm giving an IP like 123.123.123.123:53 as the resolver IP...
I guess there's a fallback - but I could not find (https://golang.org/pkg/net/) the switch to turn it off...
Thanks in advance for any hint...
Matthias
package main
import (
"context"
"fmt"
"log"
"net"
"time"
)
func GoogleDNSDialer(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{}
return d.DialContext(ctx, "udp", "123.123.123.123:53")
}
func main() {
domain := "www.google.com"
const timeout = 1000 * time.Millisecond
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
// var r net.Resolver
r := net.Resolver{
PreferGo: true,
Dial: GoogleDNSDialer,
}
records, err := r.LookupHost(ctx, domain)
if err != nil {
log.Fatal(err)
} else {
fmt.Printf("Records %v \n", records[0])
}
}

Related

Issue parsing ed25519v1 keys generated by mkp224o

I used mkp224o to generate a key. Afterwards I tried to use Go to parse the key and start a service with Bine. Unfortunately I can't seem to be able to generate the same v3 onion address as mkp224o.
package main
import (
"bytes"
"context"
"crypto/ed25519"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/cretz/bine/tor"
"github.com/ipsn/go-libtor"
"github.com/pkg/errors"
)
func main() {
log.SetOutput(os.Stdout)
if len(os.Args) != 2 {
check(errors.New("need 1 argument"))
}
var known ed25519.PrivateKey
buf, _ := os.ReadFile("/home/user/mkp224o/onions/rocin4w356yd7jadjppabxivaz56z4k2wfvy5xpxieirenda3yt2aiqd.onion/hs_ed25519_secret_key")
known = bytes.TrimLeft(buf, "== ed25519v1-secret: type0 ==\x00\x00\x00")
fmt.Println("Starting and registering onion service, please wait a bit...")
t, err := tor.Start(context.Background(), &tor.StartConf{ProcessCreator: libtor.Creator, DebugWriter: nil})
check(errors.Wrap(err, "Failed to start tor"))
defer t.Close()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel()
onion, err := t.Listen(ctx, &tor.ListenConf{Version3: true, RemotePorts: []int{80}, Key: known})
check(errors.Wrap(err, "Failed to create tor service"))
defer onion.Close()
fmt.Printf("Please open a Tor capable browser and navigate to http://%v.onion\n", onion.ID)
http.HandleFunc("/", pathHandler())
http.Serve(onion, nil)
}
func check(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
func pathHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
}
}
Returns:
Starting and registering onion service, please wait a bit...
Please open a Tor capable browser and navigate to http://r3jvsuoxe37pn6ik5vjvcxrky37bxsuopo5yn436r5pamjfkz2mkytqd.onion
when it should be returning the rocin4w356yd7jadjppabxivaz56z4k2wfvy5xpxieirenda3yt2aiqd.onion address that mkp224o generated. What am I missing?

go build doesn't recognise methods

I try to setup a small Golang Microservice for users with Gin and Mongodb.
package main
import (
"context"
"fmt"
"github.com/wzslr321/artiver/entity"
"github.com/wzslr321/artiver/settings"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"os"
"os/signal"
"syscall"
"time"
)
type application struct {
users *entity.UserCollection
}
var app *application
func init() {
initMongo()
}
func initMongo() {
oc := options.Client().ApplyURI(settings.MongodbSettings.Uri)
client, err := mongo.NewClient(oc)
if err != nil {
log.Fatalf("Error occured while initializing a new mongo client: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil {
log.Fatalf("Errorr occurred while connecting to a client: %v", err)
}
defer func() {
if err = client.Disconnect(ctx); err != nil {
panic(err)
}
}()
log.Println("Successfully connected to the database!")
app = &application{
users: &entity.UserCollection{
C: client.Database("artiver").Collection("users"),
},
}
}
func main() {
router := app.InitRouter()
It doesn't show any errors in my IDE ( GoLand ), but when I try to build it I get an error:
# command-line-arguments
users/cmd/app/main.go:67:15: app.InitRouter undefined (type *application has no field or method InitRouter)
It it easily visible on the image above, that I do have access to such a method. It is defined in the same package.
package main
import (
"github.com/gin-gonic/gin"
cors "github.com/rs/cors/wrapper/gin"
"net/http"
)
func (app *application) InitRouter() *gin.Engine {
r := gin.New()
r.Use(gin.Recovery())
r.Use(cors.Default())
r.GET("/", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "Hello World")
})
user := r.Group("/api/user")
{
user.POST("/add", app.CreateUser)
}
return r
}
I have no idea how am I supposed to fix it and what is done wrong. I'd appreciate any hint about what isn't done correctly.
Answer based on #mkopriva help in comments.
The issue was related to not running all needed .go files.
In my case, the solution was to build it this way in my Makefile:
go build -o $(path)users cmd/app/*
In similar cases, go run . most likely will do the job.

HTTP GET, from specific local IP, using alternate DNS

First, newbie to Go. Next, I am trying to run the following code below and experiencing this error
2021/06/16 18:24:15 Get "https://www.cnn.com": dial tcp: lookup www.cnn.com on 192.168.100.200:53: dial udp: address 192.168.100.65: mismatched local address type
exit status 1
My end goal is to use a predefined DNS server (alternate from the OS) and create a HTTP/S connection using a specific local IP address. I also suspect this could be accomplished with less code, so would love to understand this more from someone more familiar with Go.
package main
import (
"context"
"io/ioutil"
"log"
"net"
"net/http"
"time"
)
func main() {
q := net.ParseIP("192.168.100.65")
addr := &net.IPAddr{q,""}
var (
dnsResolverIP = "8.8.8.8:53"
dnsResolverProto = "udp"
dnsResolverTimeoutMs = 5000
)
dialer := &net.Dialer{
Resolver: &net.Resolver {
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer {
LocalAddr: addr,
Timeout: time.Duration(dnsResolverTimeoutMs) * time.Millisecond,
}
return d.DialContext(ctx, dnsResolverProto, dnsResolverIP)
},
},
}
dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, network, addr)
}
http.DefaultTransport.(*http.Transport).DialContext = dialContext
httpClient := &http.Client{}
// Testing the new HTTP client with the custom DNS resolver.
resp, err := httpClient.Get("https://www.cnn.com")
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
log.Println(string(body))
}

TCP client not working correcty golang

I have rest-ful interface written in golang. I need to do the authentication on each endpoint. once authentication is done I have to forward it back to a tcp server.
I created a tcp client and any value that is coming from the channel is to be send to tcp server. the channel is populated from the http request body.
The issue is that once I issue curl command the client is stuck with no response; so obviously I am doing something wrong not sure what is wrong. does anyone have any insights on what my problem might be?
package main
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"net/http/httputil"
"net/url"
"os"
"strconv"
auth "github.com/abbot/go-http-auth"
)
type Configuration struct {
Server string
Port int64
UserName string
Pwd string
Realm string
ProxyPort int64
Edeserver string
}
var (
Config *Configuration
logp = flag.Bool("log", false, "enable logging")
)
func ReadConfiguration() {
file, _ := os.Open("Config.json")
decoder := json.NewDecoder(file)
Config = &Configuration{}
err := decoder.Decode(&Config)
if err != nil {
fmt.Println("error:", err)
}
}
func Secret(user, realm string) string {
if user == Config.UserName {
// password is "hello"
return Config.Pwd
}
return ""
}
func reverseProxyTows(w http.ResponseWriter, authenticatedRequest *auth.AuthenticatedRequest) {
req := &authenticatedRequest.Request
if *logp {
log.Println(" Authenticated Username ", authenticatedRequest.Username)
log.Println(" Authenticated URL ", req.URL.RequestURI())
}
destinationURL := fmt.Sprintf("http://%s:%d", Config.Server, Config.Port)
u, err := url.Parse(destinationURL)
if err != nil {
log.Fatal(err)
}
if *logp {
log.Println("reverse_proxy", u)
}
reverseProxy := httputil.NewSingleHostReverseProxy(u)
reverseProxy.ServeHTTP(w, req)
}
func openConnectionTotcp(edechannel chan string) {
conn, _ := net.Dial("tcp", Config.Edeserver)
text := <-edechannel
fmt.Fprintf(conn, text+"\n")
message, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Print("Message from server: " + message)
}
func main() {
ReadConfiguration()
flag.Parse()
c := make(chan string)
go openConnectionTotcp(c)
fmt.Printf("Started proxy to destination server %v:%d and is listening on %d ", Config.Server, Config.Port, Config.ProxyPort)
authenticator := auth.NewBasicAuthenticator(Config.Realm, Secret)
http.HandleFunc("/", authenticator.Wrap(reverseProxyTows))
http.HandleFunc("/tyrion/1", authenticator.Wrap(func(w http.ResponseWriter, authenticatedRequest *auth.AuthenticatedRequest) {
req := &authenticatedRequest.Request
bodyBytes, err2 := ioutil.ReadAll(req.Body)
if err2 != nil {
log.Fatal(err2)
}
bodyString := string(bodyBytes)
c <- bodyString
fmt.Fprintf(w, "success")
}))
http.ListenAndServe(":"+strconv.FormatInt(Config.ProxyPort, 10), nil)
}
Your code execution blocks at c <- bodyString because nothing appears to be reading from that unbuffered channel. That line will pause execution until another routine reads from the channel.

malformed HTTP status code "/" error in Go

Server.go
package main
import (
"fmt"
"net/http"
//"strings"
"encoding/json"
"io/ioutil"
"strconv"
"net"
"bufio"
)
type Message struct {
Text string
}
func Unmarshal(data []byte, v interface{}) error
func main() {
//http.HandleFunc("/", handler)
server,_ := net.Listen("tcp", ":" + strconv.Itoa(8080))
if server == nil {
panic("couldn't start listening: ")
}
conns := clientConns(server)
for {
go handleConn(<-conns)
}
}
func clientConns(listener net.Listener) chan net.Conn {
ch := make(chan net.Conn)
i := 0
go func() {
for {
client, _ := listener.Accept()
if client == nil {
fmt.Printf("couldn't accept: ")
continue
}
i++
fmt.Printf("%d: %v <-> %v\n", i, client.LocalAddr(), client.RemoteAddr())
ch <- client
}
}()
return ch
}
func handleConn(client net.Conn) {
b := bufio.NewReader(client)
fmt.Println("Buffer")
for {
line, err := b.ReadBytes('\n')
if err != nil { // EOF, or worse
break
}
client.Write(line)
}
}
Client.go
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"flag"
//"io"
// "net"
// "net/rpc"
// "sync"
)
func Unmarshal(data []byte, v interface{}) error
func Marshal(v interface{}) ([]byte, error)
type Message struct {
Text string
}
func main(){
var flagtext = flag.String("flagtext", "Hello!", "Flag")
flag.Parse()
var text string
text = *flagtext
m := Message{text}
var m1 Message
b, err := json.Marshal(m)
if err == nil{
resp, err := http.Post("http://127.0.0.1:8080","application/json", strings.NewReader(string(b)))
if err != nil{
log.Fatal("Error while post: %v",err)
}
fmt.Println(resp)
err = json.Unmarshal(b, &m1)
}
}
Error I get when I run client.go is this:
Error while post: %vmalformed HTTP status code "/"
Though, the server registers a channel for each post, it shows a malformed HTTP status code. Is it because I'm listening in the wrong channel? I'm confused why this error is occurring.
This line in the server code:
client.Write(line)
sends the request line back to the client. Since the client is posting something like GET / HTTP/1.1, this means that the server is responding with something like GET / HTTP/1.1, instead of something like HTTP/1.1 200 OK. The error-message you're seeing is because / appears in the status-code position.
In server.go it seems you are trying to write your own HTTP server from the TCP socket level up. This is unnecessary work - take the easy route and use the built-in HTTP server API.
The general outline of such a server is like this:
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
and is described further in this article. More documentation is in net/http.

Resources