Hi Buds,
I faced an issue while calling upstream API having mTLS which is self-signed by the way, similar in tyk I have disabled insecure everything used Tyk OSS as well but as last I stuck at “http: proxy error: remote error: tls: bad certificate” but if I use curl it works, so I move to write a go program and got the same error “remote error: tls: bad certificate” it means there was an issue with go not tyk after google I found a link helped me to understand how to make my go program worked and finally it worked, please have a look into below details:
This is working curl command
curl --key cert.key --cert cert.crt -v https://mtls.example-url.com/api -k
This is go broken program
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
// Load the client certificate and private key
cert, err := tls.LoadX509KeyPair("cert.crt", "cert.key")
if err != nil {
log.Fatalf("Failed to load client certificate and key: %v", err)
}
// Load the CA certificate
caCert, err := ioutil.ReadFile("cert.crt")
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Create a CA certificate pool and add the CA certificate
caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
log.Fatalf("Failed to parse CA certificate")
}
// Create a TLS configuration with the client certificate and CA certificate pool
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
InsecureSkipVerify: true, // Skip verification for self-signed certs
}
// Create an HTTP client with the custom TLS configuration
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
// Make a request to the API
resp, err := client.Get("https://mtls.example-url.com/api")
if err != nil {
log.Fatalf("Failed to make request: %v", err)
}
defer resp.Body.Close()
// Read and print the response body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Failed to read response body: %v", err)
}
fmt.Println(string(body))
}
Output of this
Failed to make request: Get "https://mtls.example-url.com/api": remote error: tls: bad certificate
This is working go program by adding GetClientCertificate function
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
// Load the client certificate and private key
cert, err := tls.LoadX509KeyPair("cert.crt", "cert.key")
if err != nil {
log.Fatalf("Failed to load client certificate and key: %v", err)
}
// Load the CA certificate
caCert, err := ioutil.ReadFile("cert.crt")
if err != nil {
log.Fatalf("Failed to read CA certificate: %v", err)
}
// Create a CA certificate pool and add the CA certificate
caCertPool := x509.NewCertPool()
if ok := caCertPool.AppendCertsFromPEM(caCert); !ok {
log.Fatalf("Failed to parse CA certificate")
}
// Create a TLS configuration with the client certificate and CA certificate pool
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
InsecureSkipVerify: true, // Skip verification for self-signed certs
GetClientCertificate: func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
return &cert, nil
},
}
// Create an HTTP client with the custom TLS configuration
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
},
}
// Make a request to the API
resp, err := client.Get("https://mtls.example-url.com/api")
if err != nil {
log.Fatalf("Failed to make request: %v", err)
}
defer resp.Body.Close()
// Read and print the response body
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Failed to read response body: %v", err)
}
fmt.Println(string(body))
}
Output was the response from the API
Now can you please let me know how to make this work same for tyk as well ?
We are middle of nowhere now
Warm Regards,
Shebby