Amazon.co.uk Widgets

Log in

X
Ubuntu circle of friends

It is no longer hard to serve multiple differently named websites from the same server with SSL. Let's Encrypt supports Apache and Ubuntu and is easy to configure. 

Click the Padlock in the toolbar to see the certificate details
Success - Click the Padlock in the toolbar to see the certificate details

The Apache HTTP Server has always had a virtual hosts feature to serve multiple differently named websites from the same server. Setting it up with SSL is historically more complex than it perhaps ought to be given that the project it named after HTTP it was centred around http and https was originally an additional, often expensive and complex configuration step.

This seems outmoded to me. Even for test sites, traffic encrypted to the web browser with https is mandatory for any serious web presence. http is an insecure protocol that should really be a secondary consideration. Anyway, it is what it is.

With virtual hosts, each individual site appears to the end-user to have a different identity even though it is served from the same server. Hosting providers use this technology to provide resilience, security, scale, analytics and for many other reasons but it is also useful for developers who want to have a replica small scale development or staging environment perhaps for multiple websites. A development environment is my reason for building out Apache 2 virtual hosts with separate Let's Encrypt certificates on my Ubuntu Linux machine.

To make it work, you need to think about setting out the directory structure on your Linux machine, the Virtual Hosts configuration files for Apache2, and a properly resolving DNS record to the Linux machine hosting your virtual host site. Setting it up is easy enough but takes a little bit of concentration on the details of all these moving parts. Adding SSL to these virtual hosts is far less tricky than it once was because 'Let's Encrypt' does most of the heavy lifting now.

TL:DR — I now have two dev sites on my local Ubuntu Desktop. Both have valid Let's Encrypt SSL certificates and are working well locally and via the Internet. It took about 45 minutes to set up.

Getting ready

Theres a few things to get updated and ready before you start. You'll need :-

  • Ubuntu Desktop 24.04. LTS updated to latest. Run $ sudo apt update && sudo apt upgrade
  • Apache 2 Web Server. I'm installing Joomla so its convenient to also install the rest of the lamp stack via a task (denoted by the caret^) $ sudo apt install lamp-server^
  • An administratrive user that can 'sudo'.
  • Let's Encrypt 'certbot' installed and a good understanding of Linux locations and editing tools. To install it $ sudo snap install --classic certbotand link it $ sudo ln -s /snap/bin/certbot /usr/bin/certbot
  • An IP address on your Linux machine that is reachable from the Internet. This can either be fixed or using a dynamic DNS client for example on a laptop! You dont need this for a computer at a fixed location with a fixed IP address. $ sudo apt-get install ddclient. Read more about that here https://help.ubuntu.com/community/DynamicDNS. If your DNS provider is supported this is dead easy.
  • Local DNS, sometimes called 'split DNS', perfectly set up for your local area network or a hosts file with entries for the names pointing at the local IPv4 address of the Linux machine.
  • The domains you wish to use for your virtual hosts set up to use that IP address or an alias that resolves to it.

Folder structure for multiple websites

The default Ubuntu document root for Apache is /var/www/html. It contains the 'It Works' page. The documentation on this very page recommends you make your own virtual sites under /var/www.

  • I use the convention of using a public_html folder as the document root to denote content that is going to be visible on the Internet. The root level of your virtual host can then be used for private scripts and utilities that won't be visible on the Internet, but are clearly for that particular site.
  • Replace virtual_host_domain_name_one and virtual_host_domain_name_two in the following commands with the real domain names you plan to use. $ sudo mkdir -p /var/www/virtual_host_domain_name_one/public_html and then $ sudo mkdir -p /var/www/virtual_host_domain_name_two/public_html

File permissions

By default Ubuntu Apache2 uses www-data as the Apache user. This is a development machine, so the developer user needs to be able to control all the files and the Apache web server user needs to be able to serve them. I suppose you could enable the user www-data but I have my own local user.

  • Change into the webservers folder % cd /var/www
  • Make the current user the owner, but leave www-data as the group % sudo chown -R $USER:www-data /var/www/ *
  • Make sure your permissions are good. www-data needs to be able to write to install and run Joomla $ chmod +R g+w *

Create A first default page for each virtual host

Ceate a minimal HTML5 document for each index.html file. It will be replaced so this is just for testing.

<html lang="en">  
  <head>
    <meta charset="utf-8">
    <title>Virtual Host</title>
  </head>
  <body>
    <p>Hello, world</p>
  </body>
</html>

Create virtual host configuration files for Apache2

Apache uses configuration files called conf files to set our the virtual host information it needs to find the directories you created and make them available through the web server. The layout is straighforward but, i think, Ubuntu specific.

/etc/apache2/
|-- apache2.conf
|       `--  ports.conf
|-- mods-enabled
|       |-- *.load
|       `-- *.conf
|-- conf-enabled
|       `-- *.conf
|-- sites-enabled
|       `-- *.conf

You can see one of mine below. It sets the name of the server, the admin email address, the document root we created on the filesystem, and places error and access logs in the servers directory above the public html directory. Then it has some directory options for security, and a rewrite rule to make all web requests use SSL. (SSL will be set up shortly using Let's Encrypt). Just replace virtual_host_domain_name_one with your domain name to use it. Create one for each host, in sites-available calling the file virtual_host_domain_name_one.conf and taking care to ensure the directories are the ones you previously created.

<VirtualHost *:80>
  ServerName virtual_host_domain_name_one
  ServerAdmin admin@virtual_host_domain_name_one
  DirectoryIndex index.html index.php 
  DocumentRoot /var/www/virtual_host_domain_name_one/public_html 
  ErrorLog /var/www/virtual_host_domain_name_one/error.log 
  CustomLog /var/www/virtual_host_domain_name_one/access.log combined 
  
<Directory /var/www/virtual_host_domain_name_one/public_html> 
      Options FollowSymLinks 
      AllowOverride All 
      Require all granted 
</Directory>
</VirtualHost>

Enable the site

Once you create the conf file you need to enable it using a2ensite so that the apache web server can see it. $ sudo a2ensite virtual_host_domain_name_one does this. Check for any errors, and restart the Apache web server $ sudo systemctl restart apache2 and your virtual host is enabled. Test it by loading your Hello world homepage. Next you can apply an SSL certificate to it automatically using Lets Encrypt, but there are a couple of things to do first.

Now would be a good time to disable the default site using a2dissite as you don't really need it anymore. $ sudo a2dissite 000-default.conf does this. Do this for the default SSL site too $ sudo a2dissite default-ssl.conf.

DNS

There is a saying among the cloud technical support community that the answer to any Internet problem "is always DNS!", and it is often true. DNS resolution is the process by which your domain name is looked up and an IP address found for it (resolved). If it is not set up properly then your site won't work. If it is set up properly but your site is behind a router or firewall and the router or firewall is not set up properly it will not work. If it is set up properly using your DNS provider your site will probably still not work from your internal network but will probably work from the Internet. It seems complicated but honestly there are just a few steps to take to make sure it works reliably and well from your DNS provider and inside your home network.

  • Log in to your DNS provider
  • Set up an A record for virtual_host_domain_name_one and point it at the external IPv4 address of your router/firewall
  • Continue to the next step to set up Port Forwarding for port 443 (and Port 80), to the internal IPv4 address of your Linux machine. Nothing will work unless you can do this.

Port forwarding

Router port forwarding (This is a Ubiquiti Edge Router Lite
Router port forwarding (This is a Ubiquiti Edge Router Lite - yours will be different and that isn't the real IP address)

Development machine /etc/hosts file

Unless you have a DNS server in your own environment you'll need to add virtual_host_domain_name_one and virtual_host_domain_name_two to your local Linux hosts file /etc/hosts so that they resolve correctly on this local machine if you want to use them say from a web browser installed locally.

127.0.0.1	localhost virtual_host_domain_name_one virtual_host_domain_name_two 

Local DNS Server

If your router has a local DNS Server capability, then you could add virtual_host_domain_name_one and virtual_host_domain_name_two to it so that it resolved exactly as it would from outside your local network on the Internet. One good way to test this is to use a mobile device on a cellular connection and make sure the site resolved with the exact same URL both from the Internet over cellular and from your local network.

Get your SSL certificates from Let's Encrypt

Assuming you've done all that and installed Let's Encrypt it is awesomely simple!

Once you are satisfied your connectivity is working then you can run the certbot tool.

  • Test everything. certbot is rate limited for production SSL certificates. The simulated enpoint accessed via --dry-run is not. $ sudo certbot certonly --dry-run -d virtual_host_domain_name_one.
  • Once the test succeeds run it for real with the --apache parameter to allow it to go ahead and install and enable your virtual host $ sudo certbot --apache -d virtual_host_domain_name_one. This is really nice and avoids typo errors in config files!

That's it. You should now be able to 'see' your site home page in a secure browser.

Success - Click the Padlock in the toolbar to see the certificate details

If it isn't working check that your domain name is really resolving to your server IP address, and check you don't have a firewall blocking access. Add an inbound firewall rule if necessary.

References

See also:

Licences, trademarks, source code licences and attributions

Licences, trademarks, source code licences and attributions

Multizone and this site is not affiliated with or endorsed by The Joomla! Project™. Any products and services provided through this site are not supported or warrantied by The Joomla! Project or Open Source Matters, Inc. Use of the Joomla!® name, symbol, logo and related trademarks is permitted under a limited licence granted by Open Source Matters, Inc. 928uk® is a trademark of Multizone Limited, registered in the UK. AdMob™, AdSense™, AdWords™, Android™, Chrome OS™, Chromebook™, Chrome™, DART™, Flutter™, Firebase™, Firestore™, Fuchsia™, Gmail™, Google Maps™, Google Pixel™, Google Play™, Pixelbook Go™, and Pixel™ and other trademarks listed at the Google Brand Resource center are trademarks of Google LLC and this site is not endorsed by or affiliated with Google in any way. Apple and the Apple logo are trademarks of Apple Inc., registered in the U.S. and other countries. App Store is a service mark of Apple Inc. The OSI logo trademark is the trademark of Open Source Initiative. Microsoft, CoPilot, Microsoft 365, Microsoft Teams, and Windows are trademarks of the Microsoft group of companies. ROKU, the ROKU Logo, STREAMING STICK, ROKU TV, ROKU POWERED, the ROKU POWERED Logo, ROKU READY, the ROKU READY Logo, the purple fabric tag design,and the purple d-pad design are trademarks and/or registered trademarks of Roku, Inc. in the UK, the United States and other countries. UNIX® and the X® logo are registered trademarks of The Open Group. Any other product or company names may be trademarks™ or registered® trademarks of their respective holders. Use of these trademarks in articles here does not apply affiliation or endorsement by any of them.

Where the source code is published here on ezone.co.uk or on our GitHub by Angus Fox, Multizone Limited it is licenced according to the open source practice for the project concerned.

BSD 3-Clause "New" or "Revised" Licence
Original source code for mobile apps are licenced using the same licence as the one used by "The Flutter Authors". This Licence, the BSD 3-Clause "New" or "Revised" Licence (bsd-3-clause) is a permissive licence with a clause that prohibits others from using the name of the project or its contributors to promote derived products without written consent.
GNU General Public Licence v2.0 or later
Original source code for Joomla! published here on ezone.co.uk by Angus Fox, Multizone Limited is licenced using the same licence as the one used by Joomla!. This Licence, the GNU General Public Licence Version 2 or later (gpl-2.0) is the most widely used free software licence and has a strong copyleft requirement. When distributing derived works, the source code of the work must be made available under the same licence.

You can use any code you find here, just respect the licences and dont use the name of this site or our company to promote derived products without written consent. I mean, why would you? You're not us!

Amazon Associate
As an Amazon Associate we earn from qualifying purchases.
Logo
Our Logo Image is by Freepik. We chose it because its an M and also the letter A twice - and that represents us.