Функция tls.Listen

Функция tls.Listen создает слушатель (listener) для TLS-соединений. Она принимает два параметра: сетевой протокол (обычно "tcp") и адрес для прослушивания (например, ":443"). Вторым параметром передается указатель на конфигурацию TLS tls.Config, которая содержит сертификаты и настройки шифрования. Функция возвращает объект типа net.Listener и ошибку.

Синтаксис

gotls.Listen(network, laddr string, config *tls.Config) (net.Listener, error)

Пример

Давайте создадим простой TLS-сервер, который принимает соединения и отправляет приветственное сообщение:

gopackage main

import (
  "crypto/tls"
  "fmt"
  "log"
  "net"
)

func main() {
  cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
  if err != nil {
    log.Fatal(err)
  }

  config := &tls.Config{
    Certificates: []tls.Certificate{cert},
  }

  listener, err := tls.Listen("tcp", ":8443", config)
  if err != nil {
    log.Fatal(err)
  }
  defer listener.Close()

  fmt.Println("Server started on :8443")

  for {
    conn, err := listener.Accept()
    if err != nil {
      log.Println(err)
      continue
    }
    go handleConnection(conn)
  }
}

func handleConnection(conn net.Conn) {
  defer conn.Close()
  conn.Write([]byte("Hello, TLS client!\n"))
}

Пример

Давайте создадим TLS-сервер с настройками минимальной версии протокола и списком поддерживаемых шифров:

gopackage main

import (
  "crypto/tls"
  "fmt"
  "log"
  "net"
)

func main() {
  cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
  if err != nil {
    log.Fatal(err)
  }

  config := &tls.Config{
    Certificates:       []tls.Certificate{cert},
    MinVersion:         tls.VersionTLS12,
    PreferServerCipherSuites: true,
    CipherSuites: []uint16{
      tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
      tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
    },
  }

  listener, err := tls.Listen("tcp", ":8443", config)
  if err != nil {
    log.Fatal(err)
  }
  defer listener.Close()

  fmt.Println("Secure server started on :8443")

  for {
    conn, err := listener.Accept()
    if err != nil {
      log.Println(err)
      continue
    }
    go handleSecureConnection(conn)
  }
}

func handleSecureConnection(conn net.Conn) {
  defer conn.Close()
  conn.Write([]byte("Secure connection established\n"))
}

Пример

Давайте создадим TLS-сервер с взаимной аутентификацией, требующий проверку клиентских сертификатов:

gopackage main

import (
  "crypto/tls"
  "crypto/x509"
  "fmt"
  "log"
  "net"
  "os"
)

func main() {
  cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
  if err != nil {
    log.Fatal(err)
  }

  caCert, err := os.ReadFile("ca.crt")
  if err != nil {
    log.Fatal(err)
  }
  caCertPool := x509.NewCertPool()
  caCertPool.AppendCertsFromPEM(caCert)

  config := &tls.Config{
    Certificates: []tls.Certificate{cert},
    ClientAuth:   tls.RequireAndVerifyClientCert,
    ClientCAs:  caCertPool,
  }

  listener, err := tls.Listen("tcp", ":8443", config)
  if err != nil {
    log.Fatal(err)
  }
  defer listener.Close()

  fmt.Println("Mutual TLS server started on :8443")

  for {
    conn, err := listener.Accept()
    if err != nil {
      log.Println(err)
      continue
    }
    go handleMutualTLSConnection(conn)
  }
}

func handleMutualTLSConnection(conn net.Conn) {
  defer conn.Close()
  tlsConn, ok := conn.(*tls.Conn)
  if ok {
    state := tlsConn.ConnectionState()
    fmt.Printf("Client certificate: %s\n", state.PeerCertificates[0].Subject.CommonName)
  }
  conn.Write([]byte("Mutual TLS connection accepted\n"))
}

Смотрите также

  • функцию tls.Dial,
    которая устанавливает TLS-соединение с сервером
  • структуру tls.Config,
    которая содержит настройки TLS-соединений
  • функцию tls.LoadX509KeyPair,
    которая загружает сертификат и ключ из файлов
  • структуру tls.Certificate,
    которая представляет X.509 сертификат