mitm

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2024 License: MIT Imports: 18 Imported by: 0

README

mitm - mitm is a SSL-capable man-in-the-middle proxy for use with golang net/http.

It is heavily inspired by the mitmproxy project (https://mitmproxy.org/).

Install

go get github.com/kr/mitm

Docs

http://godoc.org/github.com/kr/mitm

Contributors

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateCA

func GenerateCA(name string) (certPEM, keyPEM []byte, err error)

GenerateCA generates a CA cert and key pair.

func GenerateCert

func GenerateCert(ca *tls.Certificate, hosts ...string) (*tls.Certificate, error)

GenerateCert generates a leaf cert from ca.

func HTTPDirector

func HTTPDirector(r *http.Request)

HTTPDirector is director designed for use in Proxy for http proxies.

func HTTPSDirector

func HTTPSDirector(req *http.Request)

HTTPSDirector is a director designed for use in Proxy for transparent TLS proxies.

func NewListener

func NewListener(inner net.Listener, ca *tls.Certificate, conf *tls.Config) net.Listener

NewListener returns a net.Listener that generates a new cert from ca for each new Accept. It uses SNI to generate the cert, and herefore only works with clients that send SNI headers.

This is useful for building transparent MITM proxies.

func SkipNone

func SkipNone(req *http.Request) bool

SkipNone doesn't skip any request and proxy all of them.

Types

type Proxy

type Proxy struct {
	// Wrap specifies a function for optionally wrapping upstream for
	// inspecting the decrypted HTTP request and response.
	Wrap func(upstream http.Handler) http.Handler

	// CA specifies the root CA for generating leaf certs for each incoming
	// TLS request.
	CA *tls.Certificate

	// TLSServerConfig specifies the tls.Config to use when generating leaf
	// cert using CA.
	TLSServerConfig *tls.Config

	// TLSClientConfig specifies the tls.Config to use when establishing
	// an upstream connection for proxying.
	TLSClientConfig *tls.Config

	// FlushInterval specifies the flush interval
	// to flush to the client while copying the
	// response body.
	// If zero, no periodic flushing is done.
	FlushInterval time.Duration

	// Director is function which modifies the request into a new
	// request to be sent using Transport. See the documentation for
	// httputil.ReverseProxy for more details. For mitm proxies, the
	// director defaults to HTTPDirector, but for transparent TLS
	// proxies it should be set to HTTPSDirector.
	Director func(*http.Request)

	// SkipRequest is a function used to skip some requests from being
	// proxied. If it returns true, the request passes by without being
	// wrapped. If false, it's wrapped and proxied. By default we use
	// SkipNone, which doesn't skip any request
	SkipRequest func(*http.Request) bool

	// Transport is the low-level transport to perform proxy requests.
	// If nil, http.DefaultTransport is used.
	Transport http.RoundTripper

	// ForceUseCustomTransport if true, indicates that Transport will be used any way operating HTTPs connections
	// instead of (if false) using wrapping TLS dial. Useful when need to library used as HTTPs -> ? transport proxy
	ForceUseCustomTransport bool
}

Proxy is a forward proxy that substitutes its own certificate for incoming TLS connections in place of the upstream server's certificate.

Example
package main

import (
	"crypto/tls"
	"log"
	"net/http"
)

type codeRecorder struct {
	http.ResponseWriter

	code int
}

func (w *codeRecorder) WriteHeader(code int) {
	w.ResponseWriter.WriteHeader(code)
	w.code = code
}

func main() {
	ca, err := loadCA()
	if err != nil {
		log.Fatal(err)
	}

	p := &Proxy{
		CA: &ca,
		Wrap: func(upstream http.Handler) http.Handler {
			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				cr := &codeRecorder{ResponseWriter: w}
				log.Println("Got Content-Type:", r.Header.Get("Content-Type"))
				upstream.ServeHTTP(cr, r)
				log.Println("Got Status:", cr.code)
			})
		},
	}
	listenAndServe(p)
}

func loadCA() (cert tls.Certificate, err error) { panic("example only") }
func listenAndServe(_ http.Handler)             { panic("example only") }
Output:

func (*Proxy) ServeHTTP

func (p *Proxy) ServeHTTP(w http.ResponseWriter, req *http.Request)

type ServerConn

type ServerConn struct {
	*tls.Conn

	// ServerName is set during Conn's handshake to the client's requested
	// server name set in the SNI header. It is not safe to access across
	// multiple goroutines while Conn is performing the handshake.
	ServerName string
}

A ServerConn is a net.Conn that holds its clients SNI header in ServerName after the handshake.

func Server

func Server(cn net.Conn, p ServerParam) *ServerConn

Server wraps cn with a ServerConn configured with p so that during its Handshake, it will generate a new certificate using p.CA. After a successful Handshake, its ServerName field will be set to the clients requested ServerName in the SNI header.

type ServerParam

type ServerParam struct {
	CA        *tls.Certificate // the Root CA for generatng on the fly MITM certificates
	TLSConfig *tls.Config      // a template TLS config for the server.
}

ServerParam struct

Jump to

Keyboard shortcuts

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