Score:2

Apache virtualhost port 443 serves content from port 80 configuration

ng flag

I'm running Apache 2.4.52 on Ubuntu Server 22.04. I'm trying to run https through port 443, eventually aiming to have a redirect from port 80 to force content on https. However, Apache seems to be using the DocumentRoot from the port 80 config, despite the browser connecting to the https url and being served the right SSL certificate.

For example:

<VirtualHost *:80>

        ServerName [mydomain]
        ServerAlias [www.mydomain]
        DocumentRoot /var/www/testpage1/

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

        #RewriteEngine On
        #RewriteCond %{HTTPS} off
        #RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}
        #Redirect permanent / https://[mydomain]

</VirtualHost>

<VirtualHost *:443>

        ServerName [mydomain]
        ServerAlias [www.mydomain]
        DocumentRoot /var/www/testpage2/
        
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/live/[mydomain]/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/[mydomain]/privkey.pem

</VirtualHost>

results in the index.html from "/var/www/testpage1/" being shown instead of testpage2.


At this point, if I uncomment either

#RewriteEngine On
#RewriteCond %{HTTPS} off
#RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}

or

#RewriteEngine On
#Redirect permanent / https://[mydomain]

it just hits me with an "ERR_TOO_MANY_REDIRECTS"

If I comment out the DocumentRoot in the port 80 config, both the http and https url take me to the apache default config page.

And if I comment out the ServerName and ServerAlias in either the 80 or 443 config, both still take me to testpage1.


my ports.conf in /etc/apache2/ looks like this:

Listen 80

<IfModule ssl_module>
        Listen 443
</IfModule>

<IfModule mod_gnutls.c>
        Listen 443
</IfModule>

I've checked that the ssl module is turned on

In the Apache error logs, there is an AH01909 "server certificate does NOT include an ID which matches the server name" warning. Could this be an issue, or is there something else I'm missing?

Thanks for any help.


edit: my apache2.conf in /etc/apache2/ is as follows:

# This is the main Apache server configuration file.  It contains the
# configuration directives that give the server its instructions.
# See http://httpd.apache.org/docs/2.4/ for detailed information about
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
# hints.
#
#
# Summary of how the Apache 2 configuration works in Debian:
# The Apache 2 web server configuration in Debian is quite different to
# upstream's suggested way to configure the web server. This is because Debian's
# default Apache2 installation attempts to make adding and removing modules,
# virtual hosts, and extra configuration directives as flexible as possible, in
# order to make automating the changes and administering the server as easy as
# possible.

# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
#   /etc/apache2/
#   |-- apache2.conf
#   |   `--  ports.conf
#   |-- mods-enabled
#   |   |-- *.load
#   |   `-- *.conf
#   |-- conf-enabled
#   |   `-- *.conf
#   `-- sites-enabled
#       `-- *.conf
#
#
# * apache2.conf is the main configuration file (this file). It puts the pieces
#   together by including all remaining configuration files when starting up the
#   web server.
#
# * ports.conf is always included from the main configuration file. It is
#   supposed to determine listening ports for incoming connections which can be
#   customized anytime.
#
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
#   directories contain particular configuration snippets which manage modules,
#   global configuration fragments, or virtual host configurations,
#   respectively.
#
#   They are activated by symlinking available configuration files from their
#   respective *-available/ counterparts. These should be managed by using our
#   helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
#   their respective man pages for detailed information.
#
# * The binary is called apache2. Due to the use of environment variables, in
#   the default configuration, apache2 needs to be started/stopped with
#   /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
#   work with the default configuration.


# Global configuration
#

#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE!  If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the Mutex documentation (available
# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
# you will save yourself a lot of trouble.
#
# Do NOT add a slash at the end of the directory path.
#
#ServerRoot "/etc/apache2"

#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
#Mutex file:${APACHE_LOCK_DIR} default

#
# The directory where shm and other runtime files will be stored.
#

DefaultRuntimeDir ${APACHE_RUN_DIR}

#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}

#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5


# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}

#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off

# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log

#
# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# "LogLevel info ssl:warn"
#
LogLevel warn

# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf

# Include list of ports to listen on
Include ports.conf


# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

#<Directory /srv/>
#   Options Indexes FollowSymLinks
#   AllowOverride None
#   Require all granted
#</Directory>




# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives.  See also the AllowOverride
# directive.
#
AccessFileName .htaccess

#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>


#
# The following directives define some format nicknames for use with
# a CustomLog directive.
#
# These deviate from the Common Log Format definitions in that they use %O
# (the actual bytes sent including headers) instead of %b (the size of the
# requested file), because the latter makes it impossible to detect partial
# requests.
#
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
# Use mod_remoteip instead.
#
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.

# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf

# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
ServerName 192.168.0.51
turtle avatar
sz flag
Take a look at your /etc/apache2.conf file
Sit399 avatar
ng flag
@turtle post updated to show /etc/apache2/apache2.conf
turtle avatar
sz flag
Your apache config is directing apache to serve anything reachable from /var/www so if your trying to block users from seeing testpage1 from port 443 you might need to explicitly deny access and also grant access to testpage2:
turtle avatar
sz flag
`<VirtualHost *:443> ServerName [mydomain] ServerAlias [www.mydomain] DocumentRoot /var/www/testpage2/ ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine on SSLCertificateFile /etc/letsencrypt/live/[mydomain]/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/[mydomain]/privkey.pem <Directory /var/www/testpage2/> Require all granted </Directory> <Directory /var/www/testpage1/> Require all denied </Directory> </VirtualHost>`
Sit399 avatar
ng flag
@turtle I've fixed the certificate matching the server name issue by moving the keys to another directory. I've added " <Directory /var/www/testpage2/> Require all granted </Directory> <Directory /var/www/testpage1/> Require all denied </Directory>" to the virtualhost config, but the same issue persists for some reason (testpage1 can still be accessed)
turtle avatar
sz flag
Do a `grep -r "DocumentRoot"` in your /etc/apache2 directory there must be another DocumentRoot loading earlier. You could also do a grep for all the includes `grep -re "^Include"` to show you possible other files being pulled in.
Sit399 avatar
ng flag
Hey @turtle thanks for all your help with diagnosis. It turned out that the issue was never caused by Apache and virtualhosts - just a combination of cloudflare edge certificates and my stupidity misidentifying them as my own masking that I didn't allow https through my firewall.
Score:1
ng flag

As stupid as it seems, and after weeks of headache, it turns out I just didn't allow HTTPS traffic through my firewall.

As I proxied my site through Cloudflare, what I thought was the correct SSL certificate was actually the Cloudflare Edge certificates. As the SSL/TLS encryption mode wasn't on strict, the site requested by Cloudflare from my server was still served through port 80, but the traffic between my browser and Cloudflare was still encrypted so it still displayed as https on my browser.

sudo ufw allow 'Apache Full' and setting the encryption mode to strict ended up fixing all the issues.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.