Case Study Bloom Credit: Multi-Provider API Security with KrakenD

You are viewing a previous version of KrakenD Enterprise Edition (v2.4), go to the latest version

Document updated on Sep 26, 2023

Virtual Hosts

The Virtual Host server allows you to run different configurations of KrakenD endpoints based on the host accessing the server.

For instance, you can declare an endpoint /foo that behaves entirely differently when KrakenD is accessed through a host-a.tld or a host-b.tld. For instance, the same /foo path can have different rate limits or authorization endpoints depending on the called host.

Virtual host configuration

To add virtual hosts, add the component server/virtualhost under the service extra_config, as depicted below:

{
    "version": 3,
    "extra_config": {
        "server/virtualhost": {
           "hosts": ["host-a.tld", "host-b.tld"]
        }
    }
}
Fields of "server/virtualhost"
* required fields

hosts * array
All recognized virtual hosts by KrakenD must be listed here. The values declared here must match the content of the Host header when passed by the client.
Example: ["api-a.host.com","api-b.host.com"]

Declaring endpoints

When you enable the virtual host plugin, all requests to KrakenD (/{path}) that match with a recognized host in the list are rewritten internally to /__virtual/{host}/{path}.

Any request to a host that is not declared in the list does not have this redirection.

Virtual host example

Given the following extra_config configuration:

{
    "extra_config": {
        "server/virtualhost": {
            "hosts": [
                "host-a.yourserver.com",
                "host-b.yourserver.com"
            ]
        }
    }
}

And the following endpoints:

{
  "version": 3,
  "endpoints": [
    {
      "endpoint": "/foo",
      "backend": [
        {
          "url_pattern": "/__debug/no-host",
          "host": ["http://localhost:8080"]
        }
      ]
    },
    {
      "endpoint": "/__virtual/host-a.yourserver.com/foo",
      "backend": [
        {
          "url_pattern": "/__debug/host-A",
          "host": ["http://localhost:8080"]
        }
      ]
    },
    {
      "endpoint": "/__virtual/host-b.yourserver.com/foo",
      "backend": [
        {
          "url_pattern": "/__debug/host-B",
          "host": ["http://localhost:8080"]
        }
      ]
    }
  ]
}

You can check how /foo hits different endpoints in the following order:

  • curl -i -H 'Host: anything' http://localhost:8080/foo: No rewriting placed as host is unknown. Hits the first endpoint.
  • curl -i -H 'Host: host-a.yourserver.com' http://localhost:8080/foo: Hits the second endpoint
  • curl -i -H 'Host: host-b.yourserver.com' http://localhost:8080/foo: Hits the third endpoint

Using host headers with port

Although it is not frequent, sometimes the Host header might also contain the port. For instance, Host: host-a.tld:1234. When the header contains the port, you must add it as a different entry in the virtual host configuration and the endpoint definition.

The following example supports Host headers with values Host: host-a.tld:1234 and Host: host-a.tld:

{
    "$schema": "https://www.krakend.io/schema/v2.4/krakend.json",
    "version": 3,
    "echo_endpoint": true,
    "host": ["http://localhost:8080"],
    "extra_config": {
        "server/virtualhost": {
            "hosts": ["host-a.tld:1234","host-a.tld"]
        }
    },
    "endpoints": [
        {
            "endpoint": "/default",
            "backend": [{
                "url_pattern": "/__echo/any-non-matching-host",
                "allow": ["req_uri"]
            }]
        },
        {
            "endpoint": "/__virtual/host-a.tld/default",
            "backend": [{
                "url_pattern": "/__echo/virtualhost-without-port",
                "allow": ["req_uri"]
            }]
        },
        {
            "endpoint": "/__virtual/host-a.tld:1234/default",
            "backend": [{
                "url_pattern": "/__echo/virtualhost-with-port",
                "allow": ["req_uri"]
            }]
        }
    ]
}

Upgrading from the old virtual host plugin (before v2.4)

If you used the static plugin before EE v2.4, eliminate now all entries referring to plugins. This means:

  • If you don’t use additional plugins, you can get rid of the plugin entry in the root level.
  • You can delete all plugin/http-server objects if they only use the static-filesystem
  • You can delete any virtualhost object in the configuration

This can be summarized with a diff as:

  "version": 3,
-  "plugin": {
-     "pattern":".so",
-     "folder": "/opt/krakend/plugins/"
-  },
  "extra_config": {
-    "plugin/http-server": {
-      "name": ["virtualhost"],
-      "virtualhost": {
+    "server/virtualhost": {

For instance, if you had this configuration:

{
    "version": 3,
    "plugin": {
        "pattern":".so",
        "folder": "/opt/krakend/plugins/"
    },
    "extra_config": {
        "plugin/http-server": {
            "name": ["virtualhost", "some-other-plugin" ],
            "virtualhost": {
                "hosts": ["host-a.tld", "host-b.tld"]
            }
        }
    }
}

This now becomes:

{
    "version": 3,
    "extra_config": {
        "server/virtualhost": {
            "hosts": ["host-a.tld", "host-b.tld"]
        }
    }
}

No additional changes are required in the endpoints.

Scarf

Unresolved issues?

The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.

See all support channels