diff --git a/README.md b/README.md index d4eba9f..a098c5c 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,8 @@ $ go get -v github.com/jpillora/chisel/chisel-forward ### Features * Easy to use -* Performant +* [Performant](#performance)* +* [Encrypted connections](https://github.com/jpillora/conncrypt) with `auth` derived (PBKDF2) symmetric key * Client auto-reconnects with [exponential backoff](https://github.com/jpillora/backoff) * Client can create multiple tunnel endpoints over one TCP connection * Server optionally doubles as a [reverse proxy](http://golang.org/pkg/net/http/httputil/#NewSingleHostReverseProxy) @@ -65,9 +66,6 @@ $ chiseld --help --port, Defines the HTTP listening port (defaults to 8080). You may also set the PORT environment variable. - --auth, Specifies the exact authentication string the client must - provide to attain access. You may also set the AUTH environment - variable. --proxy, Specifies the default proxy target to use when chiseld receives a normal HTTP request. @@ -189,6 +187,9 @@ Note, we're using an in-memory "file" server on localhost for these tests See more [test/](test/) + + + ### Known Issues * **WebSockets support is required** @@ -199,7 +200,6 @@ See more [test/](test/) * Openshift has full support though connections are only accepted on ports 8443 and 8080 * Google App Engine has **no** support - ### Contributing * http://golang.org/doc/code.html @@ -212,7 +212,6 @@ See more [test/](test/) * Users file with white-listed remotes * Pass in TLS server configuration -* Encrypt data with `auth` as the symmetric key * Expose a stats page for proxy throughput * Configurable connection retry times * Treat forwarder stdin/stdout as a socket diff --git a/chisel-forward/client/client.go b/chisel-forward/client/client.go index 7362b50..de49a07 100644 --- a/chisel-forward/client/client.go +++ b/chisel-forward/client/client.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/yamux" "github.com/jpillora/backoff" "github.com/jpillora/chisel" + "github.com/jpillora/conncrypt" "golang.org/x/net/websocket" ) @@ -130,7 +131,11 @@ func (c *Client) start() { continue } - conn := chisel.NewCryptoConn(c.auth, ws) + conn := net.Conn(ws) + + if c.auth != "" { + conn = conncrypt.New(conn, &conncrypt.Config{Password: c.auth}) + } //write config, read result chisel.SizeWrite(conn, c.encconfig) diff --git a/chisel-forward/main.go b/chisel-forward/main.go index 866e916..a01c60a 100644 --- a/chisel-forward/main.go +++ b/chisel-forward/main.go @@ -35,8 +35,8 @@ var help = ` Options: - --auth AUTH, Specifies the optional authentication string used by - the server. + --auth, Enables AES256 encryption and specifies the string to + use to derive the key. -v, Enable verbose logging diff --git a/chiseld/main.go b/chiseld/main.go index f8f809d..c05e74a 100644 --- a/chiseld/main.go +++ b/chiseld/main.go @@ -17,15 +17,12 @@ var help = ` Options: --host, Defines the HTTP listening host – the network interface - (defaults to 0.0.0.0). You may also set the HOST environment - variable. + (defaults to 0.0.0.0). - --port, Defines the HTTP listening port (defaults to 8080). You - may also set the PORT environment variable. + --port, Defines the HTTP listening port (defaults to 8080). - --auth, Specifies the exact authentication string the client must - provide to attain access. You may also set the AUTH environment - variable. + --auth, Enables AES256 encryption and specifies the string to + use to derive the key. --proxy, Specifies the default proxy target to use when chiseld receives a normal HTTP request. diff --git a/chiseld/server/server.go b/chiseld/server/server.go index 8af40b8..a51a627 100644 --- a/chiseld/server/server.go +++ b/chiseld/server/server.go @@ -1,11 +1,13 @@ package chiselserver import ( + "net" "net/http" "net/http/httputil" "net/url" "github.com/jpillora/chisel" + "github.com/jpillora/conncrypt" "golang.org/x/net/websocket" ) @@ -93,7 +95,11 @@ func (s *Server) handleHTTP(w http.ResponseWriter, r *http.Request) { func (s *Server) handleWS(ws *websocket.Conn) { - conn := chisel.NewCryptoConn(s.auth, ws) + conn := net.Conn(ws) + + if s.auth != "" { + conn = conncrypt.New(conn, &conncrypt.Config{Password: s.auth}) + } configb := chisel.SizeRead(conn) config, err := chisel.DecodeConfig(configb) diff --git a/crypto_conn.go b/crypto_conn.go deleted file mode 100644 index b96281e..0000000 --- a/crypto_conn.go +++ /dev/null @@ -1,48 +0,0 @@ -package chisel - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/sha1" - "io" - "net" - - "golang.org/x/crypto/pbkdf2" -) - -var salt = []byte("chisel-some-salt") - -func NewCryptoConn(password string, conn net.Conn) net.Conn { - - key := pbkdf2.Key([]byte(password), salt, 4096, 32, sha1.New) - - block, _ := aes.NewCipher([]byte(key)) - - var riv [aes.BlockSize]byte - rstream := cipher.NewOFB(block, riv[:]) - reader := &cipher.StreamReader{S: rstream, R: conn} - - var wiv [aes.BlockSize]byte - wstream := cipher.NewOFB(block, wiv[:]) - writer := &cipher.StreamWriter{S: wstream, W: conn} - - return &cryptoConn{ - Conn: conn, - reader: reader, - writer: writer, - } -} - -type cryptoConn struct { - net.Conn - reader io.Reader - writer io.Writer -} - -func (c *cryptoConn) Read(p []byte) (int, error) { - return c.reader.Read(p) -} - -func (c *cryptoConn) Write(p []byte) (int, error) { - return c.writer.Write(p) -} diff --git a/simple_protocol.go b/simple_protocol.go index 69a4571..939a272 100644 --- a/simple_protocol.go +++ b/simple_protocol.go @@ -7,6 +7,7 @@ import ( //simple protocol [2 bytes of size, size bytes of data] +//TODO add length and error checks func SizeRead(c net.Conn) []byte { sizeb := make([]byte, 2) c.Read(sizeb) diff --git a/test/chisel_test.go b/test/chisel_test.go index cd3796c..1b8743e 100644 --- a/test/chisel_test.go +++ b/test/chisel_test.go @@ -112,15 +112,15 @@ func TestMain(m *testing.M) { time.Sleep(100 * time.Millisecond) - hd := exec.Command("chiseld", "--port", "2002", "--auth", "foobar") + hd := exec.Command("chiseld", "--port", "2002" /*"--auth", "foobar",*/) + // hd.Stdout = os.Stdout if err := hd.Start(); err != nil { log.Fatal(err) } - hf := exec.Command("chisel-forward", - "--auth", "foobar", + hf := exec.Command("chisel-forward", /*"--auth", "foobar",*/ "127.0.0.1:2002", "2001:3000") - + // hf.Stdout = os.Stdout if err := hf.Start(); err != nil { log.Fatal(err) }