gproxy

package module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2021 License: Apache-2.0 Imports: 27 Imported by: 0

README

graphik

gproxy is a reverse proxy service AND library for creating flexible, expression-based, lets-encrypt secured gRPC and http reverse proxies

GoDoc trigger/expression language reference

go get -u github.com/graphikDB/gproxy

docker pull graphikDB:gproxy:v0.0.8
    proxy, err := gproxy.New(ctx,
		// serve unencrypted http/gRPC traffic on port 8080
		gproxy.WithInsecurePort(8080),
		// serve encrypted http/gRPC traffic on port 443
		gproxy.WithSecurePort(443),
		// if the request is http & the request host contains localhost, proxy to the target server
		gproxy.WithTrigger(fmt.Sprintf(`this.http && this.host.contains('localhost') => { "target": "%s"}`, srv.URL)), // must return "target" attribute in the json map
		// when deploying, set the letsencrypt list of allowed domains
		gproxy.WithLetsEncryptHosts([]string{
			// "www.graphikdb.io",
		}))
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	if err := proxy.Serve(ctx); err != nil {
		fmt.Println(err.Error())
		return
	}

Library Features

  • Automatic Lets Encrypt Based SSL Encryption
  • Transparent gRPC Proxy(including streaming)
  • Transparent http Proxy(including websockets)
  • Expression-Based Routing
  • Add HTTP Middlewares
  • Add gRPC Unary Interceptors
  • Add gRPC Stream Interceptors
  • MTLS

Service Features

  • Automatic Lets Encrypt Based SSL Encryption
  • Transparent gRPC Proxy(including streaming)
  • Transparent http Proxy(including websockets)
  • CORS
  • Expression-Based Routing
  • 12-Factor Config
  • Hot Reload Config
  • Dockerized(graphikDB:gproxy:v0.0.8)
  • K8s Deployment Manifest
  • Docker-Compose File

GProxy as a Service

default config path: ./gproxy.yaml which may be changed with the --config flag or the GRAPHIK_CONFIG environmental variable

Example Config:

debug: true
autocert:
  - "www.example.com"
routing:
  - "this.http && this.host == 'localhost:8080' => { 'target': 'http://localhost:7821' }"
  - "this.grpc && this.host == 'localhost:8080' => { 'target': 'localhost:7820' }"
server:
  insecure_port: 8080
  secure_port: 443
cors:
  origins: "*"
  methods: "*"
  headers:
    - "GET"
    - "POST"
    - "PUT"
    - "DELETE"
    - "PATCH"

Deployment

Kubernetes

example manifest:

apiVersion: v1
kind: Namespace
metadata:
  name: gproxy
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: gproxy-config
  namespace: gproxy
data:
  gproxy.yaml: |-
    debug: true
    autocert:
      - "www.example.com"
    routing:
      - "this.http && this.host == 'localhost:8080' => { 'target': 'http://localhost:7821' }"
      - "this.grpc && this.host == 'localhost:8080' => { 'target': 'localhost:7820' }"
    server:
      insecure_port: 8080
      secure_port: 443
    cors:
      origins: "*"
      methods: "*"
      headers:
        - "GET"
        - "POST"
        - "PUT"
        - "DELETE"
        - "PATCH"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: gproxy
  namespace: gproxy
  labels:
    app: gproxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gproxy
  serviceName: "gproxy"
  template:
    metadata:
      labels:
        app: gproxy
    spec:
      containers:
        - name: gproxy
          image: graphikdb/gproxy:v0.0.8
          imagePullPolicy: Always
          ports:
            - containerPort: 80
            - containerPort: 443
          env:
            - name: GPROXY_CONFIG
              value: /tmp/gproxy/gproxy.yaml
          volumeMounts:
            - mountPath: /tmp/certs
              name: certs-volume
            - mountPath: /tmp/gproxy/gproxy.yaml
              name: config-volume
              subPath: gproxy.yaml
      volumes:
        - name: config-volume
          configMap:
            name: gproxy-config
  volumeClaimTemplates:
    - metadata:
        name: certs-volume
      spec:
        accessModes: [ "ReadWriteOnce" ]
        resources:
          requests:
            storage: 5Mi

---
apiVersion: v1
kind: Service
metadata:
  name: gproxy
  namespace: gproxy
spec:
  selector:
    app: gproxy
  ports:
    - protocol: TCP
      port: 80
      name: insecure
    - protocol: TCP
      port: 443
      name: secure
  type: LoadBalancer
---

apply with kubectl apply -f k8s.yaml

Docker-Compose

Coming Soon

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Middleware

type Middleware func(handler http.Handler) http.Handler

Middleware is an http middleware

type Opt

type Opt func(p *Proxy) error

Opt is a function that configures a Proxy instance

func WithAutoRedirectHttps added in v0.0.8

func WithAutoRedirectHttps(redirect bool) Opt

WithAutoRedirectHttps makes the proxy redirect http requests to https(443)

func WithCertCacheDir added in v0.0.5

func WithCertCacheDir(certCache string) Opt

WithCertCacheDir sets the directory in which certificates will be cached (default: /tmp/certs)

func WithInsecurePort

func WithInsecurePort(insecurePort int) Opt

WithInsecurePort sets the port that non-encrypted traffic will be served on(optional)

func WithLetsEncryptHosts added in v0.0.7

func WithLetsEncryptHosts(allowedHosts []string) Opt

WithLetsEncryptHosts sets the letsencryp host policy on the proxy(required)

func WithLogger

func WithLogger(logger *logger.Logger) Opt

WithLogger sets the proxies logger instance(optional)

func WithMiddlewares

func WithMiddlewares(middlewares ...Middleware) Opt

WithMiddlewares sets the http middlewares on encrypted & non-encrypted traffic(optional)

func WithSecurePort

func WithSecurePort(securePort int) Opt

WithSecurePort sets the port that encrypted traffic will be served on(optional)

func WithStreamInterceptors

func WithStreamInterceptors(sinterceptors ...grpc.StreamServerInterceptor) Opt

WithStreamInterceptors adds gRPC stream interceptors to the proxy instance

func WithTrigger added in v0.0.7

func WithTrigger(triggerExpression string) Opt

WithTrigger adds a trigger/expression based route to the reverse proxy

func WithUnaryInterceptors

func WithUnaryInterceptors(uinterceptors ...grpc.UnaryServerInterceptor) Opt

WithUnaryInterceptors adds gRPC unary interceptors to the proxy instance

type Proxy

type Proxy struct {
	// contains filtered or unexported fields
}

Proxy is a secure(lets encrypt) gRPC & http reverse proxy

func New

func New(ctx context.Context, opts ...Opt) (*Proxy, error)

New creates a new proxy instance. A host policy & either http routes, gRPC routes, or both are required.

Example
package main

import (
	"context"
	"fmt"
	"github.com/graphikDB/gproxy"
	"net/http"
	"net/http/httptest"
	"time"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello world"))
	}))

	proxy, err := gproxy.New(ctx,
		// serve unencrypted http/gRPC traffic on port 8080
		gproxy.WithInsecurePort(8080),
		// serve encrypted http/gRPC traffic on port 443
		gproxy.WithSecurePort(443),
		// if the request is http & the request host contains localhost, proxy to the target server
		gproxy.WithTrigger(fmt.Sprintf(`this.http && this.host.contains('localhost') => { "target": "%s"}`, srv.URL)),
		// when deploying, set the letsencrypt allowed domains
		gproxy.WithLetsEncryptHosts([]string{
			// "www.graphikdb.io",
		}))
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	if err := proxy.Serve(ctx); err != nil {
		fmt.Println(err.Error())
		return
	}
}
Output:

func (*Proxy) Serve

func (p *Proxy) Serve(ctx context.Context) error

Serve starts the gRPC(if grpc router was registered) & http proxy(if http router was registered)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL