proxy

package
v0.0.0-...-85548f4 Latest Latest
Warning

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

Go to latest
Published: Mar 24, 2019 License: GPL-3.0 Imports: 21 Imported by: 0

Documentation

Index

Examples

Constants

View Source
const CertOrg = "GoMITMProxy"

Certificate Organization used when generating the certificate authority

View Source
const DefaultDNSServer = "8.8.8.8"

DefaultDNSServer is the default forward dns server DNSServer will use if ForwardDNSServer is left unset

View Source
const DefaultKeyAge = time.Hour * 24

Default max age a certificate authority will be valid for. Automatically generated host keys are set to expire no later then the CA's max age.

View Source
const ERRCastErrorFailed = ErrorStr("cast to type proxy error failed")

Error unable to cast go error to ProxyError

View Source
const ERRCertCAExpired = ErrorStr("ca expired")

Error certificate authority has expired

View Source
const ERRCertCAParse = ErrorStr("parse ca failed")

Error unable to parse ca

View Source
const ERRCertCARead = ErrorStr("read ca file failed")

Error unable to read ca file

View Source
const ERRCertGenCA = ErrorStr("generate ca failed")

Error generating certificate authority

View Source
const ERRCertGenHostKey = ErrorStr("generate host key failed")

Error failed to generate host key

View Source
const ERRCertGenerateKey = ErrorStr("generate key failed")

Error generating key

View Source
const ERRCertNoCA = ErrorStr("no certificate authority set")

Error no certificate authority set in Certs

View Source
const ERRCertWriteCA = ErrorStr("writing ca to disk failed")

Error writing certificate authority files to disk

View Source
const ERRCertx509Create = ErrorStr("create x509 cert failed")

Error creating x509 certificate

View Source
const ERRCertx509Parse = ErrorStr("parse x509 cert failed")

Error parsing x509 certificate

View Source
const ERRHTTPProxyStart = ErrorStr("http server failed to start")

Error returned when http server fails to start

View Source
const ERRProxyShutdown = ErrorStr("proxy shutdown failed")

Error returned when shutting down the http and https servers fails

View Source
const ERRTLSProxyStart = ErrorStr("https server failed to start")

Error returned when https server fails to start

View Source
const EXITCODECertFatal = 131

Exit code returned when an unrecoverable certificate error occurs

View Source
const EXITCODEDNSServer = 132

Exit code returns when the dns server fails

View Source
const EXITCODEProxyServer = 129

Exit code returned when the proxy server fails

View Source
const GoMITMProxyHeader = "GoMITMProxy"

GoMITMProxyHeader is the header key added to all requests, and server responses that are proxied.

View Source
const KeyLength = 1024

Key length for certificate authority, and host keys

View Source
const Version = "0.3.1"

Variables

This section is empty.

Functions

This section is empty.

Types

type Certs

type Certs struct {
	KeyAge time.Duration `json:"key_age"`
	// contains filtered or unexported fields
}

Certs generates and stores certificates for MITMProxy. Virtual host certificates are generated on demand, and cached.

func (*Certs) GenerateCAPair

func (c *Certs) GenerateCAPair() (key *rsa.PrivateKey, cert *x509.Certificate, err error)

GenerateCAPair generates a certificate authority key and cert pair. It both stores, and returns the generated pair.

Example
package main

import (
	"github.com/jmizell/GoMITMProxy/proxy"
	"log"
)

func main() {

	// Create the cert store
	certs := &proxy.Certs{}

	// Generate a RSA private key, and x509 certificate for the cert authority
	_, _, err := certs.GenerateCAPair()
	if err != nil {
		log.Fatal(err)
	}

	// Write the key and certs as PEM encoded files to disk
	err = certs.WriteCA("/path/to/cert.crt", "/path/to/key.key")
	if err != nil {
		log.Fatal(err)
	}
}
Output:

func (*Certs) GenerateHostKey

func (c *Certs) GenerateHostKey(vhost string) (*tls.Certificate, error)

GenerateHostKey returns a tls.Certificate for a given virtual host, signed by the CA.

func (*Certs) Get

func (c *Certs) Get(vhost string) (*tls.Certificate, error)

Get attempts to retrieve a cert in the cache for the given virtual host, or generates a new one if not present in the cache.

func (*Certs) LoadCAPair

func (c *Certs) LoadCAPair(keyFile, certFile string) error

LoadCAPair reads the certificate authority cert, and key from pem encoded files on disk.

func (*Certs) WriteCA

func (c *Certs) WriteCA(certFileName, keyFileName string) error

WriteCA writes the certificate authority key and cert as pem encoded files to disk.

type DNSServer

type DNSServer struct {
	ListenAddr       string `json:"listen_addr"`        // UDP address to listen for dns requests
	Port             int    `json:"port"`               // UDP Port to listen for dns requests
	ForwardDNSServer string `json:"forward_dns_server"` // Forward DNS server to query for each request
	DNSRegex         string `json:"dns_regex"`          // A record requests that match this pattern will return the proxy ip
	// contains filtered or unexported fields
}

DNSServer is a forwarding dns server, that can redirect arbitrary A record requests back to the MITMProxy listening address. DNSServer only returns requests for valid dns entries, any request that cannot be answered by the forward dns server is returned nxdomain.

Example
package main

import (
	"github.com/jmizell/GoMITMProxy/proxy"
	"log"
)

func main() {

	// DNS Server listening on TCP and UDP port 53, network address 127.0.0.1,
	// forwarding requests to 8.8.8.8, except in the case of A record requests
	// for example.com, which are rewritten to point to 127.0.0.1.
	dnsServer := &proxy.DNSServer{
		ListenAddr:       "127.0.0.1",
		Port:             53,
		ForwardDNSServer: "8.8.8.8",
		DNSRegex:         ".*example.com",
	}

	err := dnsServer.ListenAndServe()
	if err != nil {
		log.Fatal(err)
	}
}
Output:

func (*DNSServer) ListenAndServe

func (d *DNSServer) ListenAndServe() (err error)

ListenAndServe starts a forwarding DNS server on both the TCP and UDP network address ListenAddr.

func (*DNSServer) ServeDNS

func (d *DNSServer) ServeDNS(ctx context.Context, w dns.MessageWriter, r *dns.Query)

ServeDNS handles incoming dns requests, forwarding to an upstream server, and overwriting A record answers that match the pattern in DNSRegex.

type ErrorStr

type ErrorStr string

ErrorStr is a string representation of ProxyError, to be used as a constant

func (ErrorStr) Err

func (e ErrorStr) Err() *ProxyError

Err returns the ProxyError value of the string

type HTTPServer

type HTTPServer struct {
	ListenAddr string // TCP address for the server to listen on
	Port       int    // TCP Port of the server to listen on
	// contains filtered or unexported fields
}

HTTPServer handles incoming http requests for MITMProxy

func (*HTTPServer) GetPort

func (p *HTTPServer) GetPort() int

GetPort returns the Port that TLSServer will listen to. In the case that Port is a nil value, this value will change to a randomly selected Port after calling ListenAndServe

func (*HTTPServer) ListenAndServe

func (p *HTTPServer) ListenAndServe(ready chan bool, handler http.Handler) error

ListenAndServe creates the server process, and blocks until an error occurs. A ready channel is used to signal when the server has started listening.

func (*HTTPServer) Shutdown

func (p *HTTPServer) Shutdown() error

Shutdown calls Shutdown on the listening server with a background context

type MITMProxy

type MITMProxy struct {

	// LogResponses enabled logging the the response with the request.
	LogResponses bool `json:"log_responses"`

	// Certs is the store for the root CA, and all automatically generated host keys.
	// Uninitialized a new Certs struct will be created either from the certificate files
	// provided in CAKeyFile, and CACertFile, or if those are empty, new ones will be
	// generated and written to disk.
	Certs      *Certs `json:"-"`
	CAKeyFile  string `json:"ca_key_file"`  // File path to the CA key file
	CACertFile string `json:"ca_cert_file"` // File path to the CA certificate file

	ListenAddr string `json:"listen_addr"` // TCP address to listen on
	HTTPSPorts []int  `json:"https_ports"` // List of ports to start a tls server on
	HTTPPorts  []int  `json:"http_ports"`  // List of ports to start http server on

	ForwardDNSServer string `json:"forward_dns_server"` // Forward DNS server for the dns server to query
	DNSPort          int    `json:"dns_port"`           // Port to start listening for dns requests on, a zero value disables the server
	DNSRegex         string `json:"dns_regex"`          // A regex pattern representing the vhosts to redirect to the proxy

	DNSResolverOverride string `json:"dns_resolver_override"` // DNSServer overrides net.DefaultResolver with this dns server address.

	// ProxyTransport is the http.Handler that receives requests, and performs the round trip.
	// If this value is nil, then ReverseProxy is used.
	//
	// When a custom handler is set, logging will also need to be implemented, as LogResponses is not
	// passed to the custom handler.
	ProxyTransport http.Handler `json:"-"`
	// contains filtered or unexported fields
}

MITMProxy handles the creation of servers, and the transport of requests to their targets. A zero value is a no-op, a valid config that starts servers is minimally at least one Port specification in HTTPSPorts, or HTTPPorts.

Example
package main

import (
	"github.com/jmizell/GoMITMProxy/proxy"
	"log"
)

func main() {

	// This creates a MITM proxy listening on TCP ports 80 and 443 network address
	// 127.0.0.1, and a dns server on port 53 forwarding requests to 8.8.8.8,
	// redirecting requests for example.com to 127.0.0.1.
	//
	// When CAKeyFile and CACertFile are empty, and a proxy.Certs struct isn't
	// supplied, the proxy will generate the keys, and write them to the current
	// working directory
	p := &proxy.MITMProxy{
		ListenAddr:          "127.0.0.1",
		ForwardDNSServer:    "8.8.8.8",
		DNSResolverOverride: "8.8.8.8",
		DNSPort:             53,
		DNSRegex:            ".*example.com",
		HTTPSPorts:          []int{443},
		HTTPPorts:           []int{80},
	}

	// Run generates the CA, and starts listening for client connections
	if err := p.Run(); err != nil {
		log.Fatal(err)
	}
}
Output:

func NewProxyWithDefaults

func NewProxyWithDefaults() *MITMProxy

NewProxyWithDefaults returns a proxy with the default values used in gomitmproxy

func (*MITMProxy) Run

func (p *MITMProxy) Run() (err error)

Run creates the certificate store if not present, starts the dns server if configured, updates the net.DefaultResolver if ForwardDNSServer is set, and starts the tls and http servers. It blocks until the first server error is received, or the servers exit.

func (*MITMProxy) Shutdown

func (p *MITMProxy) Shutdown() (err error)

Shutdown signals all servers to exit, and waits for them to return, or errors after a 10 second timeout.

type ProxyError

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

ProxyError is the custom error type for the proxy package. A ProxyError contains a type string, and an error value describes the details of the specific error.

A ProxyError returned as a normal error, can be easily cast back to a ProxyError with UnmarshalError.

Types of ProxyErrors can be compared against each other using Match.

Example (CastProxyError)
package main

import (
	"fmt"
	"github.com/jmizell/GoMITMProxy/proxy"
)

func main() {

	// Create a proxy error constant. This is the immutable representation of our errors that
	// we can later compare against to check error types.
	const customProxyErr = proxy.ErrorStr("custom error")

	// Create a proxy error with a embedded go error.
	newProxyError := customProxyErr.Err().WithError(fmt.Errorf("go error"))

	// Use the proxy error as a go error.
	var goError error
	goError = newProxyError

	// Now cast our go error back to a proxy error.
	var receivingProxyError proxy.ProxyError
	if err := receivingProxyError.UnmarshalError(goError); err != nil {
		fmt.Printf("couldn't unmarshal go error to proxy.ProxyError, %s", err.Error())
		return
	}

	// Compare the proxy error against the constant to see if they are the same type.
	if receivingProxyError.Match(customProxyErr.Err()) {
		fmt.Println("receivingProxyError matches customProxyErr type")
	}

	// Retrieve the embedded go error from the proxy error.
	fmt.Printf("receivingProxyError has error %s\n", receivingProxyError.GetError())
}
Output:

Example (NestedErrors)
package main

import (
	"fmt"
	"github.com/jmizell/GoMITMProxy/proxy"
)

func main() {

	// Create a couple proxy error constants.
	const customProxyErr1 = proxy.ErrorStr("custom error one")
	const customProxyErr2 = proxy.ErrorStr("custom error two")

	// Create a new proxy error with a embedded proxy error.
	newProxyError := customProxyErr1.Err().WithError(customProxyErr2.Err())

	// Retrieve the embedded error and cast back to a proxy error.
	var embeddedProxyErr proxy.ProxyError
	if err := embeddedProxyErr.UnmarshalError(newProxyError.GetError()); err != nil {
		fmt.Printf("couldn't unmarshal go error to proxy.ProxyError, %s", err.Error())
		return
	}

	// Compare the embedded proxy error against the constant.
	if embeddedProxyErr.Match(customProxyErr2.Err()) {
		fmt.Println("receivingProxyError matches customProxyErr2 type")
	}
}
Output:

func NewError

func NewError(errType string) *ProxyError

NewError creates a ProxyError of the specified type

func (*ProxyError) Error

func (e *ProxyError) Error() string

ProxyError fulfills the golang error type. It returns the error type, and if present appends the go error.

func (*ProxyError) GetError

func (e *ProxyError) GetError() error

GetError returns the golang error value stored in ProxyError

func (*ProxyError) IsProxyError

func (e *ProxyError) IsProxyError(err error) bool

IsProxyError determines if the supplied error is a ProxyError

func (*ProxyError) Match

func (e *ProxyError) Match(err *ProxyError) bool

Match determines if the ProxyError have the same error type

func (*ProxyError) MustUnmarshalError

func (e *ProxyError) MustUnmarshalError(err error)

MustUnmarshalError casts an error value to a ProxyError, or panics on failure

func (*ProxyError) UnmarshalError

func (e *ProxyError) UnmarshalError(err error) error

UnmarshalError casts an error value to a ProxyError

func (*ProxyError) WithError

func (e *ProxyError) WithError(err error) *ProxyError

WithError adds a golang error to ProxyError. This is used to nest errors, or chains of errors in the ProxyError type

func (*ProxyError) WithReason

func (e *ProxyError) WithReason(format string, a ...interface{}) *ProxyError

WithReason creates a new golang error and adds it to ProxyError using the format string provided

type ReverseProxy

type ReverseProxy struct {

	// LogResponses enabled logging the the response with the request.
	LogResponses bool `json:"log_responses"`

	// Transport is the http transport used to perform proxy requests. If nil, http.DefaultTransport is used.
	Transport http.RoundTripper `json:"-"`
}

ReverseProxy is an http.Handler that that receives requests, performs the round trip, and handles logging.

func (*ReverseProxy) ServeHTTP

func (p *ReverseProxy) ServeHTTP(resp http.ResponseWriter, req *http.Request)

type Server

type Server interface {
	ListenAndServe(chan bool, http.Handler) error
	GetPort() int
	Shutdown() error
}

server represents a tls or http server to be used in MITMProxy

type TLSServer

type TLSServer struct {
	ListenAddr string // TCP address for the server to listen on
	Port       int    // TCP Port of the server to listen on
	Certs      *Certs // Certificate cache
	// contains filtered or unexported fields
}

TLSServer handles incoming https and http/2 requests for MITMProxy

func (*TLSServer) GetPort

func (p *TLSServer) GetPort() int

GetPort returns the Port that TLSServer will listen to. In the case that Port is a nil value, this value will change to a randomly selected Port after calling ListenAndServe

func (*TLSServer) ListenAndServe

func (p *TLSServer) ListenAndServe(ready chan bool, handler http.Handler) error

ListenAndServe creates the server process, and blocks until an error occurs. A ready channel is used to signal when the server has started listening.

func (*TLSServer) Shutdown

func (p *TLSServer) Shutdown() error

Shutdown calls Shutdown on the listening server with a background context

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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