Skip to content

Commit 187fea3

Browse files
OS-kiranmalsettyip-rwdependabot[bot]Rajpratik71jpillora
authored
Upstream sync (#14)
* Set ServerName (SNI) to *hostname. Useful for spoofing our way through restrictive gateways. * Bump actions/checkout from 2 to 3.1.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v2...v3.1.0) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> * Added --sni switch to control the ServerName when connecting with TLS. Makes 'domain fronting' possible. * feat: dependabot workflow automation for updating dependency Signed-off-by: Pratik Raj <[email protected]> * Bump github.com/fsnotify/fsnotify from 1.4.9 to 1.6.0 (jpillora#389) Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * UDP buffer size override with CHISEL_UDP_MAX_SIZE environment variable (jpillora#367) * Add locking around the connection count to fix a data race. (jpillora#342) Co-authored-by: andres-portainer <[email protected]> * fix: small typo error in main.go (jpillora#334) * Respond to /health and /version by request path rather than by the whole url string (jpillora#328) Co-authored-by: bar <[email protected]> * Update version.go (jpillora#288) * Providing chisel's client with a logger level (jpillora#281) Co-authored-by: Barak Sharoni <[email protected]> Co-authored-by: barak-sharoni-velocity <[email protected]> * add EnvBool * Fix jpillora#390: Use code to generate certificates for client & server (jpillora#400) * docker alpine->google-distroless * docker to use scratch * Fix missing NetDialContext: c.config.DialContext (jpillora#398) * actions: setup go v3 * switch to scratch image * update dependabot * move chisel to flyio * Bump to Go 1.21 (jpillora#440) Co-authored-by: cmeng <[email protected]> * add arm v5 builds (jpillora#395) * Sync with upstream --------- Signed-off-by: dependabot[bot] <[email protected]> Signed-off-by: Pratik Raj <[email protected]> Co-authored-by: ip-rw <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Pratik Raj <[email protected]> Co-authored-by: Jaime Pillora <[email protected]> Co-authored-by: fsiegmund <[email protected]> Co-authored-by: andres-portainer <[email protected]> Co-authored-by: andres-portainer <[email protected]> Co-authored-by: 0xflotus <[email protected]> Co-authored-by: BigSully <[email protected]> Co-authored-by: bar <[email protected]> Co-authored-by: invist <[email protected]> Co-authored-by: zuzgon <[email protected]> Co-authored-by: Barak Sharoni <[email protected]> Co-authored-by: barak-sharoni-velocity <[email protected]> Co-authored-by: Jaime Pillora <[email protected]> Co-authored-by: Guillaume SMAHA <[email protected]> Co-authored-by: cmeng <[email protected]> Co-authored-by: maurerr <[email protected]>
1 parent b364cdd commit 187fea3

File tree

12 files changed

+331
-152
lines changed

12 files changed

+331
-152
lines changed

.github/goreleaser.yml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ builds:
2525
- mips64le
2626
- s390x
2727
goarm:
28+
- 5
2829
- 6
2930
- 7
3031
gomips:

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
name: Test
1111
strategy:
1212
matrix:
13-
go-version: [1.19.x, 1.20.x]
13+
go-version: [1.21.x]
1414
platform: [ubuntu-latest, macos-latest, windows-latest]
1515
runs-on: ${{ matrix.platform }}
1616
steps:

README.md

+38-18
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,23 @@ $ chisel server --help
119119
--port, -p, Defines the HTTP listening port (defaults to the environment
120120
variable PORT and fallsback to port 8080).
121121
122-
--key, An optional string to seed the generation of a ECDSA public
122+
--key, (deprecated use --keygen and --keyfile instead)
123+
An optional string to seed the generation of a ECDSA public
123124
and private key pair. All communications will be secured using this
124125
key pair. Share the subsequent fingerprint with clients to enable detection
125126
of man-in-the-middle attacks (defaults to the CHISEL_KEY environment
126127
variable, otherwise a new key is generate each run).
127128
129+
--keygen, A path to write a newly generated PEM-encoded SSH private key file.
130+
If users depend on your --key fingerprint, you may also include your --key to
131+
output your existing key. Use - (dash) to output the generated key to stdout.
132+
133+
--keyfile, An optional path to a PEM-encoded SSH private key. When
134+
this flag is set, the --key option is ignored, and the provided private key
135+
is used to secure all communications. (defaults to the CHISEL_KEY_FILE
136+
environment variable). Since ECDSA keys are short, you may also set keyfile
137+
to an inline base64 private key (e.g. chisel server --keygen - | base64).
138+
128139
--authfile, An optional path to a users.json file. This file should
129140
be an object with users defined like:
130141
{
@@ -300,6 +311,9 @@ $ chisel client --help
300311
--hostname, Optionally set the 'Host' header (defaults to the host
301312
found in the server url).
302313
314+
--sni, Override the ServerName when using TLS (defaults to the
315+
hostname).
316+
303317
--tls-ca, An optional root certificate bundle used to verify the
304318
chisel server. Only valid when connecting to the server with
305319
"https" or "wss". By default, the operating system CAs will be used.
@@ -341,38 +355,42 @@ $ chisel client --help
341355

342356
### Security
343357

344-
Encryption is always enabled. When you start up a chisel server, it will generate an in-memory ECDSA public/private key pair. The public key fingerprint (base64 encoded SHA256) will be displayed as the server starts. Instead of generating a random key, the server may optionally specify a key seed, using the `--key` option, which will be used to seed the key generation. When clients connect, they will also display the server's public key fingerprint. The client can force a particular fingerprint using the `--fingerprint` option. See the `--help` above for more information.
358+
Encryption is always enabled. When you start up a chisel server, it will generate an in-memory ECDSA public/private key pair. The public key fingerprint (base64 encoded SHA256) will be displayed as the server starts. Instead of generating a random key, the server may optionally specify a key file, using the `--keyfile` option. When clients connect, they will also display the server's public key fingerprint. The client can force a particular fingerprint using the `--fingerprint` option. See the `--help` above for more information.
345359

346360
### Authentication
347361

348362
Using the `--authfile` option, the server may optionally provide a `user.json` configuration file to create a list of accepted users. The client then authenticates using the `--auth` option. See [users.json](example/users.json) for an example authentication configuration file. See the `--help` above for more information.
349363

350364
Internally, this is done using the _Password_ authentication method provided by SSH. Learn more about `crypto/ssh` here http://blog.gopheracademy.com/go-and-ssh/.
351365

352-
### SOCKS5 Guide
366+
### SOCKS5 Guide with Docker
367+
368+
1. Print a new private key to the terminal
369+
370+
```sh
371+
chisel server --keygen -
372+
# or save it to disk --keygen /path/to/mykey
373+
```
353374

354375
1. Start your chisel server
355376

356-
```sh
357-
docker run \
358-
--name chisel -p 9312:9312 \
359-
-d --restart always \
360-
jpillora/chisel server -p 9312 --socks5 --key supersecret
361-
```
377+
```sh
378+
jpillora/chisel server --keyfile '<ck-base64 string or file path>' -p 9312 --socks5
379+
```
362380

363-
2. Connect your chisel client (using server's fingerprint)
381+
1. Connect your chisel client (using server's fingerprint)
364382
365-
```sh
366-
chisel client --fingerprint 'rHb55mcxf6vSckL2AezFV09rLs7pfPpavVu++MF7AhQ=' <server-address>:9312 socks
367-
```
383+
```sh
384+
chisel client --fingerprint '<see server output>' <server-address>:9312 socks
385+
```
368386
369-
3. Point your SOCKS5 clients (e.g. OS/Browser) to:
387+
1. Point your SOCKS5 clients (e.g. OS/Browser) to:
370388
371-
```
372-
<client-address>:1080
373-
```
389+
```
390+
<client-address>:1080
391+
```
374392
375-
4. Now you have an encrypted, authenticated SOCKS5 connection over HTTP
393+
1. Now you have an encrypted, authenticated SOCKS5 connection over HTTP
376394
377395
378396
#### Caveats
@@ -403,6 +421,8 @@ Since WebSockets support is required:
403421
- `1.5` - Added reverse SOCKS support (by @aus)
404422
- `1.6` - Added client stdio support (by @BoleynSu)
405423
- `1.7` - Added UDP support
424+
- `1.8` - Move to a `scratch`Docker image
425+
- `1.9` - Switch from `--key` seed to P256 key strings with `--key{gen,file}` + bump to Go 1.21 (by @cmenginnz)
406426
407427
## License
408428

client/client.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"golang.org/x/sync/errgroup"
3030
)
3131

32-
//Config represents a client configuration
32+
// Config represents a client configuration
3333
type Config struct {
3434
Fingerprint string
3535
Auth string
@@ -45,7 +45,7 @@ type Config struct {
4545
Verbose bool
4646
}
4747

48-
//TLSConfig for a Client
48+
// TLSConfig for a Client
4949
type TLSConfig struct {
5050
SkipVerify bool
5151
CA string
@@ -54,7 +54,7 @@ type TLSConfig struct {
5454
ServerName string
5555
}
5656

57-
//Client represents a client instance
57+
// Client represents a client instance
5858
type Client struct {
5959
*cio.Logger
6060
config *Config
@@ -69,7 +69,7 @@ type Client struct {
6969
tunnel *tunnel.Tunnel
7070
}
7171

72-
//NewClient creates a new client instance
72+
// NewClient creates a new client instance
7373
func NewClient(c *Config) (*Client, error) {
7474
//apply default scheme
7575
if !strings.HasPrefix(c.Server, "http") {
@@ -190,7 +190,7 @@ func NewClient(c *Config) (*Client, error) {
190190
return client, nil
191191
}
192192

193-
//Run starts client and blocks while connected
193+
// Run starts client and blocks while connected
194194
func (c *Client) Run() error {
195195
ctx, cancel := context.WithCancel(context.Background())
196196
defer cancel()
@@ -221,7 +221,7 @@ func (c *Client) verifyServer(hostname string, remote net.Addr, key ssh.PublicKe
221221
return nil
222222
}
223223

224-
//verifyLegacyFingerprint calculates and compares legacy MD5 fingerprints
224+
// verifyLegacyFingerprint calculates and compares legacy MD5 fingerprints
225225
func (c *Client) verifyLegacyFingerprint(key ssh.PublicKey) error {
226226
bytes := md5.Sum(key.Marshal())
227227
strbytes := make([]string, len(bytes))
@@ -236,7 +236,7 @@ func (c *Client) verifyLegacyFingerprint(key ssh.PublicKey) error {
236236
return nil
237237
}
238238

239-
//Start client and does not block
239+
// Start client and does not block
240240
func (c *Client) Start(ctx context.Context) error {
241241
ctx, cancel := context.WithCancel(ctx)
242242
c.stop = cancel
@@ -293,12 +293,12 @@ func (c *Client) setProxy(u *url.URL, d *websocket.Dialer) error {
293293
return nil
294294
}
295295

296-
//Wait blocks while the client is running.
296+
// Wait blocks while the client is running.
297297
func (c *Client) Wait() error {
298298
return c.eg.Wait()
299299
}
300300

301-
//Close manually stops the client
301+
// Close manually stops the client
302302
func (c *Client) Close() error {
303303
if c.stop != nil {
304304
c.stop()

client/client_test.go

+49-75
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package chclient
22

33
import (
4-
"crypto/ecdsa"
54
"crypto/elliptic"
65
"log"
76
"net/http"
@@ -45,87 +44,62 @@ func TestCustomHeaders(t *testing.T) {
4544
c.Close()
4645
}
4746

48-
// with the update Go to 1.20, these Unit Tests start failing,
49-
// since this test is related to client side, and the "fingerprint" flag is not available in cloud-connector
50-
// we can remove/comment these 3 Unit Tests, until fixed in upstream
51-
52-
// func TestFallbackLegacyFingerprint(t *testing.T) {
53-
// config := Config{
54-
// Fingerprint: "a5:32:92:c6:56:7a:9e:61:26:74:1b:81:a6:f5:1b:44",
55-
// }
56-
// c, err := NewClient(&config)
57-
// if err != nil {
58-
// t.Fatal(err)
59-
// }
60-
// r := ccrypto.NewDetermRand([]byte("test123"))
61-
// priv, err := ecdsa.GenerateKey(elliptic.P256(), r)
62-
// if err != nil {
63-
// t.Fatal(err)
64-
// }
65-
// pub, err := ssh.NewPublicKey(&priv.PublicKey)
66-
// if err != nil {
67-
// t.Fatal(err)
68-
// }
69-
// err = c.verifyServer("", nil, pub)
70-
// if err != nil {
71-
// t.Fatal(err)
72-
// }
73-
// }
74-
75-
// func TestVerifyLegacyFingerprint(t *testing.T) {
76-
// config := Config{
77-
// Fingerprint: "a5:32:92:c6:56:7a:9e:61:26:74:1b:81:a6:f5:1b:44",
78-
// }
79-
// c, err := NewClient(&config)
80-
// if err != nil {
81-
// t.Fatal(err)
82-
// }
83-
// r := ccrypto.NewDetermRand([]byte("test123"))
84-
// priv, err := ecdsa.GenerateKey(elliptic.P256(), r)
85-
// if err != nil {
86-
// t.Fatal(err)
87-
// }
88-
// pub, err := ssh.NewPublicKey(&priv.PublicKey)
89-
// if err != nil {
90-
// t.Fatal(err)
91-
// }
92-
// err = c.verifyLegacyFingerprint(pub)
93-
// if err != nil {
94-
// t.Fatal(err)
95-
// }
96-
// }
47+
func TestFallbackLegacyFingerprint(t *testing.T) {
48+
config := Config{
49+
Fingerprint: "a5:32:92:c6:56:7a:9e:61:26:74:1b:81:a6:f5:1b:44",
50+
}
51+
c, err := NewClient(&config)
52+
if err != nil {
53+
t.Fatal(err)
54+
}
55+
r := ccrypto.NewDetermRand([]byte("test123"))
56+
priv, err := ccrypto.GenerateKeyGo119(elliptic.P256(), r)
57+
if err != nil {
58+
t.Fatal(err)
59+
}
60+
pub, err := ssh.NewPublicKey(&priv.PublicKey)
61+
if err != nil {
62+
t.Fatal(err)
63+
}
64+
err = c.verifyServer("", nil, pub)
65+
if err != nil {
66+
t.Fatal(err)
67+
}
68+
}
9769

98-
// func TestVerifyFingerprint(t *testing.T) {
99-
// config := Config{
100-
// Fingerprint: "qmrRoo8MIqePv3jC8+wv49gU6uaFgD3FASQx9V8KdmY=",
101-
// }
102-
// c, err := NewClient(&config)
103-
// if err != nil {
104-
// t.Fatal(err)
105-
// }
106-
// r := ccrypto.NewDetermRand([]byte("test123"))
107-
// priv, err := ecdsa.GenerateKey(elliptic.P256(), r)
108-
// if err != nil {
109-
// t.Fatal(err)
110-
// }
111-
// pub, err := ssh.NewPublicKey(&priv.PublicKey)
112-
// if err != nil {
113-
// t.Fatal(err)
114-
// }
115-
// err = c.verifyServer("", nil, pub)
116-
// if err != nil {
117-
// t.Fatal(err)
118-
// }
119-
// }
70+
func TestVerifyLegacyFingerprint(t *testing.T) {
71+
config := Config{
72+
Fingerprint: "a5:32:92:c6:56:7a:9e:61:26:74:1b:81:a6:f5:1b:44",
73+
}
74+
c, err := NewClient(&config)
75+
if err != nil {
76+
t.Fatal(err)
77+
}
78+
r := ccrypto.NewDetermRand([]byte("test123"))
79+
priv, err := ccrypto.GenerateKeyGo119(elliptic.P256(), r)
80+
if err != nil {
81+
t.Fatal(err)
82+
}
83+
pub, err := ssh.NewPublicKey(&priv.PublicKey)
84+
if err != nil {
85+
t.Fatal(err)
86+
}
87+
err = c.verifyLegacyFingerprint(pub)
88+
if err != nil {
89+
t.Fatal(err)
90+
}
91+
}
12092

121-
func TestVerifyEmptyFingerprint(t *testing.T) {
122-
config := Config{}
93+
func TestVerifyFingerprint(t *testing.T) {
94+
config := Config{
95+
Fingerprint: "qmrRoo8MIqePv3jC8+wv49gU6uaFgD3FASQx9V8KdmY=",
96+
}
12397
c, err := NewClient(&config)
12498
if err != nil {
12599
t.Fatal(err)
126100
}
127101
r := ccrypto.NewDetermRand([]byte("test123"))
128-
priv, err := ecdsa.GenerateKey(elliptic.P256(), r)
102+
priv, err := ccrypto.GenerateKeyGo119(elliptic.P256(), r)
129103
if err != nil {
130104
t.Fatal(err)
131105
}

go.mod

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/jpillora/chisel
22

3-
go 1.20
3+
go 1.21
44

55
require (
66
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
@@ -9,15 +9,15 @@ require (
99
github.com/jpillora/backoff v1.0.0
1010
github.com/jpillora/requestlog v1.0.0
1111
github.com/jpillora/sizestr v1.0.0
12-
golang.org/x/crypto v0.10.0
13-
golang.org/x/net v0.11.0
12+
golang.org/x/crypto v0.12.0
13+
golang.org/x/net v0.14.0
1414
golang.org/x/sync v0.3.0
1515
)
1616

1717
require (
1818
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 // indirect
1919
github.com/jpillora/ansi v1.0.3 // indirect
2020
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect
21-
golang.org/x/sys v0.9.0 // indirect
22-
golang.org/x/text v0.10.0 // indirect
21+
golang.org/x/sys v0.11.0 // indirect
22+
golang.org/x/text v0.12.0 // indirect
2323
)

0 commit comments

Comments
 (0)