2015-03-06 12 views
5

Bir Go TCP sunucusu (http/s) oluşturuyorum ve SSL kullanacak şekilde yapılandırmaya çalışıyorum. Bunu gerçekleştirmek için kullanmaya çalıştığım bir StartCom ücretsiz SSL sertifikası var. Benim sunucu kodu şöyle görünür: Ben vs. bazı certs fakat openssl s_client -CApath /etc/ssl/certs/ -connect localhost:5555 den çıkış içermeyen certs, sırasına etrafında anahtarlama denedimGolang SSL TCP soket sertifika yapılandırması

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() 

temelde aynı, verify error:num=20:unable to get local issuer certificate kalır. Tam çıkış için bkz. here. Ara sertifikalarla yanlış bir şeyler yapıyorum gibi görünüyor, ama hiçbir fikrim yok. Birkaç günlüğüne bu konuda çalışıyorum, bir sürü googling ve SO'ing, ama hiçbir şey benim durumuma tam olarak uymuyor gibiydi. Apache ve HAProxy'de birçok sertifika kurdum, ama bu gerçekten beni güldürdü.

+0

Hata kodunu, hata kodu olarak kullanmayın, çünkü bu, yerleşik arabirim adını maskeler. – JimB

+0

Teşekkür ederim, bunu düzeltirim! –

cevap

4

RootCAs alan sunucu sertifikaları doğrulamak müşteriler içindir. Sadece doğrulama için bir sertifika sunmak istediğinizi varsayalım, bu nedenle ihtiyacınız olan her şey Certificates dilimine yüklenmelidir. İşte

minimal örnektir:

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 kullanılarak değiliz rağmen, hala http.ListenAndServeTLS başlayan sunucu kurulumu yürümeye yararlı olabilir.

+0

Ara sertifika example.com.pem dosyasına eklenmeli mi o zaman? Yani ana sertifika ile yüklü? –

+0

@kkhugs: Kullanışlı bir araca ihtiyaç duyan bir sertifikam yok, ama nginx'in örneğinde olduğu gibi onları example1.pem'e zincirlemelisiniz diye kesin olarak eminim (docs 'Sertifikalar içeriyor Bir veya daha fazla sertifika zinciri '). – JimB

+0

Teşekkürler, ara dosyayı cert dosyasına ekleyerek ve önerilen şekilde kullanıldıkça mükemmel çalıştı! –