Reputation: 508
I'm trying to secure connection between AWS API Gateway and my API endpoint services exactly as it is described int his documentation: http://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html
AFAIK I need to copy the cert form AWS API Gateway and use http.ListenAndServeTLS
method. But it accepts two files: keyFile and certFile
func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler)
.
When I click on copy link (see image below)
the only thing I get is the certificate in such format (I've shortened it for explanation purposes):
-----BEGIN CERTIFICATE-----
MIIC6TCCAdGgAwIBAgIJAKbyiCf2f5J2MA0GCSqGSIb3DQEBCwUAMDQxCzAJBgNV
fYe+dxR0PMFvfUpZaGgaY1ykQG1sNaw/b6NjNg9c1aEVSZ7b1eU/cBmb6XqHw0Ih
7yHtBm+p8Px4NMAT9YhytTxPRBYpApfUsfPMa3qfUWvvj4TD0LR6bW980bebyxUn
BigXToSFlPeiNGdU/Zpiw9crzplojNBFc=
-----END CERTIFICATE-----
So my question is, how exactly I need to configure ListenAndServeTLS
method to make sure the any request to my service is from API Gateway? Where I can find private key? It's quite confusing for me.
Upvotes: 1
Views: 1716
Reputation: 1728
The client certificate AWS is given you is for authenticating the client that send requests to your service, which is the AWS gateway.
This cert is not to be used to start your server, but to authenticates requests.
See an example of use below, untested code, but as a lead.
func Hello(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "hello, world!\n")
}
func main() {
http.HandleFunc("/hello", Hello)
certBytes, err := ioutil.ReadFile("aws-gateway.pem")
if err != nil {
log.Fatal(err)
}
block, certBytes := pem.Decode(certBytes)
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
log.Fatal(err)
}
clientCertPool := x509.NewCertPool()
clientCertPool.AddCerts(cert)
tlsConfig := &tls.Config{
ClientCAs: clientCertPool,
// NoClientCert
// RequestClientCert
// RequireAnyClientCert
// VerifyClientCertIfGiven
// RequireAndVerifyClientCert
ClientAuth: tls.RequireAndVerifyClientCert,
}
tlsConfig.BuildNameToCertificate()
server := &http.Server{
Addr: ":8080",
TLSConfig: tlsConfig,
}
server.ListenAndServeTLS("server.crt", "server.key")
}
This way, your service will require that all requests provide a certificate and will verify it against the pool of ClientCA. You could, of course, add more certificates to the client pool if desired.
Upvotes: 3