2015-03-06 9 views
5

Я создаю сервер Go TCP (НЕ http/s), и я пытаюсь настроить его на использование SSL. У меня есть бесплатный сертификат SSL StartCom, который я пытаюсь использовать для этого. Мой код сервера выглядит следующим образом:Конфигурация сертификата сокета SSL Golang SSL TCP

cert, err := tls.LoadX509KeyPair("example.com.pem", "example.com.key") 
    if err != nil { 
     fmt.Println("Error loading certificate. ",err) 
    } 
    trustCert, err := ioutil.ReadFile("sub.class1.server.ca.pem") 
    if err != nil { 
     fmt.Println("Error loading trust certificate. ",err) 
    } 
    validationCert, err := ioutil.ReadFile("ca.pem") 
    if err != nil { 
     fmt.Println("Error loading validation certificate. ",err) 
    } 
    certs := x509.NewCertPool() 
    if !certs.AppendCertsFromPEM(validationCert) { 
     fmt.Println("Error installing validation certificate.") 
    } 
    if !certs.AppendCertsFromPEM(trustCert) { 
     fmt.Println("Error installing trust certificate.") 
    } 

    sslConfig := tls.Config{RootCAs: certs,Certificates: []tls.Certificate{cert}} 

    service := ":5555" 
    tcpAddr, error := net.ResolveTCPAddr("tcp", service) 
    if error != nil { 
     fmt.Println("Error: Could not resolve address") 
    } else { 
     netListen, error := tls.Listen(tcpAddr.Network(), tcpAddr.String(), &sslConfig) 
     if error != nil { 
      fmt.Println(error) 
     } else { 
      defer netListen.Close() 

      for { 
       fmt.Println("Waiting for clients") 
       connection, error := netListen.Accept() 

Я попытался переключения вокруг порядка, а не сертификаты, включая некоторые сертификаты и т.д., но на выходе из openssl s_client -CApath /etc/ssl/certs/ -connect localhost:5555 остается по существу то же, verify error:num=20:unable to get local issuer certificate. См. here для полного вывода. Кажется, я делаю что-то неправильно с промежуточными сертификатами, но я понятия не имею, что. Я работаю над этим в течение нескольких дней, много googling и SO'ing, но ничего, казалось, не соответствовало моей ситуации. Я установил много сертификатов в Apache и HAProxy, но это действительно меня озадачило.

+0

Не используйте 'error' как значение ошибки, так как это маскирует имя встроенного интерфейса. – JimB

+0

Спасибо, я исправлю это! –

ответ

4

Поле RootCAs предназначено для клиентов, которые проверяют сертификаты сервера. Я предполагаю, что вы только хотите представить сертификат для проверки, поэтому все, что вам нужно, должно быть загружено в срез Certificates.

Вот минимальный пример:

cert, err := tls.LoadX509KeyPair("example.com.pem", "example.com.key") 
if err != nil { 
    log.Fatal("Error loading certificate. ", err) 
} 

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

listener, err := tls.Listen("tcp4", "127.0.0.1:5555", tlsCfg) 
if err != nil { 
    log.Fatal(err) 
} 
defer listener.Close() 

for { 
    log.Println("Waiting for clients") 
    conn, err := listener.Accept() 
    if err != nil { 
     log.Fatal(err) 
    } 
    go handle(conn) 
} 

Даже если вы не используете HTTPS, он все еще может быть полезно пройти через настройки сервера, начиная с http.ListenAndServeTLS.

+0

Должен ли промежуточный сертификат быть добавлен в файл example.com.pem? Значит, он загружается с основным сертификатом? –

+0

@kkhugs: У меня нет сертификата, требующего промежуточной поддержки, но я вполне уверен, что вы должны просто связать их с вашим «example.com.pem», как, например, в nginx (docs say 'Certificates содержит одна или несколько цепей сертификатов'). – JimB

+0

Спасибо, добавив промежуточное звено в файл сертификата и используя, как было предложено, отлично! –