Breaking down how VirtualHosts and Subdomains work behind the scenes
Let’s dive deep into both and understand how these two helps handling multiple services or domains/hosts to the back-end server.
We all know that, A Single Back-end server can host multiple websites or web applications, Meanwhile a domain can only have 1 back-end server.
But the back-end server can host multiple subdomains/vhosts (VirtualHosts) that can work as separated domain or as a part of a domain (subdomain), both.
# Examples of VirtualHosts
admin.example.com # here, admin is vhost
login.example.com # here, login is vhost
book.example.com # here, book is vhostSubdomain is a part of a domain, which serves a separated category service to that domain. (i.e., login, courses, forums, contact, etc.)
# Examples of Subdomains
courses.example.com
login.example.com
forums.example.com
contact.example.comYou can see, both, vhosts and subdomains are kind of similar. So, what’s the difference between them?
The Simple difference can be seen when DNS comes into the picture.
DNS (Domain Name System) functions like a telephone book, Just as telephone book records & mapping all telephone numbers with their owner’s name, Just as that, DNS records all the IP Addresses with their domain names. so when you search for the domain name into any browser (like youtube.com), it will first resolve the domain name into an IP address then look for the server using that IP address.
Let’s understand, what happens when you put any domain into the search-bar / url-bar into any browser?
When you search for any domain in the url-bar, the browser first check for the domain name into the Local DNS Database/Records, which is stored “hosts” file. This files has all local domain’s record for all domains and subdomains. You can read this by accessing it at given path, as they are located on different path on different platforms.
# For Linux
/etc/hosts # For Windows
C:\Windows\System32\drivers\etc\hosts
If the records for the domain not found in this file, then it will search for “Public DNS”. This is where things becomes interesting. If the domain you search for is hosted on the internet and is a registered domain, then the domain can resolve using Public DNS or in simple way, your browser will be able to find the domain records and it’s IP Address. And if the browser will not able to find Public DNS record then it will show you and error page like this:
Now, if you put entry for any of the running server’s IP address and domain name into the hosts file, you can access that server with that domain name. so assume, you are running a webserver on localhost and you put the entry for the localhost into hosts file, you can access it via that domain name.
# This is hosts file
# format for all records is: ip-address domain-name
127.0.0.1 localhost # default entry
127::1 localhost # default entry# Now add new entry
127.0.0.1 example.com # now you can search you localhost on example.com
This thing is very useful when you have configured local-server on local network and not willing to type the ip-address every time you want to access that server. So you can just add the domain record into the hosts file.
Getting onto the point, when a server is hosting multiple web application, VirtualHost is used if the server has no public DNS Record or the server is local server (inside you local network).
To configure vhost, go to you back-end server and open the configuration file or create if not exists:
# For Linux (Apache2 server)
# Assume we have 2 web application
# Root Direcotry of 1st Web application is:
/var/www/example1.com/public_html# Root Direcotry of 2nd Web application is:
/var/www/example2.com/public_html
# Create config file for 1st web application if not exists
/etc/apache2/sites-available/example1.com.conf
# Put Below code into example1.com.conf file:
<VirtualHost *:80>
ServerName example1.com
ServerAlias www.example1.com
DocumentRoot /var/www/example1.com/public_html
</VirtualHost>
# Create config file for 1st web application if not exists
/etc/apache2/sites-available/example2.com.conf
# Put Below code into example1.com.conf file:
<VirtualHost *:80>
ServerName example2.com
ServerAlias www.example2.com
DocumentRoot /var/www/example2.com/public_html
</VirtualHost>
This configuration is a demo purpose only, just to demonstrate you how to configure vhost into your webserver.
If you are into a cybersecurity domain, then you must have try to find subdomains of a web-server in CTFs or Bug-Bounty programs, etc. or if not, then very soon will be encounter because this is very basic thing and comes into reconnaissance part.
By using “ffuf” tool we can FUZZ for subdomains for public domains. But in most CTFs, targets are local. So when you FUZZ for any subdomain you won’t get any hit. Because you are sending for the subdomain using ffuf which is not public domain nor in your hosts file, so at the end it will not get any results.
Join Medium for free to get updates from this writer.
There are two possible solution add each subdomains’ entry into the hosts file, which is not feasible, and 2nd is to use “Host” header in the request header for successful request.
This is why “Host” header is used for. Host header specifies that which particular host you want to access or requesting to. curl is a best command line utility for making requests. Let’s use it, so i can show you the difference.
I have configured a ubuntu machine running apache2 server on local network. we will first add the domain name into /etc/hosts file. then try to visit it. As shown above example of setting up configuration file for vhosts, we will create a domain, in which will create 2 subdomains.
This is the file strucure i have created:
Here, We are a main domain: “linux.com” and It’s 2 subdomains/vhosts “about.linux.com” and “login.linux.com”.
Press enter or click to view image in full size
Also created all the configuration file for all domains/vhosts.
# Configuration file: linux.com
<VirtualHost *:80>
ServerName linux.com
ServerAlias www.linux.com 10.207.17.130
DocumentRoot /var/www/linux.com/public_html <Directory /var/www/linux.com/public_html>
Require all granted
</Directory>
</VirtualHost>
# Configuration file: about.linux.com.conf
<VirtualHost *:80>
ServerName about.linux.com
DocumentRoot /var/www/about.linux.com/public_html
<Directory /var/www/about.linux.com/public_html>
Require all granted
</Directory>
</VirtualHost>
# Configuration file: login.linux.com.conf
<VirtualHost *:80>
ServerName login.linux.com
DocumentRoot /var/www/login.linux.com/public_html
<Directory /var/www/login.linux.com/public_html>
Require all granted
</Directory>
</VirtualHost>
# Catch all default domains: 000-catchall.conf
<VirtualHost *:80>
ServerName _
DocumentRoot /var/empty
# Return 404 for all requests
<Location />
Require all granted
RedirectMatch 404 ".*"
</Location>
ErrorLog ${APACHE_LOG_DIR}/catchall_error.log
CustomLog ${APACHE_LOG_DIR}/catchall_access.log combined
</VirtualHost>
Now, apply changes to the server ad restart the server.
sudo a2ensite 000-catchall.conf
sudo a2ensite linux.com.conf about.linux.com.conf login.linux.com.conf
sudo systemctl reload apache2a2ensite is a helper command to enable a virtual host configuration in Apache. Now, go to our client machine, and try to access the server using IP address.
We can successfully access the server, now let’s put the DNS Record into local /etc/hosts file.
Now, search in browser “linux.com” and see the results.
Now, We will use curl command utility to make requests. Also Remember when we make requests we have to change Host header using curl -H flag, as we can’t do it on browser because browser handles Host header automatically.
Press enter or click to view image in full size
We can make request using curl and -H flag to add additional header to the request. if we change Host header to: login.linux.com, see the difference.
Press enter or click to view image in full size
By reviewing curl output, we can identify that to access that a vhost (subdomain) is active or not, we just have to set Host Header for that vhost.
You can see, if we make a request with the invalid Host Header, it's returning “404 Not Found” as we have set configuration for this in “000-catchall.conf” file.
Now let’s use ffuf tool start fuzzing for vhosts on Host header on the target server.
Press enter or click to view image in full size
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://linux.com -H 'Host: FUZZ.linux.com'We got the output of ffuf, and found all subdomains. Now we can set these subdomains record into /etc/hosts file to access them directly via adding them into url as browsers sets Host header automatically.
So, you can use this technique when working on CTFs. By adding subdomain entry into /etc/hosts after that you can access the domain/subdomain directly via url in browser or even any tools which can makes requests.