Do servers hold one website only


As from what I understand the DNS link the domain name with the IP address of the server the website is stored on, does that mean each server can only hold one website? If they don't, how does calling the server's IP address know which website I want if there are many on the same server?

Best Answer

Basically: the browser includes the domain name in the HTTP request, so the webserver knows which domain was requested and can respond accordingly.

HTTP requests

Here's how your typical HTTP request happens:

  1. The user provides a URL, in the form http://host:port/path.

  2. The browser extracts the host (domain) part of the URL and translates it into an IP address if necessary, in a process known as name resolution. This translation can occur via DNS, but it does not have to (for example, the local hosts file on common OSes bypasses DNS).

  3. The browser opens a TCP connection to the specified port, or defaults to port 80, on that IP address.

  4. The browser sends an HTTP request. For HTTP/1.1, it looks like this:

    GET /path HTTP/1.1

    (The Host header is standard and required in HTTP/1.1. It was not specified in the HTTP/1.0 spec, but some servers support it anyway.)

From here, the webserver has several pieces of information it can use to decide what the response should be. Note that it is possible for a single webserver to be bound to multiple IP addresses.

  • The requested IP address, from the TCP socket
    • The IP address of the client is also available, but this is rarely used - sometimes for blocking/filtering
  • The requested port, from the TCP socket
  • The requested hostname, as specified in the Host header by the browser in the HTTP request.
  • The requested path
  • Any other headers (cookies, etc.)

As you seem to have noticed, the most common shared hosting setup these days puts multiple websites on a single IP address:port combination, leaving just Host to differentiate between websites.

This is known as a Name-based Virtual Host in Apache-land, while Nginx calls them Server Names in Server Blocks and IIS prefers Virtual Server.

What about HTTPS?

HTTPS is a bit different. Everything is identical up to the establishment of the TCP connection, but after that an encrypted TLS tunnel must be established. The goal is to not leak any information about the request.

In order to verify that the server actually owns this domain, the server must send a certificate signed by a trusted third party. The browser will then compare this certificate with the domain it requested.

This presents a problem. How does the server know which host (website)'s certificate to send, if it needs to do this before the HTTP request is received?

Traditionally, this was solved by having a dedicated IP address (or port) for every website requiring HTTPS. Obviously, this becomes problematic as we start running out of IPv4 addresses.

Enter SNI (Server Name Indication). The browser now passes the hostname during the TLS negotiations, so the server has this info early enough to send the correct certificate. On the server side, configuration is very similar to how HTTP virtual hosts are configured.

The downside is the hostname is now passed as plain text before encryption, and is essentially leaked information. This is usually considered an acceptable tradeoff, considering the hostname is normally exposed in a DNS query anyway.

What if you request a site by IP address only?

What the server does when it does not know which specific host you requested depends on the server implementation and configuration. Typically, there is a "default", "catchall" or "fallback" site specified that will provide responses to all requests that do not explicitly specify a host.

This default site can be its own independent site (often showing an error message), or it could be any of the other sites on the server, depending on the preference of the server admin.