2015-03-06 31 views
5

Tworzę serwer Go TCP (NIE http // s) i próbuję skonfigurować go tak, aby korzystał z SSL. Mam darmowy certyfikat SSL StartCom, którego próbuję użyć, aby to osiągnąć. Mój kod serwera wygląda następująco:Konfiguracja certyfikatu gniazda SSL SSL Golang

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

Próbowałem przełączania wokół kolejności CERT, nie licząc niektórych CERT itp ale wyjście z openssl s_client -CApath /etc/ssl/certs/ -connect localhost:5555 pozostaje zasadniczo taki sam, verify error:num=20:unable to get local issuer certificate. Zobacz here dla pełnego wyjścia. Wydaje mi się, że robię coś złego w pośrednich certyfikatach, ale nie mam pojęcia co. Pracowałem nad tym przez kilka dni, dużo google i SO, ale nic nie pasowało do mojej sytuacji. Mam wiele certyfikatów w Apache i HAProxy, ale to naprawdę mnie zaskoczyło.

+0

Nie używaj "error" jako wartości błędu, ponieważ maskuje to wbudowaną nazwę interfejsu. – JimB

+0

Dziękuję, poprawię to! –

Odpowiedz

4

Pole RootCAs służy do weryfikacji certyfikatów serwera. Zakładam, że chcesz tylko przedstawić certyfikat do weryfikacji, więc wszystko, czego potrzebujesz, powinno zostać załadowane do plasterka Certificates.

Oto minimalne przykład:

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

Nawet jeśli nie używasz HTTPS, może nadal być przydatny do przejść przez konfiguracji serwera zaczynając http.ListenAndServeTLS.

+0

Czy certyfikat pośredni należy dodać do pliku example.com.pem? Czy jest on załadowany głównym certyfikatem? –

+0

@kkhugs: Nie mam certyfikatu wymagającego pośredniego pod ręką, ale jestem dość pewny, że powinieneś po prostu połączyć je z 'example.com.pem', tak jak na przykład w Nginx (docs say 'Certificates zawiera jeden lub więcej łańcuchów certyfikatów "). – JimB

+0

Dzięki, dodanie pliku pośredniego do pliku certyfikatu i użycie zgodnie z sugestiami działało idealnie! –

Powiązane problemy