Overriding Host Header not working

Hi,

When I try to override the Host of the upstream using Endpoint designer on dashboard, it seems to have no effect.

Our upstream API requires us to set a Host to specific value, but we’re trying to bypass the regular networking stack and go directly via a private IP, and therefore are trying to set the Host manually.

1 Like

Hi Boris

Can you share your API definition please so I can see how you have the API configured.

Thanks
Josh

Hey Josh,

See below TiA (I replaced the actual URLs)

{
“id”: “5a84a68a6e61b7259bf193ff”,
“name”: “My API”,
“slug”: “my-api”,
“api_id”: “536d9b890c2740a950df97c89ac5866b”,
“org_id”: “5a849bce6e61b73ff3ec4825”,
“use_keyless”: true,
“use_oauth2”: false,
“use_openid”: false,
“openid_options”: {
“providers”: [],
“segregate_by_client”: false
},
“oauth_meta”: {
“allowed_access_types”: [],
“allowed_authorize_types”: [],
“auth_login_redirect”: “”
},
“auth”: {
“use_param”: false,
“param_name”: “”,
“use_cookie”: false,
“cookie_name”: “”,
“auth_header_name”: “”,
“use_certificate”: false
},
“use_basic_auth”: false,
“use_mutual_tls_auth”: false,
“client_certificates”: [],
“upstream_certificates”: {
“my certificate”: “5a849bce6e61b73ff3ec4825b81dd9248f42d24356d7fc90872c0fc987253d5065d285d150a9ebb96227cf06”
},
“enable_jwt”: false,
“use_standard_auth”: false,
“enable_coprocess_auth”: false,
“jwt_signing_method”: “”,
“jwt_source”: “”,
“jwt_identity_base_field”: “”,
“jwt_client_base_field”: “”,
“jwt_policy_field_name”: “”,
“notifications”: {
“shared_secret”: “”,
“oauth_on_keychange_url”: “”
},
“enable_signature_checking”: false,
“hmac_allowed_clock_skew”: -1,
“base_identity_provided_by”: “”,
“definition”: {
“location”: “header”,
“key”: “x-api-version”
},
“version_data”: {
“not_versioned”: true,
“default_version”: “”,
“versions”: {
“Default”: {
“name”: “Default”,
“expires”: “”,
“paths”: {
“ignored”: [],
“white_list”: [],
“black_list”: []
},
“use_extended_paths”: true,
“extended_paths”: {},
“global_headers”: {
“Host”: “www.myurl.com
},
“global_headers_remove”: [
“Host”
],
“global_size_limit”: 0,
“override_target”: “”
}
}
},
“uptime_tests”: {
“check_list”: [
{
“url”: “myURL”,
“method”: “GET”,
“headers”: {},
“body”: “”
}
],
“config”: {
“expire_utime_after”: 0,
“service_discovery”: {
“use_discovery_service”: false,
“query_endpoint”: “”,
“use_nested_query”: false,
“parent_data_path”: “”,
“data_path”: “”,
“port_data_path”: “”,
“target_path”: “”,
“use_target_list”: false,
“cache_timeout”: 60,
“endpoint_returns_list”: false
},
“recheck_wait”: 0
}
},
“proxy”: {
“preserve_host_header”: false,
“listen_path”: “/my-api/”,
“target_url”: “https://172.200.1.140”,
“strip_listen_path”: true,
“enable_load_balancing”: false,
“target_list”: [],
“check_host_against_uptime_tests”: true,
“service_discovery”: {
“use_discovery_service”: false,
“query_endpoint”: “”,
“use_nested_query”: false,
“parent_data_path”: “”,
“data_path”: “”,
“port_data_path”: “”,
“target_path”: “”,
“use_target_list”: false,
“cache_timeout”: 0,
“endpoint_returns_list”: false
}
},
“disable_rate_limit”: true,
“disable_quota”: true,
“custom_middleware”: {
“pre”: [],
“post”: [],
“post_key_auth”: [],
“auth_check”: {
“name”: “”,
“path”: “”,
“require_session”: false
},
“response”: [],
“driver”: “”,
“id_extractor”: {
“extract_from”: “”,
“extract_with”: “”,
“extractor_config”: {}
}
},
“custom_middleware_bundle”: “”,
“cache_options”: {
“cache_timeout”: 60,
“enable_cache”: true,
“cache_all_safe_requests”: true,
“cache_response_codes”: [],
“enable_upstream_cache_control”: false,
“cache_control_ttl_header”: “”
},
“session_lifetime”: 0,
“active”: true,
“auth_provider”: {
“name”: “”,
“storage_engine”: “”,
“meta”: {}
},
“session_provider”: {
“name”: “”,
“storage_engine”: “”,
“meta”: {}
},
“event_handlers”: {
“events”: {}
},
“enable_batch_request_support”: false,
“enable_ip_whitelisting”: false,
“allowed_ips”: [],
“dont_set_quota_on_create”: false,
“expire_analytics_after”: 0,
“response_processors”: [],
“CORS”: {
“enable”: false,
“allowed_origins”: [],
“allowed_methods”: [],
“allowed_headers”: [],
“exposed_headers”: [],
“allow_credentials”: false,
“max_age”: 24,
“options_passthrough”: false,
“debug”: false
},
“domain”: “”,
“do_not_track”: false,
“tags”: [],
“enable_context_vars”: false,
“config_data”: {},
“tag_headers”: [],
“global_rate_limit”: {
“rate”: 0,
“per”: 0
},
“strip_auth_data”: true
}

"preserve_host_header": false should be switched to true

Tried that.

The Host of the API gateway is still getting sent (not replacing with my custom Host header)

Anyone has any ideas on how to do this?

You could try w/ url rewriter, to mutate the target to proxy to, but there are a few outstanding issues:

I don’t think the “global headers” way you are attempting is the way to do it.

Will the Host of Target URL be passed if the entire URL is rewritten ?

It seems the new URL is being used for Host, not the target name

To clarify: the upstream expects a specific Host to serve the proper request, however we route the API locally (172.x.x.x), but it seems that without the proper Host the upstream refuses to serve proper request.

The way we do it is: (this only works as of 2.5.2+)

a) Create a custom JSVM pre-middleware plugin that analyzes anything you want from the current request (Host, path, url etc)

b) In that plugin, set any number of custom http request headers based off what you analyze (i.e. the new target url to proxy to, the original fqdn host requested…whatever you want)

c) then via an URL rewriter do something like

                    "url_rewrites": [
                        {
                            "path": "/.*",
                            "method": "POST",
                            "match_pattern": "/.*",
                            "rewrite_to": "$tyk_context.headers_X_My_Customproxytourl",
                            "triggers": []
                        }
                    ],

The endpoint you are proxying to, would be able to see all the headers you set in your jsvm plugin as well

I just realized there can be a bit easier solution to this issue.

$tyk_context contains headers_Host value already, so maybe you can do it without middleware like this:

   "url_rewrites": [
                        {
                            "path": "/.*",
                            "method": "POST",
                            "match_pattern": "/(.*)",
                            "rewrite_to": "$tyk_context.headers_Host/$1",
                            "triggers": []
                        }
                    ],

@boris Did you figure a solution out? I am in the same situation where the endpoint is invoked via abcd.com FQDN, but the application will work only if Host header is set to xyz.com.