How to Build TLS-Encrypted Socket Server and Client in Go
This article explains the fundamentals of TLS as a transport‑layer security protocol, demonstrates how to create a TLS‑encrypted socket server and client in Go, and shows how to generate and verify certificate chains using tools like mkcert.
TLS (formerly SSL) is a Transport Layer Security protocol that operates independently of HTTP; it can be seen as a secure version of TCP, providing encryption and signing for socket communication. In everyday development, protocols such as gRPC are often run over TLS to ensure security.
Below we demonstrate how to create a TLS‑encrypted socket service in Go.
1. TLS socket server
Server example:
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
", *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
", conn.RemoteAddr())
go func(c net.Conn) {
io.Copy(c, c)
c.Close()
log.Printf("closing connection from %s
", conn.RemoteAddr())
}(conn)
}
}The server accepts concurrent client connections and echoes received data. Compared with a non‑TLS server, the only change is replacing net.Listen with tls.Listen and providing a tls.Config. Certificates and keys can be generated with the mkcert command.
2. TLS socket client
Client example:
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
")
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()
}The client replaces net.Dial with tls.Dial and supplies a tls.Config containing trusted root CAs. The certificates can be CA‑signed or self‑signed.
3. Certificate chain
Typically a CSR is submitted to a signing authority; an intermediate CA signs it, and the Root CA signs the intermediate’s CSR, forming a hierarchical chain. When validating a certificate, the verifier walks up the chain until it reaches a trusted root certificate.
Program to inspect any server’s certificate chain:
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("")
}
}If a self‑signed certificate is used without proper trust, the TLS server verification will fail. Therefore a certificate issued by a trusted CA or one generated with mkcert (which adds the certificate to the system’s root store) should be used.
Generate a certificate with mkcert:
➜ ./mkcert localhost
➜ go run tls-socket-server.go -cert localhost.pem -key localhost-key.pemIn another terminal, run the client:
➜ go run tls-dial-port.go -addr localhost:4040Because mkcert adds the generated certificate to the system’s trusted store, tls.Dial will automatically trust it.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
