All Projects → ChandraNarreddy → sillyproxy

ChandraNarreddy / sillyproxy

Licence: MIT license
SillyProxy - Dynamic SNI based TLS proxy for terminating TLS (>=1.1) HTTP connections to multiple domains.

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to sillyproxy

Gobetween
☁️ Modern & minimalistic load balancer for the Сloud era
Stars: ✭ 1,631 (+8484.21%)
Mutual labels:  tls, sni, tls-proxy
dtls
Datagram Transport Layer Security (DTLS) client.
Stars: ✭ 72 (+278.95%)
Mutual labels:  tls, ecdsa
gost
GO Simple Tunnel - a simple tunnel written in golang
Stars: ✭ 8,395 (+44084.21%)
Mutual labels:  tls, sni
ptw
Pooling TLS Wrapper
Stars: ✭ 20 (+5.26%)
Mutual labels:  tls, tls-proxy
mir
Mir is a toolkit for register method handler to http engine router(eg: gin,echo,iris,mux,httprouter) use struct tag info.
Stars: ✭ 42 (+121.05%)
Mutual labels:  httprouter, mux
sslcontext-kickstart
🔐 A lightweight high level library for configuring a http client or server based on SSLContext or other properties such as TrustManager, KeyManager or Trusted Certificates to communicate over SSL TLS for one way authentication or two way authentication provided by the SSLFactory. Support for Java, Scala and Kotlin based clients with examples. Av…
Stars: ✭ 295 (+1452.63%)
Mutual labels:  tls, keystore
Goproxy
🔥 Proxy is a high performance HTTP(S) proxies, SOCKS5 proxies,WEBSOCKET, TCP, UDP proxy server implemented by golang. Now, it supports chain-style proxies,nat forwarding in different lan,TCP/UDP port forwarding, SSH forwarding.Proxy是golang实现的高性能http,https,websocket,tcp,socks5代理服务器,支持内网穿透,链式代理,通讯加密,智能HTTP,SOCKS5代理,黑白名单,限速,限流量,限连接数,跨平台,KCP支持,认证API。
Stars: ✭ 11,334 (+59552.63%)
Mutual labels:  tls, tls-proxy
Httprouter
A high performance HTTP request router that scales well
Stars: ✭ 13,500 (+70952.63%)
Mutual labels:  httprouter, mux
docker-ssl-reverse-proxy
Easy-to-use auto-SSL reverse proxy as a Docker container based on Caddy and Let’s Encrypt
Stars: ✭ 22 (+15.79%)
Mutual labels:  tls, tls-proxy
steady-tun
Secure TLS tunnel with pool of prepared upstream connections
Stars: ✭ 37 (+94.74%)
Mutual labels:  tls, tls-proxy
Oscrypto
Compiler-free Python crypto library backed by the OS, supporting CPython and PyPy
Stars: ✭ 257 (+1252.63%)
Mutual labels:  tls, ecdsa
SSL-TLS-ECDSA-timing-attack
Timing Attack on TLS' ECDSA signature
Stars: ✭ 41 (+115.79%)
Mutual labels:  tls, ecdsa
Tlslite Ng
TLS implementation in pure python, focused on interoperability testing
Stars: ✭ 119 (+526.32%)
Mutual labels:  tls, ecdsa
go-fasthttp-sniproxy
SNI Proxy powered by fasthttp and golang to bypass DNS/SNI-based Internet filtering
Stars: ✭ 45 (+136.84%)
Mutual labels:  sni, server-name-indication
p3y
A single binary reverse proxy written in go. It was developed for use in Kubernetes, to wrap services like Prometheus with simple BasicAuth and TLS encryption.
Stars: ✭ 15 (-21.05%)
Mutual labels:  tls, tls-proxy
yubihsm-rs
Pure Rust client for YubiHSM2 devices
Stars: ✭ 70 (+268.42%)
Mutual labels:  ecdsa
rustls-native-certs
Integration with OS certificate stores for rustls
Stars: ✭ 123 (+547.37%)
Mutual labels:  tls
Swiddler
TCP/UDP debugging tool.
Stars: ✭ 56 (+194.74%)
Mutual labels:  tls
Lauschgeraet
Gets in the way of your victim's traffic and out of yours
Stars: ✭ 25 (+31.58%)
Mutual labels:  tls
ecdsa-kotlin
A simple, yet lightweight, fast elliptical curve cryptography library in kotlin.
Stars: ✭ 24 (+26.32%)
Mutual labels:  ecdsa

Build Status

SillyProxy

SillyProxy is an advanced SNI (Server Name Indication) respecting reverse proxy for terminating and proxying HTTPS connections to multiple domains.

  • SNI based TLS termination.
  • Supports both RSA and ECDSA certificates for each domain it serves.
  • Favors ECDSA over RSA if available by default. ECDSA is in orders of magnitude cheaper than RSA.
  • Has ability to hot-load SNI configuration. Currently it loads Hostname+Cert config from keystore every 30 mins.
  • Makes use of httprouter to proxy connections to backend.
  • Allows to define SNI and proxy routing configuration using a flexible JSON map.
  • Supports TLS versions 1.0, 1.1 and 1.2

Getting Started

You can build Silly for your platform using Go-1.8 or above.

go get https://github.com/ChandraNarreddy/sillyproxy

Once installed, Silly can be invoked by passing these parameters -

  • keystore - location of the keystore file. More on how to generate one below.
  • keypass - password to open the keystore file
  • minTLSVer - minimum version of TLS to support. Defaults to TLSv1.0
  • bind - address to bind on the host
  • routes - routemap for SillyProxy to follow
./sillyProxy -keypass changeme -keystore myKeyStore.ks -minTLSVer 1 -bind :8443 -routes myroutes.json

Generating the keystore

Silly reads certificates and keys from the keystore file. You can generate a keystore using the 'keystore' argument and following parameters -

  • keystore - location of the keystore file. If this keystore does not exist yet, a new one is created.
  • keypass - password to secure the keystore. Must match the previous password for an existing keystore
  • pemCert - location of the certificate file. PEM format only supported. Certificate types supported are RSA and ECDSA
  • pemKey - location of the corresponding private key file. PEM format only supported
  • hostname - SNI alias against which this certificate needs to get associated

A keystore can be used to store keys and certificates for multiple hostnames. Each host can have an ECDSA and an RSA certificate entry. Attempting to load a new certificate+pvtKey pair for an existing host+certType combination overwrites the existing entry. Please note that silly supports PEM format alone.

Default Alias

Please note that Silly needs atleast one cert+pvtkey entry (ECDSA or RSA type) associated using a "default" alias to run. This default entry will be used to serve clients that do not support SNI extension or those with an unknown Hostname in SNI extension. If there is a primary domain that you want to serve using Silly, the primary domain's certificate is best suited as "Default" entry. You are free to load the same certificate under the "Default" alias and under an actual alias too.

./sillyProxy -keystore myKeyStore.ks -pemCert certificatteFile -pemKey pvtKeyFile -keypass changeme -hostname myExternalDomainName KeyStore

Defining Routes

Silly requires routes in a JSON format. Routes are defined as JSON arrays and are composed of 'Host' to RoutePaths combinations. The 'Host' corresponds to the 'Host' header value of an incoming request. Please note that Silly cannot override an inbound request's method when it proxies a request. The Method and Path attributes act as filters to capture inbound requests.

Silly uses httprouter under the hood, it requires the path element to be defined using HTTPRouter's syntax.

The Route attribute needs an array composed of a combination of strings and numbers in the exact sequence that makes up the proxy path for inbound request. The numbers (indexed from 0) correspond to respective parameter values that Silly extracts based on the Path that you defined for the route. Silly does a plain concatenation in order as defined in the sequence and constructs the proxy path it needs to follow. Please note that Silly does a URL escape over parameters it extracts from the incoming request before composing the proxy path. String values defined in the Route attribute are not escaped.

{	
"Routes":[
	{
	 "Host":"www.MyPrimaryDomain.com",
         "MethodPathMaps": 
			[
	                 {
                          "Method": "GET",
                          "Path"  : "/wildRoute/:internalDomain/*end",
                          "Route" : [ "https://www.",0,"/.com/", 1 ]
	                 },
	                 {   
                          "Method": "GET",
	                  "Path"  : "/search/*query",
	                  "Route" : ["https://internalSearchAPI/search?q=", 0]
	                 },
                         {
	                  "Method": "POST",
	                  "Path"  : "/authenticate/",
	                  "Route" : ["https://kerberos.mydomain.com/login/"]
	                 },
	                ]
	},
	{
	"Host":"www.MySecondDomain.com",
	"MethodPathMaps":
			[
			 {
			  "Method": "POST",
			  "Path"  : "/API/:category/:item",
			  "Route" : ["http://internalRestEndpoint/",1]
			 }
			]
	}
	 ]
}

Benchmarks

Target platform:

  • GCE n1-standard-1 (1 vCPU, 3.75 GB memory) running ubuntu-1710-artful-v20180126
  • Linux instance-2 4.13.0-32-generic #35-Ubuntu SMP Thu Jan 25 09:13:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • GO version go1.9.1 linux/amd64

To minimize network induced variations, I used:

  • A backend HTTP server implementation (using GO 1.9.1) serving a minimum payload on the target machine.
  • Go-WRK run from the target machine.
  • Silly was configured with RSA and ECDSA entries for connections to the localhost.

SillyProxy Curve P-256 ECDSA performance

40 connections 2 threads
./go-wrk -c=40 -t=2 -n=10000 -m="GET" -i=true https://127.0.0.1:8443/p
ath2/path3/hello
==========================BENCHMARK==========================
URL:                            https://127.0.0.1:8443/path2/path3/hello

Used Connections:               40
Used Threads:                   2
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              15.67s
Avg time per request:           62.41ms
Requests per second:            638.18
Median time per request:        61.97ms
99th percentile time:           102.92ms
Slowest time for request:       145.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               3190.90 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)
100 connections 5 threads
./go-wrk -c=100 -t=5 -n=10000 -m="GET" -i=true https://127.0.0.1:8443/
path2/path3/hello
==========================BENCHMARK==========================
URL:                            https://127.0.0.1:8443/path2/path3/hello

Used Connections:               100
Used Threads:                   5
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              17.52s
Avg time per request:           173.35ms
Requests per second:            570.93
Median time per request:        171.43ms
99th percentile time:           272.22ms
Slowest time for request:       331.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               2854.67 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)

SillyProxy RSA-2048 performance

40 connections 2 threads
./go-wrk -c=40 -t=2 -n=10000 -m="GET" -i=true https://127.0.0.1:8443/p
ath2/path3/hello
==========================BENCHMARK==========================
URL:                            https://127.0.0.1:8443/path2/path3/hello

Used Connections:               40
Used Threads:                   2
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              50.51s
Avg time per request:           201.27ms
Requests per second:            197.99
Median time per request:        196.90ms
99th percentile time:           363.46ms
Slowest time for request:       489.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               989.96 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)
100 connections 5 threads
./go-wrk -c=100 -t=5 -n=10000 -m="GET" -i=true https://127.0.0.1:8443/
path2/path3/hello
==========================BENCHMARK==========================
URL:                            https://127.0.0.1:8443/path2/path3/hello

Used Connections:               100
Used Threads:                   5
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              51.28s
Avg time per request:           508.29ms
Requests per second:            194.99
Median time per request:        507.46ms
99th percentile time:           803.28ms
Slowest time for request:       961.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               974.97 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)

Understandably, RSA numbers pale in comparison to those of ECDSA.

Comparing with NGINX

For the inquisitive lot, below are NGINX' numbers under same settings. I used the same certificate entries and the same backend server, just replaced SillyProxy with NGINX.

nginx version: nginx/1.12.1 (Ubuntu) built with OpenSSL 1.0.2g 1 Mar 2016 TLS SNI support enabled

NGINX Curve P-256 ECDSA performance

40 connections 2 threads
./go-wrk -c=40 -t=2 -n=10000 -m="GET" -i=true https://127.0.0.1:443/pa
th2/path3/hello
==========================BENCHMARK==========================
URL:                            https://127.0.0.1:443/path2/path3/hello

Used Connections:               40
Used Threads:                   2
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              14.59s
Avg time per request:           58.11ms
Requests per second:            685.34
Median time per request:        57.03ms
99th percentile time:           100.47ms
Slowest time for request:       168.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               3426.69 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)
100 connections 5 threads
./go-wrk -c=100 -t=5 -n=10000 -m="GET" -i=true https://127.0.0.1:443/p
ath2/path3/hello
==========================BENCHMARK==========================
URL:                            https://127.0.0.1:443/path2/path3/hello

Used Connections:               100
Used Threads:                   5
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              15.73s
Avg time per request:           154.07ms
Requests per second:            635.86
Median time per request:        144.82ms
99th percentile time:           363.58ms
Slowest time for request:       538.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               3179.30 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)

NGINX RSA-2048 performance

40 connections 2 threads
/go-wrk -c=40 -t=2 -n=10000 -m="GET" -i=true https://localhost:443/pa
th2/path3/hello
==========================BENCHMARK==========================
URL:                            https://localhost:443/path2/path3/hello

Used Connections:               40
Used Threads:                   2
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              27.21s
Avg time per request:           108.25ms
Requests per second:            367.58
Median time per request:        101.13ms
99th percentile time:           156.77ms
Slowest time for request:       172.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               1837.89 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)
100 connections 5 threads
/go-wrk -c=100 -t=5 -n=10000 -m="GET" -i=true https://localhost:443/p
ath2/path3/hello
==========================BENCHMARK==========================
URL:                            https://localhost:443/path2/path3/hello

Used Connections:               100
Used Threads:                   5
Total number of calls:          10000

===========================TIMINGS===========================
Total time passed:              26.90s
Avg time per request:           265.14ms
Requests per second:            371.77
Median time per request:        261.31ms
99th percentile time:           388.29ms
Slowest time for request:       426.00ms

=============================DATA=============================
Total response body sizes:              50000
Avg response body per request:          5.00 Byte
Transfer rate per second:               1858.86 Byte/s (0.00 MByte/s)
==========================RESPONSES==========================
20X Responses:          10000   (100.00%)
30X Responses:          0       (0.00%)
40X Responses:          0       (0.00%)
50X Responses:          0       (0.00%)
Errors:                 0       (0.00%)

Benchmarks Summary

Silly's ECDSA performance is comparable to that of NGINX' whereas Silly's RSA performance compared to NGINX' is abysmal; this is expected as GO's Crypto library is not optimized for RSA. Ideally, you should use RSA certificate only as a fallback to serve clients that do not support ECDSA Signature Algorithm. Most modern browsers support ECDSA, so Silly's lacklustre RSA number should cause minimal concern.

Contributing

Please submit issues for suggestions. Pull requests are welcome too.

Author

  • Chandrakanth Narreddy

License

MIT License

Acknowledgments

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].