All Projects → AdguardTeam → gomitmproxy

AdguardTeam / gomitmproxy

Licence: GPL-3.0 license
Simple golang mitm proxy implementation

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to gomitmproxy

C-Sharp-Proxy-Server
A proxy server built with c# can be both normal and MITM Proxy
Stars: ✭ 86 (+22.86%)
Mutual labels:  proxy-server, mitmproxy
mps
MPS is a high-performance HTTP(S) proxy library that supports forward proxies, reverse proxies, man-in-the-middle proxies, tunnel proxies, Websocket proxies. MPS 是一个高性能HTTP(s)中间代理库,它支持正向代理、反向代理、中间人代理、隧道代理、Websocket代理
Stars: ✭ 64 (-8.57%)
Mutual labels:  proxy-server, mitmproxy
proxy pool
A simple proxy pool
Stars: ✭ 73 (+4.29%)
Mutual labels:  proxy-server
docker-django-nginx-uwsgi-postgres-load-balance-tutorial
實戰 Docker + Django + Nginx + uWSGI + Postgres - Load Balance -Tutorial 📝
Stars: ✭ 102 (+45.71%)
Mutual labels:  proxy-server
json-caching-proxy
Node caching HTTP proxy built on top of express-http-proxy. Persists requests and responses to an in-memory HAR-like data structure based on HAR1.2 . Caches JSON content-type responses by default with the ability to cache an entire site; including content-types describing images. Useful for testing front end code, mocking api, and saving the cac…
Stars: ✭ 31 (-55.71%)
Mutual labels:  proxy-server
prom-authzed-proxy
A Prometheus proxy that performs SpiceDB permission checks based on labels
Stars: ✭ 30 (-57.14%)
Mutual labels:  proxy-server
asyncio-socks-server
A SOCKS proxy server implemented with the powerful python cooperative concurrency framework asyncio.
Stars: ✭ 154 (+120%)
Mutual labels:  proxy-server
proxy
An HTTP proxy server written in C# and targeting .NET Core 3.
Stars: ✭ 31 (-55.71%)
Mutual labels:  proxy-server
caddy-scratch
Caddy server 2.0.0 / 1.0.5 on Docker Scratch, all in 18MB / 35MB
Stars: ✭ 32 (-54.29%)
Mutual labels:  proxy-server
torchestrator
Spin up Tor containers and then proxy HTTP requests via these Tor instances
Stars: ✭ 32 (-54.29%)
Mutual labels:  proxy-server
squid proxy pool
Squid 代理池搭建
Stars: ✭ 88 (+25.71%)
Mutual labels:  proxy-server
docker-openvpn-client
OpenVPN client with killswitch and proxy servers; built on Alpine
Stars: ✭ 217 (+210%)
Mutual labels:  proxy-server
bproxy
high-performance minimal HTTP reverse proxy
Stars: ✭ 28 (-60%)
Mutual labels:  proxy-server
PassivesScan
《被动扫描资源汇总》
Stars: ✭ 27 (-61.43%)
Mutual labels:  mitmproxy
vcr.js
Mock server with Proxy and Record support inspired by ruby VCR.
Stars: ✭ 41 (-41.43%)
Mutual labels:  proxy-server
PoW-Shield
Project dedicated to fight Layer 7 DDoS with proof of work, featuring an additional WAF. Completed with full set of features and containerized for rapid and lightweight deployment.
Stars: ✭ 99 (+41.43%)
Mutual labels:  proxy-server
thumbai
Go Mod Repository, Go Vanity Server and Proxy Server
Stars: ✭ 84 (+20%)
Mutual labels:  proxy-server
SpoofDPI
A simple and fast anti-censorship tool written in Go
Stars: ✭ 170 (+142.86%)
Mutual labels:  proxy-server
reproxy
Simple edge server / reverse proxy
Stars: ✭ 994 (+1320%)
Mutual labels:  proxy-server
jmitm
Java版本的mitmproxy,对本地浏览器所有的Http(s)请求和响应进行拦截并「重制」;也可充当轻量级B/S版抓包软件;
Stars: ✭ 19 (-72.86%)
Mutual labels:  mitmproxy

Code Coverage Go Report Card GolangCI Go Doc

gomitmproxy

This is a customizable HTTP proxy with TLS interception support. It was created as a part of AdGuard Home. However, it can be used for different purposes so we decided to make it a separate project.

Features

  • HTTP proxy
  • HTTP over TLS (HTTPS) proxy
  • Proxy authorization
  • TLS termination

How to use gomitmproxy

Simple HTTP proxy

package main

import (
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"

	"github.com/AdguardTeam/gomitmproxy"
)

func main() {
	proxy := gomitmproxy.NewProxy(gomitmproxy.Config{
		ListenAddr: &net.TCPAddr{
			IP:   net.IPv4(0, 0, 0, 0),
			Port: 8080,
		},
	})
	err := proxy.Start()
	if err != nil {
		log.Fatal(err)
	}

	signalChannel := make(chan os.Signal, 1)
	signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM)
	<-signalChannel

	// Clean up
	proxy.Close()
}

Modifying requests and responses

You can modify requests and responses using OnRequest and OnResponse handlers.

The example below will block requests to example.net and add a short comment to the end of every HTML response.

proxy := gomitmproxy.NewProxy(gomitmproxy.Config{
    ListenAddr: &net.TCPAddr{
        IP:   net.IPv4(0, 0, 0, 0),
        Port: 8080,
    },
    OnRequest: func(session *gomitmproxy.Session) (request *http.Request, response *http.Response) {
        req := session.Request()

        log.Printf("onRequest: %s %s", req.Method, req.URL.String())

        if req.URL.Host == "example.net" {
            body := strings.NewReader("<html><body><h1>Replaced response</h1></body></html>")
            res := proxyutil.NewResponse(http.StatusOK, body, req)
            res.Header.Set("Content-Type", "text/html")

            // Use session props to pass the information about request being blocked
            session.SetProp("blocked", true)
            return nil, res
        }

        return nil, nil
    },
    OnResponse: func(session *gomitmproxy.Session) *http.Response {
        log.Printf("onResponse: %s", session.Request().URL.String())

        if _, ok := session.GetProp("blocked"); ok {
            log.Printf("onResponse: was blocked")
        }

        res := session.Response()
        req := session.Request()
    
        if strings.Index(res.Header.Get("Content-Type"), "text/html") != 0 {
            // Do nothing with non-HTML responses
            return nil
        }
    
        b, err := proxyutil.ReadDecompressedBody(res)
        // Close the original body
        _ = res.Body.Close()
        if err != nil {
            return proxyutil.NewErrorResponse(req, err)
        }
    
        // Use latin1 before modifying the body
        // Using this 1-byte encoding will let us preserve all original characters
        // regardless of what exactly is the encoding
        body, err := proxyutil.DecodeLatin1(bytes.NewReader(b))
        if err != nil {
            return proxyutil.NewErrorResponse(session.Request(), err)
        }
    
        // Modifying the original body
        modifiedBody, err := proxyutil.EncodeLatin1(body + "<!-- EDITED -->")
        if err != nil {
            return proxyutil.NewErrorResponse(session.Request(), err)
        }
    
        res.Body = ioutil.NopCloser(bytes.NewReader(modifiedBody))
        res.Header.Del("Content-Encoding")
        res.ContentLength = int64(len(modifiedBody))
        return res
    },
})

Proxy authorization

If you want to protect your proxy with Basic authentication, set Username and Password fields in the proxy configuration.

proxy := gomitmproxy.NewProxy(gomitmproxy.Config{
    ListenAddr: &net.TCPAddr{
        IP:   net.IPv4(0, 0, 0, 0),
        Port: 8080,
    },
    Username: "user",
    Password: "pass",
})

HTTP over TLS (HTTPS) proxy

If you want to protect yourself from eavesdropping on your traffic to proxy, you can configure it to work over a TLS tunnel. This is really simple to do, just set a *tls.Config instance in your proxy configuration.

tlsConfig := &tls.Config{
    Certificates: []tls.Certificate{*proxyCert},
}
proxy := gomitmproxy.NewProxy(gomitmproxy.Config{
    ListenAddr: addr,
    TLSConfig:  tlsConfig,
})

TLS interception

If you want to do TLS termination, you first need to prepare a self-signed certificate that will be used as a certificates authority. Use the following openssl commands to do this.

openssl genrsa -out demo.key 2048
openssl req -new -x509 -key demo.key -out demo.crt

Now you can use it to initialize MITMConfig:

tlsCert, err := tls.LoadX509KeyPair("demo.crt", "demo.key")
if err != nil {
    log.Fatal(err)
}
privateKey := tlsCert.PrivateKey.(*rsa.PrivateKey)

x509c, err := x509.ParseCertificate(tlsCert.Certificate[0])
if err != nil {
    log.Fatal(err)
}

mitmConfig, err := mitm.NewConfig(x509c, privateKey, nil)
if err != nil {
    log.Fatal(err)
}

mitmConfig.SetValidity(time.Hour * 24 * 7) // generate certs valid for 7 days
mitmConfig.SetOrganization("gomitmproxy")  // cert organization

Please note that you can set MITMExceptions to a list of hostnames, which will be excluded from TLS interception.

proxy := gomitmproxy.NewProxy(gomitmproxy.Config{
    ListenAddr: &net.TCPAddr{
        IP:   net.IPv4(0, 0, 0, 0),
        Port: 3333,
    },
    MITMConfig:     mitmConfig,
    MITMExceptions: []string{"example.com"},
})

If you configure the APIHost, you'll be able to download the CA certificate from http://[APIHost]/cert.crt when the proxy is configured.

// Navigate to http://gomitmproxy/cert.crt to download the CA certificate
proxy.APIHost = "gomitmproxy"

Custom certs storage

By default, gomitmproxy uses an in-memory map-based storage for the certificates, generated while doing TLS interception. It is often necessary to use a different kind of certificates storage. If this is your case, you can supply your own implementation of the CertsStorage interface.

// CustomCertsStorage - an example of a custom cert storage
type CustomCertsStorage struct {
	certsCache map[string]*tls.Certificate // cache with the generated certificates
}

// Get gets the certificate from the storage
func (c *CustomCertsStorage) Get(key string) (*tls.Certificate, bool) {
	v, ok := c.certsCache[key]
	return v, ok
}

// Set saves the certificate to the storage
func (c *CustomCertsStorage) Set(key string, cert *tls.Certificate) {
	c.certsCache[key] = cert
}

Then pass it to the NewConfig function.

mitmConfig, err := mitm.NewConfig(x509c, privateKey, &CustomCertsStorage{
    certsCache: map[string]*tls.Certificate{}},
)

Notable alternatives

  • martian - an awesome debugging proxy with TLS interception support.
  • goproxy - also supports TLS interception and requests.

TODO

  • Basic HTTP proxy without MITM
  • Proxy
    • Expose APIs for the library users
    • How-to doc
    • Travis configuration
    • Proxy-Authorization
    • WebSockets support (see this)
    • certsCache -- allow custom implementations
    • Support HTTP CONNECT over TLS
    • Test plain HTTP requests inside HTTP CONNECT
    • Test memory leaks
    • Editing response body in a callback
    • Handle unknown content-encoding values
    • Handle CONNECT to APIHost properly (without trying to actually connect anywhere)
    • Allow hijacking connections (!)
    • Multiple listeners
    • Unit tests
    • Check & fix TODOs
    • Allow specifying net.Dialer
    • Specify timeouts for http.Transport
  • MITM
    • Basic MITM
    • MITM exceptions
    • Handle invalid server certificates properly (not just reset connections)
    • Pass the most important tests on badssl.com/dashboard
    • Handle certificate authentication
    • Allow configuring minimum supported TLS version
    • OCSP check (see example)
    • (?) HPKP (see example)
    • (?) CT logs (see example)
    • (?) CRLSets (see example)
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].