首页 网维知识库 使用 Go 实现 TLS socket server

使用 Go 实现 TLS socket server

安全传输层协议 TLS,以前称为 SSL(Secure Sockets Layer) ,由于HTTPS的推出受到了很多人的欢迎。但是正如TLS的名称 Transport Layer…

安全传输层协议 TLS,以前称为 SSL(Secure Sockets Layer) ,由于HTTPS的推出受到了很多人的欢迎。但是正如TLS的名称 Transport Layer Security 所示的那样,它实际上是独立于 HTTP,一个更深入的安全协议,我们可以将 TLS 视为 TCP 的安全版本,其提供了对 socket 通信进行加密和签名的功能。在我们的日常开发中,会将 gRPC 协议运行在TLS之上以确保安全。

使用 Go 实现 TLS socket server插图

今天我们来了解一下如何创建一个通过 TLS 加密的 socket 服务。

1.TLS socket server

服务端示例

func main() {
  port := flag.String("port", "8360", "listening port")
  certFile := flag.String("cert", "cert.pem", "certificate PEM file")
  keyFile := flag.String("key", "key.pem", "key PEM file")
  flag.Parse()
  cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
  if err != nil {
    log.Fatal(err)
  }
  config := &tls.Config{Certificates: []tls.Certificate{cert}}
  log.Printf("listening on port %s\n", *port)
  l, err := tls.Listen("tcp", ":"+*port, config)
  if err != nil {
    log.Fatal(err)
  }
  defer l.Close()
  for {
    conn, err := l.Accept()
    if err != nil {
      log.Fatal(err)
    }
    log.Printf("accepted connection from %s\n", conn.RemoteAddr())
    go func(c net.Conn) {
      io.Copy(c, c)
      c.Close()
      log.Printf("closing connection from %s\n", conn.RemoteAddr())
    }(conn)
  }
}

这个服务端程序接受来自多个客户端并发请求,并向客户端发送的所有的镜像数据。和非TLS服务相比,这里用 tls.Listen 替换了 net.Listen,同时需要提供一个可用的 tls.Config,我们可以使用 mkcert 命令来生成证书和密钥对文件。

2.TLS socket client

客户端示例:

func main() {
  port := flag.String("port", "8360", "port to connect")
  certFile := flag.String("certfile", "cert.pem", "trusted CA certificate")
  flag.Parse()
  cert, err := os.ReadFile(*certFile)
  if err != nil {
    log.Fatal(err)
  }
  certPool := x509.NewCertPool()
  if ok := certPool.AppendCertsFromPEM(cert); !ok {
    log.Fatalf("unable to parse cert from %s", *certFile)
  }
  config := &tls.Config{RootCAs: certPool}
  conn, err := tls.Dial("tcp", "localhost:"+*port, config)
  if err != nil {
    log.Fatal(err)
  }
  _, err = io.WriteString(conn, "Hello simple secure Server\n")
  if err != nil {
    log.Fatal("client write error:", err)
  }
  if err = conn.CloseWrite(); err != nil {
    log.Fatal(err)
  }
  buf := make([]byte, 256)
  n, err := conn.Read(buf)
  if err != nil && err != io.EOF {
    log.Fatal(err)
  }
  fmt.Println("client read:", string(buf[:n]))
  conn.Close()
}

和非 TLS 客户端相比,我们同样也只是把 net.Dial 换成 tls.Dial, tls.Config 中填写的证书可以选择权威 ca 颁发的证书,也可以使用自签名证书。

3.证书链

一般来说,我们将自己生成的 CSR 提交给签名商,他们用中级证书机构的私钥 Private Key 给我们的签名成证书,Root CA 通过它的私钥对中级机构提交的CSR进行签名。

证书颁发机构是一个树形结构的。比如在验证我们证书X的有效性的时候,会一层层的去寻找颁发者的证书,直到自签名的根证书,然后通过相应的公钥再反过来验证下一级的数字签名的正确性。直到找到X证书,这就是证书链(Certificate Chains)。

我们可以使用以下程序检查任何服务器的证书链:

func main() {
addr := flag.String("addr", "localhost:8360", "dial address")
flag.Parse()

cfg := tls.Config{}
conn, err := tls.Dial("tcp", *addr, &cfg)
if err != nil {
log.Fatal("TLS connection failed: " + err.Error())
}
defer conn.Close()

certChain := conn.ConnectionState().PeerCertificates
for i, cert := range certChain {
fmt.Println(i)
fmt.Println("Issuer:", cert.Issuer)
fmt.Println("Subject:", cert.Subject)
fmt.Println("Version:", cert.Version)
fmt.Println("NotAfter:", cert.NotAfter)
fmt.Println("DNS names:", cert.DNSNames)
fmt.Println("")
}
}

给定IP地址后,启动程序后会与服务器建立一条 TLS 连接,并上报其使用的证书给服务端。如果我们使用未处理过的自签的证书,TLS 服务端验证是通不过的。所以我们需要权威ca 颁发的证书,或者使用 mkcert 为我们的服务器生成证书来使他生效。

打开终端,执行 mkcert 命令:

➜  kangkai-iri ./mkcert localhost

➜  kangkai-iri go run tls-socket-server.go -cert localhost.pem -key localhost-key.pem

新打开一个终端,运行 tls-dial-port:

➜  kangkai-iri go run tls-dial-port.go -addr localhost:4040

我们看到生成了证书 mkcert。由于 mkcert 将此证书添加到服务器的系统根存储中,直接使用 tls.Dial 将信任该证书。

(版权归原作者所有,侵删)

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。

作者: 3182235786a

为您推荐

windows8

windows8

Windows 8 是微软公司于 2012 年推出的一款操作系统,因其独特的界面设计和功能受到广泛关注。本文将从 Win...
Windows 下载指南:获取最新版本的 Windows 操作系统

Windows 下载指南:获取最新版本的 Windows 操作系统

作为全球最受欢迎的操作系统之一,Windows 提供了丰富的功能和用户友好的界面。如果您想获取最新版本的 Windows...
windows资源管理器已停止工作

windows资源管理器已停止工作

Windows 资源管理器已停止工作是 Windows 操作系统中常见的一个问题,通常表现为资源管理器窗口无法正常打开或...
Windows 10 激活方法详解:轻松激活您的操作系统

Windows 10 激活方法详解:轻松激活您的操作系统

购买了全新的Windows 10操作系统后,如何激活它成为许多用户关注的问题。本文将为您详细介绍Windows 10的激...
windows10激活工具

windows10激活工具

Windows 10 激活工具是一款用于激活 Windows 10 操作系统的软件。通过使用激活工具,用户可以轻松地激活...

发表回复

返回顶部