SNIProxy is a TLS proxy which, based on the TLS SNI contained in TLS handshakes, routes TCP connections to backends. The proxy does not need the TLS encryption keys and can not decrypt the TLS traffic.
SNIProxy is meant to be simple to use and configure, with sane defaults and few parameters.
$ docker run --name sniproxy -p 443:443/tcp \
-v $(pwd)/sniproxy.conf:/sniproxy.conf \
atenart/sniproxy:latest -conf sniproxy.conf
SNIProxy can be bound to a custom address or port using the -bind
command
line option.
$ docker run --name sniproxy -p 443:443/tcp \
-v $(pwd)/sniproxy.conf:/sniproxy.conf \
atenart/sniproxy:latest -bind 192.168.0.1:8080 -conf sniproxy.conf
The configuration is made of a list of blocks. Each block represents a route. A route is defined by a list of hostnames, a backend to route the connection to and optional parameters:
hostname0, hostname1, … {
backend <IP/hostname>:port
parameter0
parameter1 arg0, arg1, …
…
}
A route can be as simple as:
example.net {
backend 1.2.3.4:8080
}
Hostnames can contain regexp:
# Matches example.net and all its subdomains.
example.net, *.example.net {
backend localhost:1234
}
HAProxy's PROXY protocol v1 and v2 are supported.
example.net {
backend 1.2.3.4:443
# Send a PROXY header using the PROXY protocol v1.
send-proxy
}
blog.example.net {
backend 1.2.3.5:443
# Send a PROXY header using the PROXY protocol v2.
send-proxy-v2
}
SNIProxy also has the ability to block or allow connections based on the client IP address. Single IPs or subnets (using a CIDR range) are supported.
# Deny a single client. All other connections will be routed to the backend.
example.net {
backend 1.2.3.4:443
deny 10.0.0.42
}
# Lists can be used as well, either using commas (,) or using multiple
# statements.
example.net {
backend 1.2.3.4:443
deny 10.0.0.42, 10.0.0.43, 10.0.0.44
deny 10.0.0.45
}
# When at least one IP is allowed, all IPs are denied automatically (0.0.0.0/0
# and ::/0).
example.net {
backend 1.2.3.4:443
# 192.168.0.42 is allowed, all other IPs are denied.
allow 192.168.0.42
}
# Example with ranges.
example.net {
backend 1.2.3.4:443
deny 192.168.0.0/24
}
# The most specific range wins (if the range is the same, deny wins).
example.net {
backend 1.2.3.4:443
# Deny 192.168.0.0/22 except for 192.168.0.2 and 192.168.1.8/29.
deny 192.168.0.0/22
allow 192.168.1.8/29, 192.168.0.2
}