How to set the default website on our ISPConfig server so that the Apache2 Debian Default page is not loaded when accessing the server's IP address or full hostname

botond published 2023/01/21, Sat - 00:20 time

Content

 

Introductory

ISPConfig our server manages our websites nicely, however, if the server is in the browser to your IP address or we refer to its full hostname, then we do not get the expected result, because in this case it is Apache2 Debian Default Page is loaded, which is essentially what it is Apache "welcome" page. Of course, this is not a tragic mistake, but a beauty mistake. In this description, we will see how we can configure our Apache web server so that the website we want is loaded.

I am preparing this description in parallel with the Debian 11 (Bullseye) with production server installation, because this also deserves a separate topic. Therefore, this description includes both before and after setting up SSL. I also implement this guide in a production environment, so it contains parts that have been tested in practice.
The one used here linuxportal.eu the domain name and the corresponding IP address, as well as the content of the server, were in this state at the time of writing the description, so there is a good chance that their operation and content will change when you read the article later, since they will also be used to create other tutorials.

 

 

before setting up SSL

The domain name is not yet assigned to the server, so that's all IP address can be accessed either with the domain name or hostname set in the hosts file. That's why SSL is not set on it either.

Apache Default Page

If you specify the server by its full hostname (FQDN) or with its IP address, the Apache2 Debian Default Page will be loaded (of course, this version is available for Debian systems):

http://vps.linuxportal.eu/

Apache site

http://178.238.208.205/

The Apache page also comes to the IP address

This well-known Apache default page does not appear because of an error, but because of how Apache works. Let's find out what's really going on.

Order of Apache configurations

If we look a little under the hood, the / etc / apache2 / sites-enabled / directory, then we see this:

Order of Apache configurations and virtualhosts

Here, the configs are executed based on the name order / virtual hosts. Based on the list here, the following happens:

Apache config: 000-apps.vhost

Process the very first, a 000-apps.vhost more symbolic link, which points to an Apache configuration that listens for requests on port 8081 and serves various web applications to clients, such as webmail, phpMyAdmin, etc. So everything that can be loaded with / after the host name or the domain name of a website, as if they were in a subdirectory of a given website, but in the meantime, they are loaded after entering any website.

For example, with the full hostname: https://vps.linuxportal.eu:8081/phpmyadmin, or simply with the domain name: https://linuxportal.eu:8081/phpmyadmin/.
A phpMyAdmin example on port 8081 with an HTTPS connection:

Accessing phpMyAdmin on port 8081 with an HTTPS connection

The role of port 8081 here is that this Apache configuration also protects these web services using its own SSL of the ISPConfig control panel. This SSL is requested by the ISPConfig installer a Let's Encryptfrom, but if for some reason it cannot do this, it generates a self-signed SSL for itself. In this case, the latter occurred, as the domain name was not yet directed to the server, so the authentication process failed.

It is important to note here that if, for example, phpMyAdmin or another web application is loaded not under the full hostname of the server, but for example after a web page running on the server, the web application is secured by the certificate of the given web page. , as the certificate of that website is loaded based on the URL address. We will take a closer look at this in the already set SSL stage.

Turning back to the config, if we look into the 000-apps.vhost file, then we will find this:

The apps.vhost file

So here we can see that this config/virtualhost listens on port 8081, and below that the /usr/local/ispconfig/interface/ssl/ispserver.crt file is used by the HTTPS to build a relationship.

But since it is the basis of our initial problem http://vps.linuxportal.eu/ or the http://178.238.208.205/ Our URLs do not include port 8081, so Apache skips this configuration and goes to the next one in the list.

 

 

Apache config: 000-default.conf

The next configuration in line is a 000-default.conf link which is the ../sites-available/000-default.conf points to a file. If we look at this as well:

The default.conf file

Then here we can see a completely simple virtualhost setup that only works on port 80 (HTTP) and has a / Var / www / html webroot directory. This web root directory contains the particular index.html file that displays the Apache Debian "welcome" page. Since this configuration only works on port 80, it will no longer be available after setting up SSL, but will either throw an error, or some website will come in, etc. But we will also detail and improve this below.

This is how Apache's intro page is displayed via simple HTTP connections. In the next chapter, we will look at how these server access URLs and the content displayed on them develop after valid SSL is set up

 

After setting up SSL

As I mentioned in the introduction, this description was written in parallel with the Debian 11 live server installer description, accordingly this part is already directed to the server linuxportal.eu was written after setting up a domain name and the required Let's Encrypt SSL. So here, on the working server with a valid SSL certificate, we will continue to examine the Apache settings and also set the default website.

Apache Default Page

Here we now load the HTTPS version of the same two URLs:

https://vps.linuxportal.eu/

FQDN hostname access via HTTPS

On HTTPS, the Apache Default Page no longer comes in, but our only website. This would be fine in this case, because it didn't throw an error, but if several websites are uploaded to the server, the first one in the list will probably be loaded, which may not be suitable for us.

Another problem here is that even though a website comes in, in this case not with its own web address, but with the host name of the server. Which is not good from an SEO point of view, since search engines start indexing the given website with this URL, which can cause two problems:

  • If the exact same content is available on several URLs, and none of them refer to the other canonical link designation, then Google may consider it a repetition of content and rank our website lower (with both URL addresses).
  • If a new website is added to the server later, which comes before its predecessor in the name list, that website will be included from there. And this is an even more serious problem from an SEO point of view, because in this case an entire URL structure will lose its SEO power, and a new one will be built in its place with different content. So we don't want that either.

Therefore, we need to improve this.

Interestingly, I have now set up the conditions on this server as they are here now, so that I can demonstrate what happens if, for example, there is a website on the hosting that checks the running URL address:

FQDN hostname access via HTTPS - Drupal error message

(Of course, once the description is finished, I will also re-adjust this correction on this page, so this image above only reflects the state at the time of writing the description.)

The Drupal CMS system for example, it throws this error: "The provided host name is not valid for this server.". So it detects that the system is not running from trusted addresses (trusted hosts) and stops it with the above error. It doesn't look better either, but it's still better than loading from another URL and "letting" search engines index it. Of course, Drupal does not do this for this reason, but rather for the security of its own system, but it is also useful here.

http://178.238.208.205/

IP Address - Apache2 Debian Default Page

With plain HTTP, the Apache page and the HTTPS version of the same will still come in:

https://178.238.208.205/

IP address - HTTPS error

And here, the very first page in the name list is also included (currently there is only this one), and it even loads the SSL for it, but it reports an error, because the SSL is for a specific domain name, not an IP address.

 

In the next section, we will see how we can remedy these three malfunctioning situations.

 

 

Set default website

Setting goals

Our goal is therefore to protect all URL possibilities where a website is not loaded properly, and because of this the system does not work as expected. The tasks are as follows:

  • In these cases too, a fixed website should be loaded. Typically, this is the primary website, but if we have several websites, we can decide which one it should be, not based on the roster.
  • The loading website should go to its own url and load with that. As a result, the site will also function as intended, and search engines will not index our content "aside" under a different URL address. The most suitable for this is a 301 HTTP header redirection, which redirects the browser one by one to the appropriate URL address, i.e. to your own address.

First, let's take a look at the possibilities. We can achieve the above goals in the following ways:

  • By changing the order of the virtual hosts (by renaming, we move the website you want to load to the front of the list)
  • By setting the default config accordingly

It is not recommended to choose the first of these, because in an ISPConfig environment, the control panel switches the virtual hosts on and off, so there is no guarantee that our changes will be preserved. Therefore, renaming virtualhost links to the / Etc / apache2 / sites-enabled not recommended in a library. If one LAMP server we would, it would fit there, because nothing but us claims these things, but here we don't manage the virtualhosts, but the ISPConfig panel.

The second implementation will be the good one, as it has already been examined above /etc/apache2/sites-available/000-default.conf file is Apache's default configuration, so no one touches it either, so ISPConfig doesn't change it either.

Enable SSL in the 000-default.conf config

Open the /etc/apache2/sites-available/000-default.conf file to edit:

nano /etc/apache2/sites-available/000-default.conf

Then we add the following virtualhost section to the end:

<VirtualHost *:443>

        DocumentRoot /var/www/html

        SSLEngine On
        SSLProtocol All -SSLv3 -TLSv1 -TLSv1.1
        SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt
        SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key

</VirtualHost>

Finally, our complete file looks like this after the modification:

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
</VirtualHost>

<VirtualHost *:443>

        DocumentRoot /var/www/html

        SSLEngine On
        SSLProtocol All -SSLv3 -TLSv1 -TLSv1.1
        SSLCertificateFile /usr/local/ispconfig/interface/ssl/ispserver.crt
        SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key

</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Then restart Apache:

systemctl restart apache2

This enabled SSL a 000-default config, as a result of which Apache will not skip this configuration even for those arriving with the HTTPS protocol, but will execute it, since this configuration is ahead of any virtual host starting with "100" belonging to any domain, and now includes also the handling of port 443. And for SSL, we set the certificate also used by the ISPConfig control panel.

 

 

SSL verification on different URLs

Now let's check the URLs that we tested earlier that were not working correctly:

https://vps.linuxportal.eu/

HTTPS and FQDN Name - Works

This is exactly what needs to happen here, so now the default Apache configuration comes in with HTTPS as well. Previously, you skipped this and the website loaded.

http://178.238.208.205/

HTTP and IP address - It works

Here, no changes have been made with plain HTTP, the Apache Default Page is loaded in the same way, I just listed them here so that all three URL variations appear together.

https://178.238.208.205/

HTTPS and IP Address - It works

And now the default configuration of Apache comes with the IP address as well. Although it indicates an SSL error, this does not matter here, because the point here is that Apache should not skip this configuration, but run it for us in this case.

And now comes the 301 redirect.

301 redirect to the correct website

Now that in all three cases it is Apache 000-default.conf file is executed, we just need to redirect from here with a 301 HTTP header (Moved permanently) to the website we want. In this case, the target website is loaded with its own URL address, so everything falls into place.

The redirection can be solved in two ways:

  • The Apache 000-default.conf file, we place the line "Redirect 301 / https://www.linuxportal.eu/" in both protocol blocks, with this Apache would perform the redirection to the desired website, or
  • the other solution is if PHP, we execute the 301 redirect.

In terms of achieving the current goal, we can achieve exactly the same effect with both variations: in the case of all three URL variations mentioned above that work incorrectly, the browser jumps to the set website.

Disadvantage of Apache Redirection

Of the two, the first solution would be the more elegant, because it would not have to modify additional files, but it has one drawback. If the 000-default.conf file to redirect to a specific website, then Apache status module provided by server-status route will also not be available through the original localhost, and the Apache states will not be displayed when we want to retrieve them. In this case, the output looks like this:

Query the server status in the default way:

curl http://localhost/server-status?auto

The server status is not working

The source code of our Apache 301 redirect is clearly displayed here. The status query only works if you request the redirected domain by HTTP access:

curl http://linuxportal.eu/server-status?auto

The server status is available from the other domain

So the previous request should look like this, but logically it only comes from the redirected domain.

The problem with this is that the system resource analysis / display programs that rely on this output do not know under which domain it should be accessed, but only try to load it with localhost. And then they don't get access to the data. Such a program is, for example, a Munin also, of which Apache compiles its graphs from its output.

 

 

Of course, I tested all of this, just as I test everything in the case of the other descriptions, and only then publish it so that the information here corresponds to reality and can be of help to others. So, because of this redirect, I also had Munin Apache graphs stop while I was testing this part on this server. Here are my affected graphs:

Munin - Apache accesses

Munin - Apache processes

In this case, the test of the Apache plugin run with the munin-run command gives a "U" output, which refers to Unknown, because it cannot interpret the received output, which in this case is a small HTML code containing the details of the redirection. After the redirection is terminated, everything will of course return to normal.

Of course, not only Munin relies on server status data, other system status monitoring programs can also use its output as a data source, so we solve this redirection in a PHP file.

I wrote all of this here so that those who want to set up their default website on their server in a similar way should avoid direct redirection in the Apache default configuration, no matter how obvious this solution seems. Of course, route exceptions could be added so that, for example, the /server-status/ route is not valid for redirection, etc., but it is much easier to solve all of this in 2-3 lines from PHP. In this way, the Apache config also runs undisturbed, and only browsers calling PHP are redirected.

Redirection with PHP

Redirection with PHP is not more complicated either, we just need to enter the / Var / www / html directory:

cd /var/www/html

Let's rename it here index.html file so that it is not loaded (so you don't need to set the index file in the Apache configuration):

mv index.html index.html.bak

Then create an index.php file:

nano index.php

And add the following lines:

<?php
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: https://www.linuxportal.eu");
    die();
?>

Of course, don't forget to change the example here to your own web address!

So the PHP file in the webroot will run and do the 301 header issue and then the redirect. die() is only there as a kind of extra protection, if the redirection does not happen, it will definitely stop the execution, so nothing will be loaded, and thus the incorrect content will not be loaded either. But the redirect works fine.

And if we now look at the server status with the original localhost:

curl http://localhost/server-status?auto

The server status also works

Then the data will come even for this request, so the resource monitoring applications can also work without any problems.

 

Default web page check on URLs

Finally, let's check the three previously malfunctioning URLs again, of course with our own domain names and IP addresses:

https://vps.linuxportal.eu/
http://178.238.208.205/
https://178.238.208.205/

A default website works with all three URLs

Here, the default website works with all three accesses that previously malfunctioned, which already jumps to its own address with a 301 redirect, and of course SSL also works (the third address with an https IP address first throws an SSL error, but after passing through it jumps to the corresponding page in the same way).

 

 

Conclusion

The server now produces the expected operation even when using the URL mentioned above: the website we specified is loaded in each case. In this way, incorrect search engine indexing will not occur, and our websites will not function incorrectly due to inappropriate URL addresses.