0

All of my http > https redirects are working perfectly fine.

I have setup a separate sub-domain and port to use with PHPMyAdmin to access a MySQL DB so it is less likely to get be scanned by bots etc. The examples below are very demonstration purposes only.

The problem I have is if I enter the port used on the PHPMyAdmin sub-domain after the main domain without https prefixed so that it becomes http://example.com:8080, after what starts off as a timing out webpage, it eventually redirects me to the https site but on the sub-domain at https://phpmyadmin.example.com:8081.

How do I stop the main domain redirecting to the sub-domain and instead timeout as a typical server would? If someone was to guess every port at the main domain someone would eventually find the sub-domain.

/etc/apache2/sites-enabled/example.com

<VirtualHost *:80> ServerName example.com ServerAlias www.example.com ServerAdmin [email protected] Redirect permanent / https://example.com DocumentRoot /var/www/example.com # <Directory /> # DirectoryIndex index.html index.php # Require all denied # Options FollowSymLinks # AllowOverride All # </Directory> #ErrorLog ${APACHE_LOG_DIR}/error.log #CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <VirtualHost *:443> ServerName example.com ServerAlias www.example.com ServerAdmin [email protected] DocumentRoot /var/www/example.com # <Directory /> # DirectoryIndex index.html index.php # Require all denied # Options FollowSymLinks # AllowOverride All # </Directory> #ErrorLog ${APACHE_LOG_DIR}/error.log #CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine On SSLCertificateFile "/etc/ssl/certs/example.com.crt" SSLCertificateKeyFile "/etc/ssl/private/example.com.key" SSLCertificateChainFile "/etc/ssl/certs/example.com.ca-bundle" </VirtualHost> 

/etc/apache2/sites-enabled/phpmyadmin.example.com

<VirtualHost *:8080> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com Redirect permanent / https://phpmyadmin.example.com:8081 </VirtualHost> <VirtualHost *:8081> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com DocumentRoot /usr/share/phpmyadmin # RewriteEngine On # RewriteCond %{HTTPS} off # RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} <Directory /> Require all denied Options FollowSymLinks AllowOverride All </Directory> LogLevel notice CustomLog /var/log/apache2/access.log combined ErrorLog /var/log/apache2/error.log Include /etc/phpmyadmin/apache.conf SSLEngine On SSLCertificateFile "/etc/letsencrypt/live/phpmyadmin.example.com/cert.pem" SSLCertificateKeyFile "/etc/letsencrypt/live/phpmyadmin.example.com/privkey.pem" SSLCertificateChainFile "/etc/letsencrypt/live/phpmyadmin.example.com/chain.pem" </VirtualHost> 

UPDATE 1

I think the problem is between the http to https redirect in general. By typing the HTTP port for the sub-domain onto the main domain instead, Apache's VirtualHost sees that as the initiator to redirect the http to https but totally ignores the domain is supposed to do it on. Is there a way I can isolate http to https redirect dependant on what domain prefixes it?

UPDATE 2

Are there any rewrite rules/conditions I could use on each of the http virtual hosts to only respond to the port it is listening on? My knowledge of rewrite rules etc are non-existent so I'm relying on good Google research skills to find me the write websites. I have stumbled upon this.

RewriteEngine On RewriteCond %{HTTP_HOST} ^yourdomain\.com [NC] RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L] 

UPDATE 3

I've fixed the issue.

However, if I was to access the example URL http://example.com:8080 I get a 403 forbidden error message

Forbidden You don't have permission to access this resource. 

How would I get Apache to timeout the connection rather than just flat out refuse it?

The two VirtualHost files now become:

/etc/apache2/sites-enabled/example.com

<VirtualHost *:80> ServerName example.com ServerAlias www.example.com ServerAdmin [email protected] DocumentRoot /var/www/example.com RewriteEngine On RewriteCond %{HTTP_HOST} example.com [NC] RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://www.example.com$1 [R,L] <Directory /> DirectoryIndex index.html index.php </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost> <VirtualHost *:443> ServerName example.com ServerAlias www.example.com ServerAdmin [email protected] DocumentRoot /var/www/example.com <Directory /> DirectoryIndex index.html index.php </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined SSLEngine On SSLCertificateFile "/etc/ssl/certs/example.com.crt" SSLCertificateKeyFile "/etc/ssl/private/example.com.key" SSLCertificateChainFile "/etc/ssl/certs/example.com.ca-bundle" </VirtualHost> 

/etc/apache2/sites-enabled/phpmyadmin.example.com

<VirtualHost *:8080> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com RewriteEngine On RewriteCond %{HTTP_HOST} phpmyadmin.example.com [NC] RewriteCond %{SERVER_PORT} 8080 RewriteRule ^(.*)$ https://phpmyadmin.example.com:8081$1 [R,L] </VirtualHost> <VirtualHost *:8081> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com DocumentRoot /usr/share/phpmyadmin <Directory /> DirectoryIndex index.html index.php </Directory> LogLevel notice CustomLog /var/log/apache2/access.log combined ErrorLog /var/log/apache2/error.log Include /etc/phpmyadmin/apache.conf SSLEngine On SSLCertificateFile "/etc/letsencrypt/live/phpmyadmin.example.com/cert.pem" SSLCertificateKeyFile "/etc/letsencrypt/live/phpmyadmin.example.com/privkey.pem" SSLCertificateChainFile "/etc/letsencrypt/live/phpmyadmin.example.com/chain.pem" </VirtualHost> 
8
  • what's on port 16081 ? Commented Sep 24, 2020 at 16:50
  • You can see the pattern of redirects being sent back to the brower using developer tools. usually right click, "inspect", and then switch to the network tab in firefox/chrome Commented Sep 24, 2020 at 16:53
  • @TomH I've updated the question. I accidentally left it in from my actual virtualhost Commented Sep 24, 2020 at 17:02
  • If I understand your update correctly, you want to do something different depending on whether the request is to http://phpmyadmin.example.com:8080 or http://example.com:8080. However that's exact what the other VirtualHost would do. Commented Sep 24, 2020 at 20:58
  • @TomH Yes if the request goes to http://phpmyadmin.example.com:8080 then PHPMyAdmin will load as normal. Requests going to http://example.com:8080 shouldn't do anything at all and eventually timeout. Commented Sep 24, 2020 at 21:02

1 Answer 1

0

personally, I would favour a solution using either a firewall, or ssh port forwarding and localhost, to expose the phpmyadmin service in a secure manner to trusted hosts, and definitely use decent authentication rather than "obscurity security". However to try to answer the question at hand...

Because you only have one VirtualHost on each port, the first one defined becomes the default for requests to that port, regardless of whatever domain name is set in ServerName and ServerAlias.

<VirtualHost *:8080> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com Redirect permanent / https://phpmyadmin.example.com:8081/ </VirtualHost> 

This is going to match any request to *:8080, including:

and redirect them to the service on port 8081.

In order to differentiate the requests, I would add a second VirtualHost on port 8080 which catches everything else (including http://example.com:8080), and redirects it somewhere non-existing which would cause a timeout.

<VirtualHost *:8080> ServerName example.com # redirect to somewhere non-existing will cause timeout Redirect permanent / https://192.168.99.99/ </VirtualHost> <VirtualHost *:8080> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com Redirect permanent / https://phpmyadmin.example.com:8081/ </VirtualHost> 

(note that the default one needs to come first)

Note:

How do I stop the main domain redirecting to the sub-domain and instead timeout as a typical server would?

Unfortunately, by the time apache has received the request and is processing it, the point at which it can tell whether the request is to http://phpadmin.example.com:8080 or http://example.com:8080, it is too late for apache itself to drop the initial connection and cause a timeout.

I would generally use a firewall for this purpose, either directly in iptables, or ufw/firewalld depending on your distribution, to limit access to port 8080 to only known trusted hosts.

Update: using mod_security

It looks like it might be possible to use the mod_security module to simulate the timeout: https://serverfault.com/a/401592/47650

so something like this would send a FIN packet to drop the connection after the request header was processed...

<VirtualHost *:8080> ServerName example.com SecRuleEngine On SecAction id:1,phase:1,nolog,drop </VirtualHost> <VirtualHost *:8080> ServerName phpmyadmin.example.com ServerAlias phpmyadmin.example.com Redirect permanent / https://phpmyadmin.example.com:8081/ </VirtualHost> 

https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-%28v2.x%29#drop

2
  • Needs a trailing slash to the target of the Redirect Commented Sep 25, 2020 at 15:15
  • 1
    @ezra-s edited. cheers Commented Sep 25, 2020 at 20:18

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.