Difference between revisions of "Gorelay"

From UVOO Tech Wiki
Jump to navigation Jump to search
(Created page with "# Simple HTTP Relay written in go ``` package main import ( "crypto/tls" "github.com/labstack/echo/v4" "io" "net/http" ) func main() {...")
 
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
# Simple HTTP Relay written in go
 
# Simple HTTP Relay written in go
 +
 +
## run.sh
 +
```
 +
#!/bin/bash
 +
set -eu
 +
 +
go build gorelay.go
 +
pkill gorelay || true
 +
sleep 2
 +
./gorelay -fqdn="192.168.x.y" -port=8443 -username="admin" -password="admin" -skip_tls_verify=true -uri_reg_old "/api/v1/foo/" -uri_reg_new "/api/v1/bar/"
 +
```
 +
## curl
 +
```
 +
cat <<EOF > example.json
 +
{
 +
"foo": "bar"
 +
}
 +
 +
curl -sku $AUTH -X POST -d @example.json https://proxyhost.example.com/foo
 +
```
 +
 +
## gorelay.go
 
```
 
```
 
package main
 
package main
Line 5: Line 27:
 
import (
 
import (
 
         "crypto/tls"
 
         "crypto/tls"
         "github.com/labstack/echo/v4"
+
         "flag"
 +
        "fmt"
 
         "io"
 
         "io"
 +
        "log"
 
         "net/http"
 
         "net/http"
 +
        "regexp"
 +
        "time"
 +
 +
        "github.com/labstack/echo/v4"
 
)
 
)
 +
 +
func syslogLogger(next echo.HandlerFunc) echo.HandlerFunc {
 +
        return func(c echo.Context) error {
 +
                start := time.Now()
 +
                err := next(c)
 +
                stop := time.Now()
 +
                req := c.Request()
 +
                res := c.Response()
 +
 +
                log.Printf("%s - [%s] \"%s %s %s\" %d %d %v",
 +
                        c.RealIP(),
 +
                        stop.Format(time.RFC3339),
 +
                        req.Method, req.RequestURI, req.Proto,
 +
                        res.Status, res.Size, stop.Sub(start),
 +
                )
 +
 +
                return err
 +
        }
 +
}
  
 
func main() {
 
func main() {
 +
        schema := flag.String("schema", "https", "URI schema (http or https)")
 +
        port := flag.Int("port", 443, "Port number of the remote HTTPS endpoint")
 +
        fqdn := flag.String("fqdn", "", "Fully Qualified Domain Name (required)")
 +
        username := flag.String("username", "", "Username for basic authentication")
 +
        password := flag.String("password", "", "Password for basic authentication")
 +
        skipTLS := flag.Bool("skip_tls_verify", false, "Skip TLS certificate verification")
 +
        uriRegOld := flag.String("uri_reg_old", "", "Regex to replace in URI")
 +
        uriRegNew := flag.String("uri_reg_new", "", "String to replace old URI")
 +
        flag.Parse()
 +
 +
        if *fqdn == "" {
 +
                panic("FQDN argument is required")
 +
        }
 +
 +
        uriBase := fmt.Sprintf("%s://%s:%d", *schema, *fqdn, *port)
 +
 
         e := echo.New()
 
         e := echo.New()
 +
 +
        e.Use(syslogLogger)
  
 
         e.Any("/*", func(c echo.Context) error {
 
         e.Any("/*", func(c echo.Context) error {
Line 17: Line 82:
  
 
                 client := &http.Client{}
 
                 client := &http.Client{}
                 client.Transport = &http.Transport{
+
                 if *skipTLS {
                        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+
                        client.Transport = &http.Transport{
 +
                                TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
 +
                        }
 
                 }
 
                 }
 +
                regex := regexp.MustCompile(*uriRegOld)
 +
                replaceStr := *uriRegNew
 +
                requestURI := regex.ReplaceAllString(req.RequestURI, replaceStr)
  
                // Create a new request
+
                 newReq, err := http.NewRequest(req.Method, uriBase+requestURI, req.Body)
                 newReq, err := http.NewRequest(req.Method, "https://192.168.1.1:8443"+req.RequestURI, req.Body)
 
 
                 if err != nil {
 
                 if err != nil {
 
                         return err
 
                         return err
 
                 }
 
                 }
  
                // Copy the headers
+
 
 
                 for k, v := range req.Header {
 
                 for k, v := range req.Header {
 
                         newReq.Header[k] = v
 
                         newReq.Header[k] = v
 +
                }
 +
                if *username != "" && *password != "" {
 +
                        newReq.SetBasicAuth(*username, *password)
 
                 }
 
                 }
  
                // Send the request
 
 
                 resp, err := client.Do(newReq)
 
                 resp, err := client.Do(newReq)
 
                 if err != nil {
 
                 if err != nil {
Line 39: Line 110:
 
                 defer resp.Body.Close()
 
                 defer resp.Body.Close()
  
                // Copy the response headers
 
 
                 for k, v := range resp.Header {
 
                 for k, v := range resp.Header {
 
                         c.Response().Header().Set(k, v[0])
 
                         c.Response().Header().Set(k, v[0])
 
                 }
 
                 }
  
                // Copy the response body
 
 
                 io.Copy(c.Response().Writer, resp.Body)
 
                 io.Copy(c.Response().Writer, resp.Body)
  
Line 50: Line 119:
 
         })
 
         })
  
         e.Start(":8080")
+
         e.Logger.Fatal(e.Start(":8080"))
 
}
 
}
 
```
 
```

Latest revision as of 02:56, 3 May 2024

Simple HTTP Relay written in go

run.sh

#!/bin/bash
set -eu

go build gorelay.go
pkill gorelay || true
sleep 2
./gorelay -fqdn="192.168.x.y" -port=8443 -username="admin" -password="admin" -skip_tls_verify=true -uri_reg_old "/api/v1/foo/" -uri_reg_new "/api/v1/bar/"

curl

cat <<EOF > example.json
{
"foo": "bar"
}

curl -sku $AUTH -X POST -d @example.json https://proxyhost.example.com/foo

gorelay.go

package main

import (
        "crypto/tls"
        "flag"
        "fmt"
        "io"
        "log"
        "net/http"
        "regexp"
        "time"

        "github.com/labstack/echo/v4"
)

func syslogLogger(next echo.HandlerFunc) echo.HandlerFunc {
        return func(c echo.Context) error {
                start := time.Now()
                err := next(c)
                stop := time.Now()
                req := c.Request()
                res := c.Response()

                log.Printf("%s - [%s] \"%s %s %s\" %d %d %v",
                        c.RealIP(),
                        stop.Format(time.RFC3339),
                        req.Method, req.RequestURI, req.Proto,
                        res.Status, res.Size, stop.Sub(start),
                )

                return err
        }
}

func main() {
        schema := flag.String("schema", "https", "URI schema (http or https)")
        port := flag.Int("port", 443, "Port number of the remote HTTPS endpoint")
        fqdn := flag.String("fqdn", "", "Fully Qualified Domain Name (required)")
        username := flag.String("username", "", "Username for basic authentication")
        password := flag.String("password", "", "Password for basic authentication")
        skipTLS := flag.Bool("skip_tls_verify", false, "Skip TLS certificate verification")
        uriRegOld := flag.String("uri_reg_old", "", "Regex to replace in URI")
        uriRegNew := flag.String("uri_reg_new", "", "String to replace old URI")
        flag.Parse()

        if *fqdn == "" {
                panic("FQDN argument is required")
        }

        uriBase := fmt.Sprintf("%s://%s:%d", *schema, *fqdn, *port)

        e := echo.New()

        e.Use(syslogLogger)

        e.Any("/*", func(c echo.Context) error {
                req := c.Request()

                client := &http.Client{}
                if *skipTLS {
                        client.Transport = &http.Transport{
                                TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
                        }
                }
                regex := regexp.MustCompile(*uriRegOld)
                replaceStr := *uriRegNew
                requestURI := regex.ReplaceAllString(req.RequestURI, replaceStr)

                newReq, err := http.NewRequest(req.Method, uriBase+requestURI, req.Body)
                if err != nil {
                        return err
                }


                for k, v := range req.Header {
                        newReq.Header[k] = v
                }
                if *username != "" && *password != "" {
                        newReq.SetBasicAuth(*username, *password)
                }

                resp, err := client.Do(newReq)
                if err != nil {
                        return err
                }
                defer resp.Body.Close()

                for k, v := range resp.Header {
                        c.Response().Header().Set(k, v[0])
                }

                io.Copy(c.Response().Writer, resp.Body)

                return nil
        })

        e.Logger.Fatal(e.Start(":8080"))
}