What is Virtual Hosting, and how does it work?
Short answer
Virtual Hosting allows more than one HTTP vService to share the same IP:port. Each vService is given its own domain names; TR7 looks at the domain name of the incoming request (in HTTPS, the SNI in the TLS handshake; in unencrypted traffic, the Host Header) and sends the request to the vService that carries that domain name in its list. In this way, many sites, each with its own certificate, WAF and Backend Services, are published from a single public IP. If a wildcard certificate is used in the shared vServices, SNI/Host Validation in the TLS Security Profile is turned on to prevent requests from landing on the wrong vService.
How Does It Work?
- Shared address: The Virtual Hosting list is filled in all the vServices that share the IP:port; TR7 looks at the domain name before forwarding a connection arriving at this IP:port to one of the vServices.
- The domain name is looked at: In HTTPS, the SNI that the client sends in the handshake is read before TLS is opened. In unencrypted traffic, the Host header of the request is read.
- It is forwarded to the related vService: The connection is forwarded to whichever vService has the domain name in its list; the real client IP is preserved.
- The vService terminates TLS: In HTTPS, the certificate is presented from the Certificate field of the selected vService; each site uses its own certificate. All further processing of the request (WAF, actions, Backend Service selection) is done with that vService's settings.
Rules
| Rule | Description |
|---|---|
| HTTP only | Virtual Hosting exists only in the HTTP vService; it does not exist in L7 TCP and Network. |
| The shared IP is added first | The shared IP is added to an interface under Network → Interfaces before the vServices. |
| Every list is filled | The domain name list must be filled in all the vServices that share the IP:port; a vService with an empty list cannot be defined on the same IP:port. |
| Same encryption class | HTTPS (HTTP/1.1, HTTP/2) and unencrypted (HTTP, HTTP → HTTPS) rows cannot share the same IP:port. |
| Exact match | A domain name (including wildcard), an IP address or a value with a port added (a.example.com:8080) is written to the list; an entry without a wildcard is compared exactly with the incoming value. The comparison is case-sensitive, so domain names are written in lowercase. In unencrypted traffic, on ports other than 80, the Host Header also contains the port number; on these ports, the domain name is written to the list together with the port (a.example.com:8080). In HTTPS, the SNI does not contain the port, and only the domain name is written to the list. |
| Wildcard | *.example.com is supported and matches more than one subdomain level; it does not match example.com itself. |
| Unmatched request | An unencrypted request receives 503; in HTTPS, if the SNI does not match or the client sends no SNI, the connection is closed. |
| HTTP/3 | In a vService whose list is filled, protocols with the HTTP/3 badge are not offered. |
Use with SNI/Host Validation
In Virtual Hosting, the vService is selected according to the SNI at the start of the connection. If a wildcard certificate (*.example.com) covers the domain names of more than one vService, the browser can also use the HTTP/2 connection it opened for one domain name for another domain name covered by the same certificate (connection coalescing). In this case, the request for the second domain name goes to the vService that the first connection reached.
To prevent this, SNI/Host Validation is turned on in the TLS Security Profile selected in the SSL Security field of the vServices (Certificates & PKI → TLS Security Profiles → profile → Frontend-only Settings; it is off by default). While it is on, the SNI in TLS is compared with the Host Header of the request (port and case are not taken into account); if they do not match, the request is rejected with 421 Misdirected Request, and the browser opens a new connection for the right domain name. The setting is effective only in HTTP vServices; if the client has not sent an SNI, no comparison is made. Details: Can I reject requests whose SNI and Host Header do not match (domain fronting) (SNI/Host Validation)?
In TR7
- In the vService form, the Virtual Hosting switch is turned on and the domain names are written to the list; when the switch is turned off, the list is emptied.
- vServices with Virtual Hosting defined appear in the list with the cloud icon in the Type cell; when the pointer is moved over the icon, the domain names are listed.
Common Misconceptions
- "Virtual Hosting and Content Switching are the same thing." Virtual Hosting selects between separate vServices; Conditional Backend Services (Content Switching) selects different Backend Services within a single vService according to conditions.
- "The layer that looks at the domain name opens TLS." In HTTPS, only the SNI is read; the selected vService terminates TLS with its own certificate.
- "Unmatched requests go to a default site." There is no default (catch-all) site option; an unmatched request receives 503 or its connection is closed.
- "The most specific match wins." If two vServices match the same domain name, TR7 does not give priority to the exact match: Can I do Virtual Hosting with a wildcard domain (*.example.com)?
How it is done in the documentation
Related questions
