j8a

package module
v0.9.2 Latest Latest
Warning

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

Go to latest
Published: Apr 12, 2022 License: Apache-2.0 Imports: 61 Imported by: 1

README

Circleci Builds Github Workflows Dependabot Github Issues Github Activity
Go Report Codeclimate Maintainability Codeclimate Test Coverage SSLLabs Rating Go Version License Docker Pulls Version

What's new?

v0.9.2

  • Shorter default http upstream timeout, for details see https://j8a.io/docs
  • upgraded jwx dependency to v1.2.22

v0.9.1 (03/04/2022)

  • Support for proxying Brotli (RFC7932) compressed streams, including brotli encoding for upstream content.
  • update to go 1.18

v0.9.0 (30/09/2021)

  • ACME (RFC8555) support. Server auto-renews TLS certificates 30 days before expiry for free with zero downtime, no restarts!
  • update to go 1.17

v0.8.5 (01/07/2021)

  • downstream responses with status code >=400 now drop TCP connections for both HTTP/1.1 and HTTP/2
  • more tests for HTTP/2 request/response cycles
  • minor performance improvements

What is j8a?

j8a [ dʒʌbbʌ ] is a modern TLS 1.3 reverse proxy server designed as a lightweight API gateway for micro-service style JSON APIs. It is built for DevOps engineers and allows fine-grained traceability of HTTP and Websocket traffic without sacrificing performance.

Features

  • Fast! 5k POST req/s traffic.
  • Secure. TLS1.2, TLS/1.3 termination w/ A+ SSLLabs rating.
  • Zero downtime. Auto-renew certs using ACME RFC 8555.
  • Observable. API request tracing w/ correlation ID for upstream micro-services.
  • APM. CPU, memory logging built-in. Daily TLS health and validity check for your full certificate chain.
  • JWT token validation with full JWK(S) support for RFC 7519.
  • HTTP/1.1 and HTTP/2 support w/ upstream <> downstream protocol translation.
  • Websocket Support for RFC 6455
  • Docker native

Up and running

Docker

docker pull simonmittag/j8a &&
docker run -e J8ACFG_YML -p443:443 simonmittag/j8a

Linux / Darwin

go install github.com/simonmittag/j8a/cmd/j8a && j8a

Configuration

Environment Variables

J8ACFG_YML

Supply the server configuration to the running process in .yml format

J8ACFG_YML="---
            connection:
              downstream:
                readTimeoutSeconds: 3
                roundTripTimeoutSeconds: 20
                idleTimeoutSeconds: 30
                http:
                  port: 80
                maxBodyBytes: 65535
              upstream:
                socketTimeoutSeconds: 3
                readTimeoutSeconds: 30
                idleTimeoutSeconds: 10
                maxAttempts: 4
                poolSize: 8
                tlsInsecureSkipVerify: true
            routes:
              - path: "/todos"
                resource: jsonplaceholder
            resources:
              jsonplaceholder:
                - url:
                    scheme: https
                    host: jsonplaceholder.typicode.com
                    port: 443"
LOGLEVEL

Loglevel for stdout, one of TRACE, DEBUG, INFO or WARN

LOGLEVEL="DEBUG"
TZ

TimeZone

TZ="Australia/Sydney"

Contributions

The j8a team welcomes all contributors. Everyone interacting with the project's codebase, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct

Documentation

Index

Constants

View Source
const AcceptEncodingS = "Accept-Encoding"
View Source
const COMMA = ","
View Source
const Days30 = time.Duration(time.Hour * 24 * 30)
View Source
const Days398 = PDuration(time.Hour * 24 * 398)
View Source
const DefaultConfigFile = "j8acfg.yml"
View Source
const EOF = "EOF"
View Source
const HTTP = "HTTP"
View Source
const HTTP11 = "1.1"
View Source
const HTTPS = "https://"
View Source
const J8ACFG_YML = "J8ACFG_YML"
View Source
const Q = "?"
View Source
const STAR = "*"
View Source
const Server string = "Server"

Version is the server version

View Source
const TLS = "TLS"
View Source
const UpgradeHeader = "Upgrade"
View Source
const XRequestID = "X-Request-Id"

XRequestID is a per HTTP request unique identifier

Variables

View Source
var ConfigFile = ""
View Source
var GzipContentEncodings = AcceptEncoding{EncGzip, EncXGzip}
View Source
var ID string = "unknown"

ID is a unique server ID

View Source
var SupportedContentEncodings = AcceptEncoding{EncStar, EncIdentity, EncBrotli, EncGzip, EncXGzip}
View Source
var TZ = "UTC"
View Source
var Version string = "v0.9.2"

Functions

func BootStrap

func BootStrap()

BootStrap starts up the server from a ServerConfig

func BrotliDecode added in v0.9.1

func BrotliDecode(input []byte) *[]byte

BrotliDecode decodes a []byte from Brotli binary format

func BrotliEncode added in v0.9.1

func BrotliEncode(input []byte) *[]byte

BrotliEncode encodes to brotli from byte array.

func ChunkString added in v0.9.0

func ChunkString(s string, chunkSize int) []string

func Gunzip

func Gunzip(input []byte) *[]byte

Gunzip a []byte

func Gzip

func Gzip(input []byte) *[]byte

Gzip a []byte

func JoinHashString added in v0.9.0

func JoinHashString(hash []byte) string

Types

type AboutResponse

type AboutResponse struct {
	J8a      string
	ServerID string
	Version  string
}

AboutResponse exposes standard environment

func (AboutResponse) AsJSON

func (aboutResponse AboutResponse) AsJSON() []byte

AsJSON renders the status Code response into a JSON string as []byte

func (AboutResponse) AsString

func (aboutResponse AboutResponse) AsString() string

type AcceptEncoding added in v0.9.1

type AcceptEncoding []ContentEncoding

func (AcceptEncoding) Print added in v0.9.1

func (ae AcceptEncoding) Print() string

type Acme added in v0.9.0

type Acme struct {
	// Acme Provider, currently supports letsencrypt
	Provider string

	// Domain
	Domains []string

	// Email for registration. Auto generated from domain.
	Email string
}

type AcmeHandler added in v0.9.0

type AcmeHandler struct {
	Active   map[string]bool
	Domains  map[string]string
	KeyAuths map[string][]byte
}

func NewAcmeHandler added in v0.9.0

func NewAcmeHandler() *AcmeHandler

func (*AcmeHandler) CleanUp added in v0.9.0

func (a *AcmeHandler) CleanUp(domain, token, keyAuth string) error

func (*AcmeHandler) Present added in v0.9.0

func (a *AcmeHandler) Present(domain, token, keyAuth string) error

type AcmeUser added in v0.9.0

type AcmeUser struct {
	Email        string
	Registration *registration.Resource
	// contains filtered or unexported fields
}

func (*AcmeUser) GetEmail added in v0.9.0

func (u *AcmeUser) GetEmail() string

func (*AcmeUser) GetPrivateKey added in v0.9.0

func (u *AcmeUser) GetPrivateKey() crypto.PrivateKey

func (AcmeUser) GetRegistration added in v0.9.0

func (u AcmeUser) GetRegistration() *registration.Resource

type Atmpt

type Atmpt struct {
	URL             *URL
	Label           string
	Count           int
	StatusCode      int
	ContentEncoding ContentEncoding

	CompleteHeader chan struct{}
	CompleteBody   chan struct{}
	Aborted        <-chan struct{}
	AbortedFlag    bool
	CancelFunc     func()
	// contains filtered or unexported fields
}

Atmpt wraps connection attempts to specific upstreams that are already mapped by label

type Config

type Config struct {
	Policies   map[string]Policy
	Routes     Routes
	Jwt        map[string]*Jwt
	Resources  map[string][]ResourceMapping
	Connection Connection
}

Config is the system wide configuration for j8a

type Connection

type Connection struct {
	Downstream Downstream
	Upstream   Upstream
}

Connection Params

type ContentEncoding added in v0.9.1

type ContentEncoding string
const (
	EncStar      ContentEncoding = "*"
	EncIdentity  ContentEncoding = "identity"
	EncBrotli    ContentEncoding = "br"
	EncGzip      ContentEncoding = "gzip"
	EncXGzip     ContentEncoding = "x-gzip"
	EncDeflate   ContentEncoding = "deflate"
	EncXDeflate  ContentEncoding = "x-deflate"
	EncCompress  ContentEncoding = "compress"
	EncXCompress ContentEncoding = "x-compress"
)

func NewContentEncoding added in v0.9.1

func NewContentEncoding(raw string) ContentEncoding

type Down

type Down struct {
	Req            *http.Request
	Resp           Resp
	Method         string
	Path           string
	URI            string
	UserAgent      string
	AcceptEncoding AcceptEncoding
	Body           []byte
	Aborted        <-chan struct{}
	AbortedFlag    bool
	Timeout        <-chan struct{}
	TimeoutFlag    bool
	ReqTooLarge    bool

	HttpVer  string
	TlsVer   string
	Port     int
	Listener string
	// contains filtered or unexported fields
}

Down wraps downstream exchange

type Downstream

type Downstream struct {
	// ReadTimeoutSeconds is the maximum duration for reading the entire
	// request, including the body, the downstream user agent sends to us.
	ReadTimeoutSeconds int

	// WriteTimeoutSeconds is the maximum duration round trip time in seconds any
	// single request spends in the server, this includes the time to read the request,
	// processing upstream attempts and writing the response into downstream socket.
	RoundTripTimeoutSeconds int

	// IdleTimeoutSeconds is the maximum duration, a downstream idle socket connection is kept open
	// before the server hangs up on the downstream user agent.
	IdleTimeoutSeconds int

	// MaxBodyBytes is the maximum size of the incoming HTTP request body before it is rejected
	MaxBodyBytes int64

	// Http block. defaults to on
	Http Http

	// Tls block defaults to off
	Tls Tls
}

Downstream params for the HTTP or TLS server that j8a exposes

type HTTPClient

type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
	Get(uri string) (*http.Response, error)
}

type HandlerDelegate added in v0.8.0

type HandlerDelegate struct{}

func (HandlerDelegate) ServeHTTP added in v0.8.0

func (hd HandlerDelegate) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Http added in v0.7.5

type Http struct {
	// Serving HTTP on this port
	Port int

	// Redirect HTTP to tls if set to "TLS". Only one value allowed.
	Redirecttls bool
}

type Jwt added in v0.7.0

type Jwt struct {
	Name string
	Alg  string
	// Jwt key supports pem encoding for public keys, certificates unencoded secrets for hmac.
	Key string
	// JwksUrl loads remotely.
	JwksUrl               string
	RSAPublic             KeySet
	ECDSAPublic           KeySet
	Secret                KeySet
	AcceptableSkewSeconds string
	Claims                []string
	// contains filtered or unexported fields
}

func NewJwt added in v0.7.1

func NewJwt(name string, alg string, key string, jwksUrl string, acceptableSkewSeconds string, claims ...string) *Jwt

func (*Jwt) Init added in v0.7.1

func (jwt *Jwt) Init()

we need this separate because the JSON unmarshaller creates this object without asking us.

func (*Jwt) LoadJwks added in v0.7.0

func (jwt *Jwt) LoadJwks() error

TODO this method needs a refactor and has high cognitive complexity

func (*Jwt) Validate added in v0.7.1

func (jwt *Jwt) Validate() error

type KeySet added in v0.7.0

type KeySet []KidPair

func (*KeySet) Find added in v0.7.1

func (ks *KeySet) Find(kid string) interface{}

func (*KeySet) Upsert added in v0.7.1

func (ks *KeySet) Upsert(kp KidPair)

type KidPair added in v0.7.0

type KidPair struct {
	Kid string
	Key interface{}
}

type LabelWeight

type LabelWeight struct {
	Label  string
	Weight float64
}

LabelWeight describes routing to labels

type PDuration

type PDuration time.Duration

func (PDuration) AsDays

func (p PDuration) AsDays() int

func (PDuration) AsDuration

func (p PDuration) AsDuration() time.Duration

func (PDuration) AsString

func (p PDuration) AsString() string

type Policy

type Policy []LabelWeight

Policy defines an array of LabelWeights used for routing

func (Policy) Len

func (policy Policy) Len() int

func (Policy) Less

func (policy Policy) Less(i, j int) bool

func (Policy) Swap

func (policy Policy) Swap(i, j int)

type Proxy

type Proxy struct {
	XRequestID   string
	XRequestInfo bool
	Up           Up
	Dwn          Down
	Route        *Route
}

Proxy wraps data for a single downstream request/response with multiple upstream HTTP request/response cycles.

type ReloadableCert added in v0.9.0

type ReloadableCert struct {
	Cert *tls.Certificate

	Init bool
	// contains filtered or unexported fields
}

func (*ReloadableCert) GetCertificateFunc added in v0.9.0

func (r *ReloadableCert) GetCertificateFunc(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error)

type ResourceMapping

type ResourceMapping struct {
	Name   string
	Labels []string
	URL    URL
}

ResourceMapping describes upstream servers

type Resp

type Resp struct {
	Writer          http.ResponseWriter
	StatusCode      int
	Message         string
	Body            *[]byte
	ContentLength   int64
	ContentEncoding ContentEncoding
}

Resp wraps downstream http response writer and data

type Route

type Route struct {
	Path      string
	PathRegex *regexp.Regexp
	Transform string
	Resource  string
	Policy    string
	Jwt       string
}

Route maps a Path to an upstream resource

type Routes

type Routes []Route

func (Routes) Len

func (s Routes) Len() int

func (Routes) Less

func (s Routes) Less(i, j int) bool

func (Routes) Swap

func (s Routes) Swap(i, j int)

type Runtime

type Runtime struct {
	Config
	Start          time.Time
	Memory         []sample
	AcmeHandler    *AcmeHandler
	ReloadableCert *ReloadableCert
	// contains filtered or unexported fields
}

Runtime struct defines runtime environment wrapper for a config.

var Runner *Runtime

Runner is the Live environment of the server

type StatusCodeResponse

type StatusCodeResponse struct {
	AboutResponse
	Code    int
	Message string
}

StatusCodeResponse defines a JSON structure for a canned HTTP response

func (StatusCodeResponse) AsJSON

func (statusCodeResponse StatusCodeResponse) AsJSON() []byte

AsJSON renders the status Code response into a JSON string as []byte

func (StatusCodeResponse) AsString

func (statusCodeResponse StatusCodeResponse) AsString() string

type TLSType

type TLSType string
const (
	TLS12         TLSType = "1.2"
	TLS13         TLSType = "1.3"
	TLS_UNKNOWN   TLSType = "unknown"
	TLS_NONE      TLSType = "none"
	Authorization         = "Authorization"
	Sep                   = " "
)

type Tls added in v0.7.5

type Tls struct {
	// Serving on this port
	Port int

	// TLS x509 certificate
	Cert string

	// TLS secret key
	Key string

	// Acme config for TLS. Optional, but conflicts with Cert and Key
	Acme Acme
}
type TlsLink struct {
	// contains filtered or unexported fields
}

type URL

type URL struct {
	Scheme string
	Host   string
	Port   uint16
}

URL describes host mapping

func (URL) String

func (u URL) String() string

String representation of our URL struct

type Up

type Up struct {
	Atmpt  *Atmpt
	Atmpts []Atmpt
	Count  int
}

Up wraps upstream

type Upstream

type Upstream struct {

	// PoolSize is the maximum size of the client socket connection pool for idle connections
	PoolSize int

	// IdleTimeoutSeconds is the total wait period in seconds before we hang up on an idle upstream connection.
	IdleTimeoutSeconds int

	// SocketTimeoutSeconds is the wait period to establish socket connection with an upstream server.
	// This setting controls roundtrip time for establishing simple TCP connections, combined with handshake time for TLS
	// if applicable.
	SocketTimeoutSeconds int

	// ReadTimeoutSeconds is the wait period to read the entire upstream response once connection was established
	// before an individual upstream request is aborted
	ReadTimeoutSeconds int

	// MaxAttempts is the maximum allowable number of request attempts to obtain a successful response for repeatable
	// HTTP requests.
	MaxAttempts int

	// TlsInsecureSkipVerify skips the host name validation and certificate chain verification of upstream connections
	// using TLS. Use this only for testing or if you know what you are doing. Defaults to false
	TlsInsecureSkipVerify bool
}

Upstream connection params for remote servers that are being proxied

type WebsocketStatus added in v0.8.0

type WebsocketStatus struct {
	DwnOpCode ws.OpCode
	DwnExit   error
	UpOpCode  ws.OpCode
	UpExit    error
}

type WebsocketTx added in v0.8.0

type WebsocketTx struct {
	UpBytesRead   int64
	UpBytesWrite  int64
	DwnBytesRead  int64
	DwnBytesWrite int64
}

Directories

Path Synopsis
cmd
j8a command

Jump to

Keyboard shortcuts

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