From 3f844a50de063dfcae73d09473b94962879a87d2 Mon Sep 17 00:00:00 2001 From: halulu Date: Fri, 27 Apr 2018 19:31:19 +0800 Subject: [PATCH 1/2] custom tls --- .gitignore | 4 +++- core/client.go | 2 +- core/server.go | 25 +++++-------------------- main.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 441aa15..82e5538 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .idea Caddyfile caddy.log -dist \ No newline at end of file +dist +websocks.cer +websocks.key diff --git a/core/client.go b/core/client.go index 12a8e98..a755804 100644 --- a/core/client.go +++ b/core/client.go @@ -43,7 +43,7 @@ func (client *Client) Listen() (err error) { if err != nil { return } - println(client.InsecureCert) + config.TlsConfig = &tls.Config{ InsecureSkipVerify: client.InsecureCert, } diff --git a/core/server.go b/core/server.go index 0713aaf..8138f51 100644 --- a/core/server.go +++ b/core/server.go @@ -8,11 +8,8 @@ import ( "time" - "crypto/tls" - "github.com/juju/loggo" "golang.org/x/net/websocket" - "k8s.io/client-go/util/cert" ) type Server struct { @@ -20,6 +17,8 @@ type Server struct { Pattern string ListenAddr string TLS bool + CertPath string + KeyPath string } var opened = 0 @@ -75,7 +74,7 @@ func (server *Server) Listen() (err error) { go func() { for { time.Sleep(time.Second) - logger.Debugf("%s: opened%d, closed%d", time.Since(t), opened, closed) + logger.Debugf("%ds: opened%d, closed%d", int(time.Since(t).Seconds()), opened, closed) } }() @@ -88,29 +87,15 @@ func (server *Server) Listen() (err error) { return } - println("tls") - c, k, err := cert.GenerateSelfSignedCertKey("baidu.com", nil, nil) - if err != nil { - return err - } - - certificate, err := tls.X509KeyPair(c, k) - if err != nil { - return err - } - mux := http.NewServeMux() mux.Handle(server.Pattern, websocket.Handler(handler)) s := http.Server{ - Addr: server.ListenAddr, - TLSConfig: &tls.Config{ - Certificates: []tls.Certificate{certificate}, - }, + Addr: server.ListenAddr, Handler: mux, } - err = s.ListenAndServeTLS("", "") + err = s.ListenAndServeTLS(server.CertPath, server.KeyPath) if err != nil { return err } diff --git a/main.go b/main.go index cc62a47..b668548 100644 --- a/main.go +++ b/main.go @@ -7,9 +7,12 @@ import ( "os/exec" + "io/ioutil" + "github.com/juju/loggo" "github.com/lzjluzijie/websocks/core" "github.com/urfave/cli" + "k8s.io/client-go/util/cert" ) var logger = loggo.GetLogger("websocks") @@ -113,12 +116,24 @@ func main() { Name: "tls", Usage: "enable built-in tls", }, + cli.StringFlag{ + Name: "cert", + Value: "websocks.cer", + Usage: "tls cert path", + }, + cli.StringFlag{ + Name: "key", + Value: "websocks.key", + Usage: "tls key path", + }, }, Action: func(c *cli.Context) (err error) { debug := c.GlobalBool("debug") listenAddr := c.String("l") pattern := c.String("p") tls := c.Bool("tls") + certPath := c.String("cert") + keyPath := c.String("key") if debug { logger.SetLogLevel(loggo.DEBUG) @@ -133,6 +148,8 @@ func main() { Pattern: pattern, ListenAddr: listenAddr, TLS: tls, + CertPath: certPath, + KeyPath: keyPath, } logger.Infof("Listening at %s", listenAddr) @@ -153,6 +170,37 @@ func main() { return }, }, + { + Name: "key", + Aliases: []string{"key"}, + Usage: "generate self signed cert and key", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "host", + Value: "baidu.com", + Usage: "certificate host", + }, + }, + Action: func(c *cli.Context) (err error) { + host := c.String("host") + certByte, keyByte, err := cert.GenerateSelfSignedCertKey(host, nil, nil) + if err != nil { + return err + } + + err = ioutil.WriteFile("websocks.cer", certByte, 0600) + if err != nil { + return err + } + + err = ioutil.WriteFile("websocks.key", keyByte, 0600) + if err != nil { + return err + } + + return + }, + }, } err := app.Run(os.Args) From f81506985b5302b3a67ed099695016cd0d74cfb0 Mon Sep 17 00:00:00 2001 From: halulu Date: Sat, 28 Apr 2018 17:41:00 +0800 Subject: [PATCH 2/2] generate self signed p256 key and cert --- core/crypto.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 28 +++++++++------------- 2 files changed, 75 insertions(+), 17 deletions(-) create mode 100644 core/crypto.go diff --git a/core/crypto.go b/core/crypto.go new file mode 100644 index 0000000..a842b33 --- /dev/null +++ b/core/crypto.go @@ -0,0 +1,64 @@ +package core + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "math/big" + "net" + "time" +) + +//Modified https://github.com/Shyp/generate-tls-cert +func GenP256(hosts []string) (key, cert []byte, err error) { + notBefore := time.Now() + notAfter := notBefore.Add(time.Hour * 24 * 366) + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return + } + serverKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return + } + + serverTemplate := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{"WebSocks"}, + CommonName: "WebSocks Server CA", + }, + NotBefore: notBefore, + NotAfter: notAfter, + KeyUsage: x509.KeyUsageCertSign, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + IsCA: true, + } + + for _, host := range hosts { + if ip := net.ParseIP(host); ip != nil { + serverTemplate.IPAddresses = append(serverTemplate.IPAddresses, ip) + } else { + serverTemplate.DNSNames = append(serverTemplate.DNSNames, host) + } + } + + serverCert, err := x509.CreateCertificate(rand.Reader, &serverTemplate, &serverTemplate, &serverKey.PublicKey, serverKey) + if err != nil { + return + } + + x509Key, err := x509.MarshalECPrivateKey(serverKey) + if err != nil { + return + } + + key = pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: x509Key}) + cert = pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: serverCert}) + return +} diff --git a/main.go b/main.go index b668548..5f410b3 100644 --- a/main.go +++ b/main.go @@ -12,7 +12,6 @@ import ( "github.com/juju/loggo" "github.com/lzjluzijie/websocks/core" "github.com/urfave/cli" - "k8s.io/client-go/util/cert" ) var logger = loggo.GetLogger("websocks") @@ -20,7 +19,7 @@ var logger = loggo.GetLogger("websocks") func main() { app := cli.NewApp() app.Name = "WebSocks" - app.Version = "0.2.1" + app.Version = "0.2.2" app.Usage = "A secure proxy based on websocket." app.Description = "See https://github.com/lzjluzijie/websocks" app.Author = "Halulu" @@ -175,29 +174,24 @@ func main() { Aliases: []string{"key"}, Usage: "generate self signed cert and key", Flags: []cli.Flag{ - cli.StringFlag{ - Name: "host", - Value: "baidu.com", - Usage: "certificate host", + cli.StringSliceFlag{ + Name: "hosts", + Value: &cli.StringSlice{"github.com"}, + Usage: "certificate hosts", }, }, Action: func(c *cli.Context) (err error) { - host := c.String("host") - certByte, keyByte, err := cert.GenerateSelfSignedCertKey(host, nil, nil) - if err != nil { - return err - } + hosts := c.StringSlice("hosts") - err = ioutil.WriteFile("websocks.cer", certByte, 0600) + key, cert, err := core.GenP256(hosts) + err = ioutil.WriteFile("websocks.key", key, 0600) if err != nil { - return err + return } - - err = ioutil.WriteFile("websocks.key", keyByte, 0600) + err = ioutil.WriteFile("websocks.cer", cert, 0600) if err != nil { - return err + return } - return }, },