Proxy error: remote error: tls: handshake failure

Tyk logs shows “Proxy error: remote error: tls: handshake failure” after setting up Tyk gateway with docker-compose to use a certificate with the following config, I’m unable to debug what’s causing the tls handshake failure, any ideas on what could be missing from the config or how to get detailed logs to understand what’s causing the handshake failure?

All thoughts are greatly appreciated, thank you

tyk.conf
{
“listen_port”: 443,

“http_server_options”: {
“enable_websockets”: true,
“use_ssl”: true,
“ssl_insecure_skip_verify”: true,
“certificates”: [
{
“domain_name”: “apis.mysite.net”,
“cert_file”: “/opt/tyk-gateway/certs/apis_mysite_net.crt”,
“key_file”: “/opt/tyk-gateway/certs/apis_mysite_net.key”
}
]
},
“allow_insecure_configs”: true,
“log_level”: “debug”
}

my-api.json
{
“name”: “My API”,
“api_id”: “1”,
“org_id”: “default”,
“definition”: {
“location”: “header”,
“key”: “version”
},
“auth”: {
“auth_header_name”: “authorization”
},
“version_data”: {
“not_versioned”: true,
“versions”: {
“Default”: {
“name”: “Default”
}
}
},
“proxy”: {
“listen_path”: “/my-api/”,
“target_url”: “https://api.anothersite.com/vbws”,
“strip_listen_path”: true,
“service_discovery”: {
“use_discovery_service”: false
}
}
}
}

docker-compose.yml
version: ‘3.3’
services:
tyk-gateway:
image: [URL removed]v3.2.1
ports:
- 443:443
networks:
- tyk
volumes:
- ./tyk.standalone.conf:/opt/tyk-gateway/tyk.conf
- ./apps:/opt/tyk-gateway/apps
- ./middleware:/opt/tyk-gateway/middleware
- ./certs:/opt/tyk-gateway/certs
- ./policies:/opt/tyk-gateway/policies
depends_on:
- tyk-redis
tyk-redis:
image: redis:5.0-alpine
networks:
- tyk
ports:
- 6379:6379
networks:
tyk:

Hi @Ethan and welcome to the community!

You can find details of where Tyk stores it’s logs here: Log Data

Can you confirm where you are making the call from? i.e. client side. Your tyk.conf looks fine. We have seen this issue a few times where the client has the incorrect ciphers or won’t accept insecure connections itself. curl with the ‘-k’ switch might help to root out the issue.

Thanks, G.

Hi Gregor,

  • I’m running Tyk using docker-compose, used this repo GitHub - TykTechnologies/tyk-gateway-docker: Official docker build for Tyk
  • I’m making the call from a server on a private network (origin, where Tyk is installed) to another server in the same network
  • The target server (defined in target_url) accepts requests only with https/SSL, won’t accept http requests without SSL and the request should come from a whitelisted domain, in this case it’s the one defined in the domain_name

Regarding the log data, I’m using the docker-compose image for the Tyk Gateway only (not sure if that’s makes a difference in the logging level), and enabled the “log_level”: “debug” in the API, with that I’m only seeing the following line in the log, which doesn’t tell much:

tyk-gateway_1 | time=“Jun 07 09:35:17” level=error msg=“http: proxy error: remote error: tls: handshake failure” api_id=1 api_name=“My API” mw=ReverseProxy org_id=default prefix=proxy server_name=api.anothersite.com user_id="****17c5" user_ip=172.10.0.1 user_name=

One thing which I’m not sure if it has to do with this:

I’ve tested the Keyless API example which comes with the repo, the following curl shows that the “origin” is set to the server IP rather than the domain name which I’ve defined in the API .json file as the “domain_name”. The target server checks this origin name field probably and disqualifies if the value is not the expected domain name apis.mysite.net, how can I force Tyk to set the origin value properly in the outgoing requests?

curl https://apis.mysite.net/keyless-test/get
{
“args”: {},
“headers”: {
“Accept”: “/”,
“Accept-Encoding”: “gzip”,
“Custom-Header”: “hello world”,
“Custom-Uid”: “1e2ea02f-c31a-46f8-a036-f63a9680668b”,
“Host”: “httpbin.org”,
“User-Agent”: “curl/7.29.0”,
“X-Amzn-Trace-Id”: “Root=1-60bde6a2-76ff3003707bd9a304fa750a”
},
“origin”: “172.10.0.1”,
“url”: “https://httpbin.org/get
}

I think the error is being generated by the gateway not accepting the upstream self-signed cert.

try:
You can set proxy.transport.ssl_insecure_skip_verify in an API definition to allow Tyk to an insecure HTTPS/TLS API Upstream.
https://tyk.io/docs/basic-config-and-security/security/tls-and-ssl/#api-level

I have tried that, same error.

Note that the cert is not self signed but is issued by Gandi Standard SSL CA 2

Also considering that the second API, “keyless-test” is working fine while using the same exact cert when communicating with https://httpbin.org, doesn’t that mean Tyk is using the cert properly?

Is there’s a way to get deeper logs for the following error to help understanding at which step in the handshake things are failing?

error msg=“http: proxy error: remote error: tls: handshake failure”

Unless you are trying to implement MaTLS then only the cert of the upstream service will be in scope so the https://httpbin.org cert is a different cert from a different issuing authority.
If it is a legitimate cert and not self signed then the ssl_insecure_skip_verify won’t make any difference.

You may need to explicitly define which ciphers to use as per here: TLS and SSL
or use server elected ciphers:
{
“http_server_options”: {
“prefer_server_ciphers”: true
}
}

I have tried all the possible cipher values, same error.

Is there’s a way to get deeper logs for the following error to help understanding at which step in the handshake things are failing?

An update on this issue:
It turned out to be that the target server “target_url” was rejecting traffic from the source API server, whitelisting it made things work.

Hi @Ethan,
Thanks for letting us know. As an FYI I’m still digging into your request to make sure we have a way to get deeper visibility of the logs in these scenarios as I’m sure that would have pointed the issue out quicker.

Thanks, G.

Yes, deeper level logs would be would be super helpful, thank you!