sniproxy

command module
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2023 License: Apache-2.0 Imports: 1 Imported by: 0

README

sniproxy

Proxies incoming HTTP and TLS connections based on the hostname that is parsed from either HTTP Host header (for plain HTTP connections) or TLS ClientHello.

This allows transparent proxying of the network traffic by simply rerouting connections to the sniproxy. There are many ways to re-route traffic, but most often it is done either on the DNS level or by using iptables.

Features

  • Embedded DNS server that can be used to redirect traffic to the proxy.
  • Supports both TLS and plain HTTP.
  • Supports forwarding connections to an upstream SOCKS proxy.
  • Flexible rules for redirecting, forwarding, blocking or throttling connections.
  • Cross-platform and simple.

How to install

  • Using homebrew:
    brew install ameshkov/tap/sniproxy
    
  • From source:
    go install github.com/ameshkov/sniproxy
    
  • You can get a binary for your platform from the releases page.

Using sniproxy

Redirect all traffic to a SNI proxy
  • Run sniproxy and rewrite DNS responses to point to 1.2.3.4:

    sudo sniproxy --dns-redirect-ipv4-to=1.2.3.4
    
  • You can test locally it with the following commands:

    curl "https://example.org/" --dns-servers 127.0.0.1
    curl "http://example.org/" --dns-servers 127.0.0.1
    

    Not every curl version supports --dns-servers. Alternatively, use these commands:

    curl "https://example.org/" --connect-to example.org:443:127.0.0.1:443
    curl "http://example.org/" --connect-to example.org:80:127.0.0.1:80
    
  • Now you should just point your device to the DNS server that is running on your computer.

Forward all traffic to a proxy

Run sniproxy, rewrite DNS responses to point to 1.2.3.4, :

sudo sniproxy \
    --dns-redirect-ipv4-to=1.2.3.4 \
    --forward-proxy="socks5://127.0.0.1:1080"

Now every connection will be re-routed to the SOCKS5 proxy on 127.0.0.1:1080.

You can choose which domains are re-routed. For instance, here only example. org and example.com will be re-routed through the SOCKS5 proxy:

sudo sniproxy \
    --dns-redirect-ipv4-to=1.2.3.4 \
    --forward-proxy="socks5://127.0.0.1:1080" \
    --forward-rule=example.org \
    --forward-rule=example.com

It also supports HTTP and HTTPS proxies. Here's an example:

sudo sniproxy \
    --dns-redirect-ipv4-to=1.2.3.4 \
    --forward-proxy="http://127.0.0.1:8080" \
    --forward-rule=example.org \
    --forward-rule=example.com
Block domains

You may want to block access to some domains. There are two options of how it can be done: --block-rule or --drop-rule. If the connection matches a --block-rule, the connection will be closed immediately. If the connection matches a --drop-rule, the connection will "hang" for a hard-coded limit of 3 minutes before it will be closed.

Here's how block or drop connections to domains:

sudo sniproxy \
    --dns-redirect-ipv4-to=1.2.3.4 \
    --block-rule=example.org \
    --block-rule=example.com \
    --drop-rule=example.net
Throttle connections

If you need to emulate slow network, use bandwidth-rate to set the desired bytes-per-sec rate.

sudo sniproxy \
    --dns-redirect-ipv4-to=1.2.3.4 \
    --bandwidth-rate=1000

You can also throttle connections to individual domains using bandwidth-rule.

sudo sniproxy \
    --dns-redirect-ipv4-to=1.2.3.4 \
    --bandwidth-rule="example.*:5000"
Command-line arguments
Usage:
  sniproxy [OPTIONS]

Application Options:
      --dns-address=          IP address that the DNS proxy server will be
                              listening to. (default: 0.0.0.0)
      --dns-port=             Port the DNS proxy server will be listening to.
                              (default: 53)
      --dns-upstream=         The address of the DNS server the proxy will
                              forward queries that are not rewritten by
                              sniproxy. (default: 8.8.8.8)
      --dns-redirect-ipv4-to= IPv4 address that will be used for redirecting
                              type A DNS queries.
      --dns-redirect-ipv6-to= IPv6 address that will be used for redirecting
                              type AAAA DNS queries.
      --dns-redirect-rule=    Wildcard that defines which domains should be
                              redirected to the SNI proxy. Can be specified
                              multiple times. (default: *)
      --http-address=         IP address the SNI proxy server will be listening
                              for plain HTTP connections. (default: 0.0.0.0)
      --http-port=            Port the SNI proxy server will be listening for
                              plain HTTP connections. (default: 80)
      --tls-address=          IP address the SNI proxy server will be listening
                              for TLS connections. (default: 0.0.0.0)
      --tls-port=             Port the SNI proxy server will be listening for
                              TLS connections. (default: 443)
      --bandwidth-rate=       Bytes per second the connections speed will be
                              limited to. If not set, there is no limit.
                              (default: 0)
      --bandwidth-rule=       Allows to define connection speed in bytes/sec
                              for domains that match the wildcard. Example:
                              example.*:1024. Can be specified multiple times.
      --forward-proxy=        Address of a SOCKS/HTTP/HTTPS proxy that the
                              connections will be forwarded to according to
                              forward-rule.
      --forward-rule=         Wildcard that defines what connections will be
                              forwarded to forward-proxy. Can be specified
                              multiple times. If no rules are specified, all
                              connections will be forwarded to the proxy.
      --block-rule=           Wildcard that defines connections to which
                              domains should be blocked. Can be specified
                              multiple times.
      --drop-rule=            Wildcard that defines connections to which
                              domains should be dropped (i.e. delayed for a
                              hard-coded period of 3 minutes. Can be specified
                              multiple times.
      --verbose               Verbose output (optional)
      --output=               Path to the log file. If not set, write to stdout.

Help Options:
  -h, --help                  Show this help message

Debugging locally

If you want to contribute to sniproxy, here are some tips on how to debug it locally.

First, you rarely want to run with sudo and instead you'd prefer to use high ports. sniproxy provides command-line arguments for that.

./sniproxy \
    --dns-address=127.0.0.1 \
    --dns-port=5354 \
    --dns-upstream=8.8.8.8 \
    --dns-redirect-ipv4-to=127.0.0.1 \
    --dns-redirect-rule=example.org \
    --dns-redirect-rule=example.com \
    --tls-address=127.0.0.1 \
    --tls-port=8443 \
    --http-address=127.0.0.1 \
    --http-port=8080 \
    --forward-proxy="socks5://127.0.0.1:1080" \
    --verbose

It is easy to use curl to debug sniproxy:

# HTTPS request
curl "https://example.org/" --connect-to example.org:443:127.0.0.1:8443

# Plain HTTP request
curl "http://example.org/" --connect-to example.org:80:127.0.0.1:8080

Use mitmproxy to debug sniproxy with forwarding rules:

# Run mitmproxy in SOCKS mode
mitmweb --mode=socks5

# Forward connections to mitmproxy
./sniproxy \
    --dns-address=127.0.0.1 \
    --dns-port=5354 \
    --dns-upstream=8.8.8.8 \
    --dns-redirect-ipv4-to=127.0.0.1 \
    --dns-redirect-rule=example.org \
    --dns-redirect-rule=example.com \
    --tls-address=127.0.0.1 \
    --tls-port=8443 \
    --http-address=127.0.0.1 \
    --http-port=8080 \
    --forward-proxy="socks5://127.0.0.1:1080" \
    --verbose

# Check that the connections were properly forwarded
curl "https://example.org/" --connect-to example.org:443:127.0.0.1:8443 --insecure
curl "http://example.org/" --connect-to example.org:80:127.0.0.1:8080

Documentation

Overview

Package main is responsible for the main func of sniproxy. The actual work is done in the cmd package.

Directories

Path Synopsis
internal
cmd
Package cmd is responsible for the program's command-line interface.
Package cmd is responsible for the program's command-line interface.
dnsproxy
Package dnsproxy is responsible for the DNS proxy server that will redirect specified domains to the SNI proxy.
Package dnsproxy is responsible for the DNS proxy server that will redirect specified domains to the SNI proxy.
httpupstream
Package httpupstream extends proxy with HTTP and HTTPS proxies support.
Package httpupstream extends proxy with HTTP and HTTPS proxies support.
shapeio
Package shapeio provides connections throttling functionality.
Package shapeio provides connections throttling functionality.
sniproxy
Package sniproxy is responsible for the SNI and plain HTTP proxy that will listen for incoming TLS/HTTP connections, read the server name either from the SNI field of ClientHello or from the HTTP Host header, and tunnel traffic to the respective hosts.
Package sniproxy is responsible for the SNI and plain HTTP proxy that will listen for incoming TLS/HTTP connections, read the server name either from the SNI field of ClientHello or from the HTTP Host header, and tunnel traffic to the respective hosts.
version
Package version contains version-specific metadata that is set when sniproxy is built.
Package version contains version-specific metadata that is set when sniproxy is built.

Jump to

Keyboard shortcuts

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