mirror of
				https://github.com/therootcompany/sclient
				synced 2024-11-16 17:09:00 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "master" and "v1.3.2" have entirely different histories.
		
	
	
		
	
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1 @@ | ||||
| /sclient | ||||
| /cmd/sclient/sclient | ||||
| 
 | ||||
| dist | ||||
|  | ||||
| @ -1,37 +0,0 @@ | ||||
| before: | ||||
|   hooks: | ||||
|     - go mod download | ||||
|     - go generate ./... | ||||
| builds: | ||||
|   - main: ./cmd/sclient/main.go | ||||
|     env: | ||||
|       - CGO_ENABLED=0 | ||||
|     goos: | ||||
|       - linux | ||||
|       - windows | ||||
|       - darwin | ||||
|     goarch: | ||||
|       - 386 | ||||
|       - amd64 | ||||
|       - arm | ||||
|       - arm64 | ||||
|     goarm: | ||||
|       - 6 | ||||
|       - 7 | ||||
| archives: | ||||
|   - replacements: | ||||
|       386: i386 | ||||
|       amd64: x86_64 | ||||
|     format_overrides: | ||||
|       - goos: windows | ||||
|         format: zip | ||||
| checksum: | ||||
|   name_template: 'checksums.txt' | ||||
| snapshot: | ||||
|   name_template: "{{ .Tag }}-next" | ||||
| changelog: | ||||
|   sort: asc | ||||
|   filters: | ||||
|     exclude: | ||||
|       - '^docs:' | ||||
|       - '^test:' | ||||
							
								
								
									
										114
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								README.md
									
									
									
									
									
								
							| @ -1,4 +1,5 @@ | ||||
| # sclient | ||||
| sclient.go | ||||
| ========== | ||||
| 
 | ||||
| Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally. | ||||
| 
 | ||||
| @ -7,75 +8,81 @@ Also ideal for multiplexing a single port with multiple protocols using SNI. | ||||
| Unwrap a TLS connection: | ||||
| 
 | ||||
| ```bash | ||||
| sclient whatever.com:443 localhost:3000 | ||||
| 
 | ||||
| $ sclient whatever.com:443 localhost:3000 | ||||
| > [listening] whatever.com:443 <= localhost:3000 | ||||
| ``` | ||||
| 
 | ||||
| Connect via Telnet | ||||
| 
 | ||||
| ```bash | ||||
| telnet localhost 3000 | ||||
| $ telnet localhost 3000 | ||||
| ``` | ||||
| 
 | ||||
| Connect via netcat (nc) | ||||
| 
 | ||||
| ```bash | ||||
| nc localhost 3000 | ||||
| $ nc localhost 3000 | ||||
| ``` | ||||
| 
 | ||||
| cURL | ||||
| 
 | ||||
| ```bash | ||||
| curl http://localhost:3000 -H 'Host: whatever.com' | ||||
| $ curl http://localhost:3000 -H 'Host: whatever.com' | ||||
| ``` | ||||
| 
 | ||||
| A poor man's (or Windows user's) makeshift replacement for `openssl s_client`, `stunnel`, or `socat`. | ||||
| 
 | ||||
| # Table of Contents | ||||
| 
 | ||||
| - [Install](#install) | ||||
| - [Usage](#usage) | ||||
| - [Examples](#examples) | ||||
| - [Build from Source](#build-from-source) | ||||
| 
 | ||||
| # Install | ||||
| 
 | ||||
| ### Mac, Linux | ||||
| 
 | ||||
| ```bash | ||||
| curl -sS https://webinstall.dev/sclient | bash | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| curl.exe -A MS https://webinstall.dev/sclient | powershell | ||||
| ``` | ||||
| Install | ||||
| ======= | ||||
| 
 | ||||
| ### Downloads | ||||
| 
 | ||||
| Check the [Github Releases](https://github.com/therootcompany/sclient/releases) for | ||||
| * [Windows 10](https://telebit.cloud/sclient/dist/windows/amd64/sclient.exe) | ||||
| * [Mac OS X](https://telebit.cloud/sclient/dist/darwin/amd64/sclient) | ||||
| * [Linux (x64)](https://telebit.cloud/sclient/dist/linux/amd64/sclient) | ||||
| * [Raspberry Pi (armv7)](https://telebit.cloud/sclient/dist/linux/armv7/sclient) | ||||
| * more downloads <https://telebit.cloud/sclient/> | ||||
| 
 | ||||
| - macOS (x64) Apple Silicon [coming soon](https://github.com/golang/go/issues/39782) | ||||
| - Linux (x64, i386, arm64, arm6, arm7) | ||||
| - Windows 10 (x64, i386) | ||||
| ### Build from source | ||||
| 
 | ||||
| # Usage | ||||
| For the moment you'll have to install go and compile `sclient` yourself: | ||||
| 
 | ||||
| * <https://golang.org/doc/install#install> | ||||
| 
 | ||||
| ```bash | ||||
| git clone https://git.rootprojects.org/root/sclient.go.git | ||||
| pushd sclient.go | ||||
| go build -o dist/sclient cmd/sclient/main.go | ||||
| rsync -av dist/sclient /usr/local/bin/sclient | ||||
| sclient example.com:443 localhost:3000 | ||||
| ``` | ||||
| 
 | ||||
| Or | ||||
| 
 | ||||
| ```bash | ||||
| go get git.rootprojects.org/root/sclient.go/cmd/sclient | ||||
| go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 | ||||
| ``` | ||||
| 
 | ||||
| Usage | ||||
| ===== | ||||
| 
 | ||||
| ```bash | ||||
| sclient [flags] <remote> <local> | ||||
| ``` | ||||
| 
 | ||||
| - flags | ||||
|   - -k, --insecure ignore invalid TLS (SSL/HTTPS) certificates | ||||
|   - --servername <string> spoof SNI (to disable use IP as <remote> and do not use this option) | ||||
| - remote | ||||
|   - must have servername (i.e. example.com) | ||||
|   - port is optional (default is 443) | ||||
| - local | ||||
|   - address is optional (default is localhost) | ||||
|   - must have port (i.e. 3000) | ||||
| * flags | ||||
|   * -k, --insecure ignore invalid TLS (SSL/HTTPS) certificates | ||||
|   * --servername <string> spoof SNI (to disable use IP as <remote> and do not use this option) | ||||
| * remote | ||||
|   * must have servername (i.e. example.com) | ||||
|   * port is optional (default is 443) | ||||
| * local | ||||
|   * address is optional (default is localhost) | ||||
|   * must have port (i.e. 3000) | ||||
| 
 | ||||
| # Examples | ||||
| Examples | ||||
| ======== | ||||
| 
 | ||||
| Bridge between `telebit.cloud` and local port `3000`. | ||||
| 
 | ||||
| @ -120,32 +127,3 @@ sclient --servername "Robert'); DROP TABLE Students;" -k example.com localhost:3 | ||||
| ```bash | ||||
| sclient --servername "../../../.hidden/private.txt" -k example.com localhost:3000 | ||||
| ``` | ||||
| 
 | ||||
| # Build from source | ||||
| 
 | ||||
| You'll need to install [Go](https://golang.org). | ||||
| See [webinstall.dev/golang](https://webinstall.dev/golang) for install instructions. | ||||
| 
 | ||||
| ```bash | ||||
| curl -sS https://webinstall.dev/golang | bash | ||||
| ``` | ||||
| 
 | ||||
| Then you can install and run as per usual. | ||||
| 
 | ||||
| ```bash | ||||
| git clone https://git.rootprojects.org/root/sclient.go.git | ||||
| 
 | ||||
| pushd sclient.go | ||||
|   go build -o dist/sclient cmd/sclient/main.go | ||||
|   sudo rsync -av dist/sclient /usr/local/bin/sclient | ||||
| popd | ||||
| 
 | ||||
| sclient example.com:443 localhost:3000 | ||||
| ``` | ||||
| 
 | ||||
| ## Install or Run with Go | ||||
| 
 | ||||
| ```bash | ||||
| go get git.rootprojects.org/root/sclient.go/cmd/sclient | ||||
| go run git.rootprojects.org/root/sclient.go/cmd/sclient example.com:443 localhost:3000 | ||||
| ``` | ||||
|  | ||||
							
								
								
									
										33
									
								
								build-all.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								build-all.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| #GOOS=windows GOARCH=amd64 go install | ||||
| go tool dist list | ||||
| 
 | ||||
| gocmd=cmd/sclient/main.go | ||||
| golib="" | ||||
| echo "" | ||||
| 
 | ||||
| echo "" | ||||
| echo "Windows amd64" | ||||
| GOOS=windows GOARCH=amd64 go build -o dist/windows/amd64/sclient.exe $gocmd $golib | ||||
| echo "Windows 386" | ||||
| GOOS=windows GOARCH=386 go build -o dist/windows/386/sclient.exe $gocmd $golib | ||||
| 
 | ||||
| echo "" | ||||
| echo "Darwin (macOS) amd64" | ||||
| GOOS=darwin GOARCH=amd64 go build -o dist/darwin/amd64/sclient $gocmd $golib | ||||
| 
 | ||||
| echo "" | ||||
| echo "Linux amd64" | ||||
| GOOS=linux GOARCH=amd64 go build -o dist/linux/amd64/sclient $gocmd $golib | ||||
| echo "Linux 386" | ||||
| 
 | ||||
| echo "" | ||||
| GOOS=linux GOARCH=386 go build -o dist/linux/386/sclient $gocmd $golib | ||||
| echo "RPi 3 B+ ARMv7" | ||||
| GOOS=linux GOARCH=arm GOARM=7 go build -o dist/linux/armv7/sclient $gocmd $golib | ||||
| echo "RPi Zero ARMv5" | ||||
| GOOS=linux GOARCH=arm GOARM=5 go build -o dist/linux/armv5/sclient $gocmd $golib | ||||
| 
 | ||||
| echo "" | ||||
| echo "" | ||||
| 
 | ||||
| rsync -av ./dist/ root@telebit.cloud:/opt/telebit-relay/lib/extensions/admin/sclient/dist/ | ||||
| @ -10,49 +10,23 @@ import ( | ||||
| 	sclient "git.rootprojects.org/root/sclient.go" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// commit refers to the abbreviated commit hash | ||||
| 	commit = "0000000" | ||||
| 	// version refers to the most recent tag, plus any commits made since then | ||||
| 	version = "v0.0.0-pre0+0000000" | ||||
| 	// GitTimestamp refers to the timestamp of the most recent commit | ||||
| 	date = "0000-00-00T00:00:00+0000" | ||||
| ) | ||||
| 
 | ||||
| func ver() string { | ||||
| 	return fmt.Sprintf("sclient %s (%s) %s", version, commit[:7], date) | ||||
| } | ||||
| 
 | ||||
| func usage() { | ||||
| 	fmt.Fprintf(os.Stderr, "\n%s\n"+ | ||||
| 		"\nusage: sclient <remote> <local>\n"+ | ||||
| 	fmt.Fprintf(os.Stderr, "\nusage: sclient <remote> <local>\n"+ | ||||
| 		"\n"+ | ||||
| 		"   ex: sclient example.com 3000\n"+ | ||||
| 		"      (sclient example.com:443 localhost:3000)\n"+ | ||||
| 		"\n"+ | ||||
| 		"   ex: sclient example.com:8443 0.0.0.0:4080\n"+ | ||||
| 		"\n"+ | ||||
| 		"   ex: sclient example.com:443 -\n"+ | ||||
| 		"\n", ver()) | ||||
| 		"\n") | ||||
| 	flag.PrintDefaults() | ||||
| 	fmt.Println() | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	if len(os.Args) >= 2 { | ||||
| 		if "version" == strings.TrimLeft(os.Args[1], "-") { | ||||
| 			fmt.Printf("%s\n", ver()) | ||||
| 			os.Exit(0) | ||||
| 			return | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	flag.Usage = usage | ||||
| 	insecure := flag.Bool("k", false, "alias for --insecure") | ||||
| 	silent := flag.Bool("s", false, "alias of --silent") | ||||
| 	insecure := flag.Bool("k", false, "ignore bad TLS/SSL/HTTPS certificates") | ||||
| 	servername := flag.String("servername", "", "specify a servername different from <remote> (to disable SNI use an IP as <remote> and do use this option)") | ||||
| 	flag.BoolVar(insecure, "insecure", false, "ignore bad TLS/SSL/HTTPS certificates") | ||||
| 	flag.BoolVar(silent, "silent", false, "less verbose output") | ||||
| 	flag.Parse() | ||||
| 	remotestr := flag.Arg(0) | ||||
| 	localstr := flag.Arg(1) | ||||
| @ -73,7 +47,6 @@ func main() { | ||||
| 		LocalAddress:       "localhost", | ||||
| 		InsecureSkipVerify: *insecure, | ||||
| 		ServerName:         *servername, | ||||
| 		Silent:             *silent, | ||||
| 	} | ||||
| 
 | ||||
| 	remote := strings.Split(remotestr, ":") | ||||
|  | ||||
							
								
								
									
										25
									
								
								sclient.go
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								sclient.go
									
									
									
									
									
								
							| @ -18,7 +18,6 @@ type Tunnel struct { | ||||
| 	LocalPort          int | ||||
| 	InsecureSkipVerify bool | ||||
| 	ServerName         string | ||||
| 	Silent             bool | ||||
| } | ||||
| 
 | ||||
| // DialAndListen will create a test TLS connection to the remote address and then | ||||
| @ -46,7 +45,7 @@ func (t *Tunnel) DialAndListen() error { | ||||
| 		} else { | ||||
| 			name = "stdin" | ||||
| 		} | ||||
| 		conn := &stdnet{os.Stdin, os.Stdout, &stdaddr{net.UnixAddr{Name: name, Net: network}}} | ||||
| 		conn := &stdnet{os.Stdin, os.Stdout, &stdaddr{net.UnixAddr{name, network}}} | ||||
| 		t.handleConnection(remote, conn) | ||||
| 		return nil | ||||
| 	} | ||||
| @ -58,10 +57,8 @@ func (t *Tunnel) DialAndListen() error { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if !t.Silent { | ||||
| 		fmt.Fprintf(os.Stdout, "[listening] %s:%d <= %s:%d\n", | ||||
| 			t.RemoteAddress, t.RemotePort, t.LocalAddress, t.LocalPort) | ||||
| 	} | ||||
| 	fmt.Fprintf(os.Stdout, "[listening] %s:%d <= %s:%d\n", | ||||
| 		t.RemoteAddress, t.RemotePort, t.LocalAddress, t.LocalPort) | ||||
| 
 | ||||
| 	for { | ||||
| 		conn, err := ln.Accept() | ||||
| @ -113,7 +110,7 @@ func pipe(r netReadWriteCloser, w netReadWriteCloser, t string) { | ||||
| 		if nil != err { | ||||
| 			//fmt.Fprintf(os.Stdout, "[debug] (%s:%d) error reading %s\n", t, count, err) | ||||
| 			if io.EOF != err { | ||||
| 				fmt.Fprintf(os.Stderr, "[read error] (%s:%d) %s\n", t, count, err) | ||||
| 				fmt.Fprintf(os.Stderr, "[read error] (%s:%s) %s\n", t, count, err) | ||||
| 			} | ||||
| 			r.Close() | ||||
| 			//w.Close() | ||||
| @ -152,14 +149,12 @@ func (t *Tunnel) handleConnection(remote string, conn netReadWriteCloser) { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if !t.Silent { | ||||
| 		if "stdio" == conn.RemoteAddr().Network() { | ||||
| 			fmt.Fprintf(os.Stdout, "(connected to %s:%d and reading from %s)\n", | ||||
| 				t.RemoteAddress, t.RemotePort, conn.RemoteAddr().String()) | ||||
| 		} else { | ||||
| 			fmt.Fprintf(os.Stdout, "[connect] %s => %s:%d\n", | ||||
| 				strings.Replace(conn.RemoteAddr().String(), "[::1]:", "localhost:", 1), t.RemoteAddress, t.RemotePort) | ||||
| 		} | ||||
| 	if "stdio" == conn.RemoteAddr().Network() { | ||||
| 		fmt.Fprintf(os.Stdout, "(connected to %s:%d and reading from %s)\n", | ||||
| 			t.RemoteAddress, t.RemotePort, conn.RemoteAddr().String()) | ||||
| 	} else { | ||||
| 		fmt.Fprintf(os.Stdout, "[connect] %s => %s:%d\n", | ||||
| 			strings.Replace(conn.RemoteAddr().String(), "[::1]:", "localhost:", 1), t.RemoteAddress, t.RemotePort) | ||||
| 	} | ||||
| 
 | ||||
| 	go pipe(conn, sclient, "local") | ||||
|  | ||||
| @ -1,11 +0,0 @@ | ||||
| # I like my yoda conditions ST1017 | ||||
| checks = ["all", "-ST1017", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-ST1023"] | ||||
| initialisms = ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", | ||||
| 	"EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", | ||||
| 	"IP", "JSON", "QPS", "RAM", "RPC", "SLA", | ||||
| 	"SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", | ||||
| 	"UDP", "UI", "GID", "UID", "UUID", "URI", | ||||
| 	"URL", "UTF8", "VM", "XML", "XMPP", "XSRF", | ||||
| 	"XSS", "SIP", "RTP", "AMQP", "DB", "TS"] | ||||
| dot_import_whitelist = [] | ||||
| http_status_code_whitelist = ["200", "400", "404", "500"] | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user