Merge branch 'client-socks' of https://github.com/aus/chisel into red

This commit is contained in:
aus
2019-08-28 11:46:40 -05:00
5 changed files with 46 additions and 21 deletions
+26 -1
View File
@@ -11,6 +11,7 @@ import (
"strings"
"time"
"github.com/armon/go-socks5"
"github.com/gorilla/websocket"
"github.com/jpillora/backoff"
"github.com/aus/chisel/share"
@@ -42,6 +43,7 @@ type Client struct {
running bool
runningc chan error
connStats chshare.ConnStats
socksServer *socks5.Server
}
//NewClient creates a new client instance
@@ -68,11 +70,15 @@ func NewClient(config *Config) (*Client, error) {
//swap to websockets scheme
u.Scheme = strings.Replace(u.Scheme, "http", "ws", 1)
shared := &chshare.Config{}
createSocksServer := false
for _, s := range config.Remotes {
r, err := chshare.DecodeRemote(s)
if err != nil {
return nil, fmt.Errorf("Failed to decode remote '%s': %s", s, err)
}
if r.Socks && r.Reverse {
createSocksServer = true
}
shared.Remotes = append(shared.Remotes, r)
}
config.shared = shared
@@ -102,6 +108,14 @@ func NewClient(config *Config) (*Client, error) {
Timeout: 30 * time.Second,
}
if createSocksServer {
socksConfig := &socks5.Config{}
client.socksServer, err = socks5.New(socksConfig)
if err != nil {
return nil, err
}
}
return client, nil
}
@@ -272,6 +286,12 @@ func (c *Client) Close() error {
func (c *Client) connectStreams(chans <-chan ssh.NewChannel) {
for ch := range chans {
remote := string(ch.ExtraData())
socks := remote == "socks"
if socks && c.socksServer == nil {
c.Debugf("Denied socks request, please enable client socks remote.")
ch.Reject(ssh.Prohibited, "SOCKS5 is not enabled on the client")
continue
}
stream, reqs, err := ch.Accept()
if err != nil {
c.Debugf("Failed to accept stream: %s", err)
@@ -279,6 +299,11 @@ func (c *Client) connectStreams(chans <-chan ssh.NewChannel) {
}
go ssh.DiscardRequests(reqs)
l := c.Logger.Fork("conn#%d", c.connStats.New())
go chshare.HandleTCPStream(l, &c.connStats, stream, remote)
if socks {
go chshare.HandleSocksStream(l, c.socksServer, &c.connStats, stream)
} else {
go chshare.HandleTCPStream(l, &c.connStats, stream, remote)
}
}
}
+4
View File
@@ -224,6 +224,8 @@ var clientHelp = `
socks
5000:socks
R:2222:localhost:22
R:socks
R:5000:socks
When the chisel server has --socks5 enabled, remotes can
specify "socks" in place of remote-host and remote-port.
@@ -235,6 +237,8 @@ var clientHelp = `
be prefixed with R to denote that they are reversed. That
is, the server will listen and accept connections, and they
will be proxied through the client which specified the remote.
Reverse remotes specifying "R:socks" will terminate a connection
at the client's internal SOCKS5 proxy.
Options:
+1 -15
View File
@@ -2,7 +2,6 @@ package chserver
import (
"context"
"io"
"net/http"
"strings"
"sync/atomic"
@@ -179,22 +178,9 @@ func (s *Server) handleSSHChannels(clientLog *chshare.Logger, chans <-chan ssh.N
//handle stream type
connID := s.connStats.New()
if socks {
go s.handleSocksStream(clientLog.Fork("socksconn#%d", connID), stream)
go chshare.HandleSocksStream(clientLog.Fork("socksconn#%d", connID), s.socksServer, &s.connStats, stream)
} else {
go chshare.HandleTCPStream(clientLog.Fork("conn#%d", connID), &s.connStats, stream, remote)
}
}
}
func (s *Server) handleSocksStream(l *chshare.Logger, src io.ReadWriteCloser) {
conn := chshare.NewRWCConn(src)
s.connStats.Open()
l.Debugf("%s Opening", s.connStats)
err := s.socksServer.ServeConn(conn)
s.connStats.Close()
if err != nil && !strings.HasSuffix(err.Error(), "EOF") {
l.Debugf("%s: Closed (error: %s)", s.connStats, err)
} else {
l.Debugf("%s: Closed", s.connStats)
}
}
-5
View File
@@ -43,11 +43,6 @@ func DecodeRemote(s string) (*Remote, error) {
p := parts[i]
//last part "socks"?
if i == len(parts)-1 && p == "socks" {
if reverse {
// TODO allow reverse+socks by having client
// automatically start local SOCKS5 server
return nil, errors.New("'socks' incompatible with reverse port forwarding")
}
r.Socks = true
continue
}
+15
View File
@@ -12,6 +12,7 @@ import (
"net"
"strings"
"github.com/armon/go-socks5"
"github.com/jpillora/sizestr"
"golang.org/x/crypto/ssh"
)
@@ -56,3 +57,17 @@ func HandleTCPStream(l *Logger, connStats *ConnStats, src io.ReadWriteCloser, re
connStats.Close()
l.Debugf("%s: Close (sent %s received %s)", connStats, sizestr.ToString(s), sizestr.ToString(r))
}
func HandleSocksStream(l *Logger, server *socks5.Server, connStats *ConnStats, src io.ReadWriteCloser) {
conn := NewRWCConn(src)
connStats.Open()
l.Debugf("%s Opening", connStats)
err := server.ServeConn(conn)
connStats.Close()
if err != nil && !strings.HasSuffix(err.Error(), "EOF") {
l.Debugf("%s: Closed (error: %s)", connStats, err)
} else {
l.Debugf("%s: Closed", connStats)
}
}