2014-05-06 4 views
9

Il seguente è il mio TLS backend:Golang ListenAndServeTLS restituisce i dati quando non si usa https nel browser

package main 

import (
    "fmt" 
    "net/http" 
) 

const (
    PORT  = ":8443" 
    PRIV_KEY = "./private_key" 
    PUBLIC_KEY = "./public_key" 
) 

func rootHander(w http.ResponseWriter, r *http.Request) { 
    fmt.Fprint(w, "Nobody should read this.") 
} 

func main() { 
    http.HandleFunc("/", rootHander) 
    err := http.ListenAndServeTLS(PORT, PUBLIC_KEY, PRIV_KEY, nil) 
    if err != nil { 
     fmt.Printf("main(): %s\n", err) 
    } 
} 

Le chiavi vengono generati utilizzando queste due righe:

openssl genrsa -out private_key 2048 
openssl req -new -x509 -key private_key -out public_key -days 365 

Quando ho avviare il server TLS e visitare il sito con un browser (https://example.com:8443) Ottengo il risultato previsto, dopo ignorando il messaggio di avviso del browser:

Nobody should read this. 

Finora tutto è bello.

Ora, quando indico il mio browser per http://example.com:8443 (notare che http viene utilizzato, non https) ottengo il seguente risultato Firfox (Chrome fa lo stesso, ma il download del sito):

using http

Domanda: Perché c'è un punto interrogativo?

+0

funziona https://groups.google.com/forum/#!topic/golang-nuts/ZtP5vPPeyHE anche per te ? – ddevienne

risposta

9

Se si reindirizza l'output in od, curl -k -3 http://localhost:8443 | od -A n -t x1, si ottiene la seguente sequenza di byte 15 03 01 00 02 02 0a che è reso/maneggiato dal browser.

Quale, secondo https://code.google.com/p/go/issues/detail?id=2253, è TLS per "Non ho capito cosa hai detto".

+2

Quindi, è di progettazione. Se voglio consentire solo https, dovrei reindirizzare, giusto? – Kiril

+0

@Kiril Esiste già una soluzione per questo problema? Cosa intendi con "reindirizzamento"? – codepushr

+0

Questo è in realtà un comportamento previsto. Puoi controllare https://golang.org/pkg/net/http/#Request (TLS) per sapere se una richiesta sta usando http o https. – Kiril

4

Se a tutto ancora relevent:

http.ListenAndServeTLS(...) prende certificato e chiave privata non pubblico & chiave privata.

+0

Grazie per il chiarimento. Quindi ho creato un certificato con una chiave privata corrispondente? – Kiril

+1

Sì.Hai creato un certificato con una chiave privata. Hai appena chiamato il cert "public_key". Di solito è più simile a questo: '-out cert.pem'. – SunSparc

1

Ecco un codice per reindirizzare le richieste dalla porta 80 alla 443 e per servire i certificati tls utilizzando una CA come consente di crittografare. So che con consente di crittografare (letsencrypt.org) si desidera fare riferimento al file fullchain.pem risultante nonché al privkey.pem.

Il problema più grande dell'auto firma è che non sarà molto redditizio in produzione. Con golang configuriamo le nostre applicazioni in modo abbastanza specifico, quindi qualcosa di semplice come allegare correttamente i certificati tls è un argomento importante quando siamo pronti per il lancio.

qui alcune semplici righe di codice che ho effettivamente utilizzato per lanciare un sito statico:

package main 
import (
"net/http" 
"log" 
) 
func redirect(w http.ResponseWriter, req *http.Request) { 
// remove/add not default ports from req.Host 
target := "https://" + req.Host + req.URL.Path 
if len(req.URL.RawQuery) > 0 { 
    target += "?" + req.URL.RawQuery 
} 
log.Printf("redirect to: %s", target) 
http.Redirect(w, req, target, 
     http.StatusTemporaryRedirect) 
} 


func main() { 
//define a variable for the FileServer directory in this case ./static/ 
var fs = http.FileServer(http.Dir("static")) 
//express the handler function 
http.Handle("/", fs) 
//We should redirect requests on port 80 
go http.ListenAndServe(":80", http.HandlerFunc(redirect)) 
//finally we Listen for requests and serve them up on a specific port 
http.ListenAndServeTLS(":443", "fullchain.pem", "privkey.pem", nil) 

} 
Problemi correlati