3

This is an extension (not a dupe) of How to disable non-ssl connection on Apache 2.2

Like the above question, I have:

Added a virtual host config /etc/apache2/sites-available/example.com.conf with an SSL cert.

<IfModule mod_ssl.c>
    <VirtualHost example.com:443>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/html

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

        SSLEngine on

        SSLCertificateFile  /my/certs/mydomain.com.cert
        SSLCertificateKeyFile   /my/certs/mydomain.com.key
        SSLCACertificateFile    /my/certs/myprovider.ca

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>
        <Directory /usr/lib/cgi-bin>
                SSLOptions +StdEnvVars
        </Directory>


    </VirtualHost>
</IfModule>

Then:

  1. Run a2enconf ssl to enable SSL.
  2. Run a2ensite example.com to enable my domain.
  3. Run a2dissite 000-default to disable the host default site.
  4. Run a2dissite default-ssl to disable the host default ssl site.

What should remain is only the site https://example.com/

However, I can also access http://example.com/ (non-SSL) which is an unexpected feature.

The other question's answers are to simply disable port 80 by commenting out Listen 80 but that means that other virtual hosts won't be able to specify port 80.

Why does Apache2 appear to accept port 80 when no virtual host specifies it and what is the correct way without disabling port 80 altogether?

1 Answers1

1

This is almost an answer in that it doesn't leak information out of port 80 by accident:

Create a file in /etc/apache2/sites-available/forbidipaccess.conf with contents:

NameVirtualHost *:80
<VirtualHost *:80>
  <Location />
  Order deny,allow
  Deny from all
  </Location>
</VirtualHost>

Then run: sudo a2ensite forbidipaccess and sudo service apache2 reload

This doesn't block the IP as such, but it does issue a 403 Forbidden response if there isn't a config with that specific domain name as its ServerName or ServerAlias.

If we wanted to be super-nice and didn't like the "Forbidden" message, we could alternatively use an Apache Rewrite to return a 301/2/3 which would forward the user to the equivalent SSL, e.g.

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{SERVER_NAME}/%$1 [R=301,L]