Secure Client for exposing TLS (aka SSL) secured services as plain-text connections locally. Also ideal for multiplexing a single port with multiple protocols using SNI. https://webinstall.dev/sclient
您最多能選擇 25 個主題 主題必須以字母或數字為開頭,可包含連接號「-」且最長為 35 個字元。
 
 

126 行
2.9 KiB

package main
import (
"flag"
"fmt"
"os"
"strconv"
"strings"
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"+
"\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())
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")
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)
i := flag.NArg()
if 2 != i {
// We may omit the second argument if we're going straight to stdin
if stat, _ := os.Stdin.Stat(); 1 == i && (stat.Mode()&os.ModeCharDevice) == 0 {
localstr = "|"
} else {
usage()
os.Exit(1)
}
}
sclient := &sclient.Tunnel{
RemotePort: 443,
LocalAddress: "localhost",
InsecureSkipVerify: *insecure,
ServerName: *servername,
Silent: *silent,
}
remote := strings.Split(remotestr, ":")
//remoteAddr, remotePort, err := net.SplitHostPort(remotestr)
if 2 == len(remote) {
rport, err := strconv.Atoi(remote[1])
if nil != err {
usage()
os.Exit(0)
}
sclient.RemotePort = rport
} else if 1 != len(remote) {
usage()
os.Exit(0)
}
sclient.RemoteAddress = remote[0]
if "-" == localstr || "|" == localstr {
// User may specify stdin/stdout instead of net
sclient.LocalAddress = localstr
sclient.LocalPort = -1
} else {
// Test that argument is a local address
local := strings.Split(localstr, ":")
if 1 == len(local) {
lport, err := strconv.Atoi(local[0])
if nil != err {
usage()
os.Exit(0)
}
sclient.LocalPort = lport
} else {
lport, err := strconv.Atoi(local[1])
if nil != err {
usage()
os.Exit(0)
}
sclient.LocalAddress = local[0]
sclient.LocalPort = lport
}
}
err := sclient.DialAndListen()
if nil != err {
fmt.Fprintf(os.Stderr, "%s\n", err)
//usage()
//os.Exit(6)
}
}