Isolate incoming application requests with virtual hosts
A virtual host is a configuration entity that enables a single server to host multiple domain name and port configurations. You can configure virtual hosts on your Open Liberty server to isolate incoming application requests from each other and from administrative traffic, such as metrics and JMX communications.
For example, your company might maintain two applications on the same server, one for customers and another for employees. By using virtual hosts, you can specify different hostname and port number configurations for each application. You can also specify aliases for each host so that the customer application is accessed from the customer.example.com
URL and the employee application is accessed from the employee.example.com
URL. Although the two applications run on the same server and share many of the same configuration resources, incoming requests for each application are isolated from the other. Inbound requests that are associated with one virtual host cannot access applications that are associated with any other virtual host, even if those other virtual hosts share a physical machine.
You can also configure a dedicated virtual host for your application to keep incoming application requests isolated from administrative traffic, such as metrics and JMX communications, which are handled by the default virtual host.
Virtual host aliases
Each virtual host has an ID value and a list of one or more host aliases by which it is known. A host alias is the TCP/IP hostname and port number combination that is used to request a resource, for example, yourHostName:80
. When no port number is specified, the default is port number is 80
.
The virtual host configuration accepts a wildcard value (*
) for the hostname in virtual host alias configurations. You can use wildcard entries for aliases by port to specify that all valid hostname and address combinations on a particular port map to a particular virtual host. However, wildcard hostname values are not recommended for security-hardened production environments. For more information, see Virtual hosts and application security in production environments.
The default alias for a virtual host is *:80
, which uses an external port that is not secure. This default is used for any virtual hosts that do not specify an alias configuration, including the default_host
default virtual host.
The configuration of a virtual host alias determines whether a virtual host uses secure ports, and whether the ports are internal or external:
Aliases of the form
*:9080
use the internal port that is not secure.Aliases of the form
*:9443
use the secure internal port.Aliases of the form
*:443
use the secure external port.
If a request specifies a resource by using an alias that cannot be mapped to an alias of a defined virtual host, the result is a 404 error.
The default virtual host
Open Liberty provides one default virtual host that is called default_host
, which is automatically configured the first time that you start your server. Unless you specifically want to isolate resources on the same server from one another, you probably do not need any virtual hosts other than the default virtual host. However, the default virtual host is also used for JMX communications and other metrics processes. To separate this traffic from incoming requests to an application, you can configure another virtual host for the application.
The host aliases for the default virtual host are configured as *:80
and *:9080
, where port 80
is the HTTP server port and port 9080
is the port for HTTP transport. The default virtual host includes common aliases, such as the machine IP address, short hostname, and fully qualified hostname. One of these aliases comprises the first part of the path for accessing a resource, such as a servlet. For example, the localhost:80
alias is used in the http://localhost:80/myServlet
request.
Virtual hosts and application security in production environments
As part of hardening your network security configuration, you can use virtual hosts to restrict incoming requests to your applications. To keep Open Liberty administrative traffic separate from application requests, configure applications to run on a virtual host other than the default host for the server. Furthermore, the best practice for security-hardened production environments is to avoid wildcard values (*
) in alias hostnames. Rather than using wildcards, alias hostname values must match only the specific hosts that administrators expect a server to handle. For more information, see Network security hardening: Virtual hosts.
Virtual host configuration
In Open Liberty, you can define virtual hosts or adjust the configuration of the default virtual host by specifying attributes for the virtualHost configuration element in your server.xml
file.
Isolate applications on the same server
The following example illustrates a common use case for virtual hosting: configuring two applications to run on different ports on the same server. The configuration defines two HTTP endpoints and two virtual hosts. The alias configurations associate the application-1
virtual host with the defaultHttpEndpoint
endpoint and the application-2
virtual host with the alternateEndpoint
endpoint:
<httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9080" />
<httpEndpoint id="alternateEndpoint" host="*" httpPort="9081" />
<virtualHost id="application-1">
<hostAlias>example_host:9080</hostAlias>
</virtualHost>
<virtualHost id="application-2">
<hostAlias>localhost:9081</hostAlias>
</virtualHost>
<enterpriseApplication location="myApp.ear" name="App1"/>
<webApplication location="myApp2.war" name="App2" />
Furthermore, the virtual host configuration for the application-2
virtual host specifies that an application on this host is available only on the localhost
interface. This configuration is useful if you want an application to accept traffic only from the computer where it is running, for development or testing purposes.
The defaultHttpEndpoint
HTTP endpoint is configured to expose all interfaces on port 9080
. The alternateEndpoint
HTTP endpoint is configured to expose all interfaces on port 9081. If the App1
application has a WAR file with an ibm-web-bnd.xml
file that specifies virtual-host name="application-1"
, then this application can be accessed only at the your_host_name:9080/app1_context_root
endpoint. If the App2
application that is configured in the webApplication
element has an ibm-web-bnd.xml
file that specifies virtual-host name="application-2"
, then this application can be accessed only at the localhost:9081/app2_context_root
endpoint.
If a third application that doesn’t specify a virtual host is deployed on the same server, it is accessible by a proxied request that maps to the default virtual host. For example, port 80
is not defined by any of the hostAlias
attributes. If a request is made to a proxy on that port, it is routed to the default_host
virtual host.
Isolate applications based on the requested host or port
The default virtual host in Open Liberty, default_host
, is used for administrative traffic, such as JMX communications. To isolate incoming application requests from administrative traffic, you can configure a separate virtual host for your application.
The following example illustrates a virtualHost
element and hostAlias
attribute configuration in the server.xml
file:
<virtualHost id="proxiedRequests">
<hostAlias>external.host.name:80</hostAlias>
<hostAlias>external.host.name:443</hostAlias>
</virtualHost>
If requests are coming from a proxy, this configuration routes any request that is made to the proxy host and port to the "proxiedRequests" virtual host.
To associate your application with this virtual host, you must add a reference to it in the application code. Add a virtual-host
element to the ibm-web-bnd.xml
or ibm-web-bnd.xmi
file of the application WAR
file, as shown in the following example:
<?xml version="1.0" encoding="UTF-8"?>
<web-bnd
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xmk/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0" />
<virtual-host name="proxiedRequests" />
</web-bnd>
Restrict access to an application based on the originating endpoint
To restrict access to system applications that are using the defaultHttpEndpoint
HTTP endpoint, you can define a new endpoint and specify the allowFromEndpointRef
attribute in your virtual host configuration. When this attribute is specified, a virtual host accepts requests only from the specified endpoint. While virtual host aliases can filter requests based on the Host
HTTP header, the allowFromEndpointRef
attribute can specify a constraint at the system network interface layer.
In the following example, the localHostOnly
HTTP endpoint specifies that ports 9081
and 9444
are exposed only on the localhost
interface. The default_host
is restricted to this endpoint by the allowFromEndpointRef
attribute:
<httpEndpoint id="localHostOnly" host="localhost" httpPort="9081" httpsPort="9444"/>
<virtualHost id="default_host" allowFromEndpointRef="localHostOnly">
<hostAlias>*:9081</hostAlias>
<hostAlias>*:9444</hostAlias>
</virtualHost>
</virtualHost id="proxiedRequests">
<hostAlias>*:9080</hostAlias>
<hostAlias>*:9443</hostAlias>
<hostAlias>external.host.name:80</hostAlias>
<hostAlias>external.host.name:443</hostAlias>
</virtualHost>
With this configuration, the default_host
virtual host now accepts requests that are directed only at localhost:9081
and localhost:9444
that also originate from the localHostOnly
endpoint. Any other request to ports 9081
and 9444
are refused. For example, a request from the defaultHttpEndpoint
with Host
headers that reference localhost:9081
is refused.
The proxiedRequests
virtual host accepts any request to port 9080
or 9443
, which are the ports that are used by the defaultHttpEndpoint
HTTP endpoint. It also accepts requests that have a host header that references the external hostname from the proxy and port 80
or 443
.