1

I have a website where I'm wanting 1 file (version.txt) to be accessible via regular HTTP, but I want everything else to redirect to https. To do this, I added the "RedirectMatch" line below in my /etc/httpd/conf.d/somewhere.com.conf file (running centos7). Before I wanted to serve this file via HTTP, the line was a "Redirect permanent" type line. When I first made this change, I did some tests and it appeared to work; I was definitely able to access version.txt with plain HTTP, and I thought other accesses were being redirected to https. However, I just navigated to the website today and noticed it was all coming over HTTP. I have very little knowledge with websites, so I'm guessing that my testing for the redirect was faulty due to browser caching or something that tricked me into thinking it was working.

The question: in my conf.d file below, why doesn't the website redirect everything except version.txt to https? How can I change it so that it allows HTTP access of version.txt, but redirects everything else to HTTPS?

(bonus if you have any ideas on what fooled me into thinking it was working at first)

<VirtualHost *:80>
  ServerName somewhere.com
  ServerAdmin [email protected]
  DocumentRoot /var/www/somewhere.com
  ErrorLog /etc/httpd/logs/error_log_somewhere
  CustomLog /etc/httpd/logs/access_log_somewhere combined
  RedirectMatch permanent "^(/*version.txt/.*)" https://somewhere.com$1
</VirtualHost>
<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/pki/tls/certs/somewhere.com_ssl_certificate.cer
  SSLCertificateKeyFile /etc/pki/tls/private/_.somewhere.com_private_key.key
  SSLCertificateChainFile /etc/pki/tls/certs/_.somewhere.com_ssl_certificate_INTERMEDIATE.cer
  ServerName somewhere.com
  ServerAlias www.somewhere.com
  ServerAdmin [email protected]
  DocumentRoot /var/www/somewhere.com
  ErrorLog /etc/httpd/logs/error_log_somewheres
  CustomLog /etc/httpd/logs/access_log_somewheres combined
</VirtualHost>
ServerSignature Off
ServerTokens Prod
Header always append X-Frame-Options SAMEORIGIN
5
  • Similar (but not duplicate) question: Redirect all URLs exactly except one URL that must be redirected to a different URL Commented Oct 14, 2022 at 15:19
  • Thanks Stephen, I used similar questions to figure out the initial setup. Since it's all so new to me, the site is live, and I don't have access to a test setup right now, I was hoping somebody might be able to look at it and easily see what I did wrong. If it ends up not being that easy though, I'll put a test setup together to tinker with
    – Dtor
    Commented Oct 14, 2022 at 17:17
  • Is AllowOverride being set somewhere allowing .htaccess to over ride your .conf settings. I'm reading the conf as redirect for only (star)version.txt.(star), as I don't see the not in the code. So the .htaccess may be redirecting everything? Commented Oct 15, 2022 at 1:35
  • I was thinking the ^ at the beginning of the regex meant 'not', is that not the case? What I pasted is the entire .conf file, is AllowOverride default on or where else can it be set?
    – Dtor
    Commented Oct 18, 2022 at 13:45
  • Ah ok, you are correct, AllowOverride is set in the conf/httpd.conf file
    – Dtor
    Commented Oct 18, 2022 at 13:50

1 Answer 1

3

If it were me; I would set up to give the http its own directory and redirect anything that would be a 404 to the https using the .htaccess of http location. This keeps things easy to understand for any future revisits to how the site is working, and uses coding that is well established and followed by anyone else who may need to work on the site.

A a2enmod rewrite (apache2) may be required if you are self hosting or VPS hosting to enable rewrite mod; but it appears to be already enable? in your case.

The .conf you are using

<VirtualHost *:80>
  ServerName somewhere.com
  ServerAdmin [email protected]
  DocumentRoot /var/www/port80-somewhere.com
  ErrorLog /etc/httpd/logs/error_log_somewhere
  CustomLog /etc/httpd/logs/access_log_somewhere combined
</VirtualHost>
# allow .htaccess over ride may already be allowed.
<Directory /var/www/port80-somewhere.com/>
    Options -Indexes FollowSymLinks
    AllowOverride all
    Require all granted
</Directory>

CentOS 7 may want to AllowOverride here /etc/httpd/conf/httpd.conf But I think it is already allowed.

<Directory /var/www/port80-somewhere.com/>
    Options -Indexes FollowSymLinks
    AllowOverride all
    Require all granted
</Directory>

/var/www/port80-somewhere.com/.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]

Thus; if version.txt exists in /var/www/port80-somewhere.com/ it will be presented from port 80. Anything that does not exist in /var/www/port80-somewhere.com/ is 301ed to the secure site. So you can pick and choose at will what will be available on http without needing to reconfigure.

Note: I would also put the favicon.ico in /var/www/port80/favicon.ico because the browser will ask for it.

Update

The .htaccess is a derivative of Apache documentation, which is in common usage by Wordpress sites.

# Apache configuration file
# http://httpd.apache.org/docs/2.2/mod/quickreference.html

# Turning on the rewrite engine is necessary for the following rules and
# features. "+FollowSymLinks" must be enabled for this to work symbolically.

<IfModule mod_rewrite.c>
    Options +FollowSymLinks
    RewriteEngine On
</IfModule>

# For all files not found in the file system, reroute the request to the
# "index.php" front controller, keeping the query string intact

<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

Except as you noted does not redirect the root of the domain itself. Sorry I missed that.

  • First condition... the file "-f" requested does not "!" exist.
  • Second condition ... the request is not "!" a directory "-d"
  • Third condition ... we don't want the root index.php or index.html either. If the request URI is HTTP://example.com/ the requested URI is "/" or ^/$ as the condition.

The one you are using per comments is good. My thought of using the %{REQUEST_URI} is that if revisited in the future the only thing that may need to be changed is the site within "". So less things to go wrong.

If conditions are true 301 to new location.

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]

RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ "https://example.com/$1" [R=301,L]

We need to use the rewrite engine. Depending on the build if one is using the installed version of apache from the linux os. It may not be turned on? Apache came to the rescue with a2enmod ... which allows it to be turned on in a way that will not break on a future release, (thank you Apache).

The virtual host looks fairly off the shelf so it will not break in future releases. But we need to allow .htaccess so we can configure directories to rewrite etc using .htaccess so that we don't need to restart the server. The derivative of /etc/apache2/sites-available/000-default.conf use AllowOverride all.

<Directory /var/www/port80-somewhere.com/>
    Options -Indexes FollowSymLinks
    AllowOverride all
    Require all granted
</Directory>

Specifically in the directory where HTTP exists. We want .htaccess enabled. "AllowOverrided all" does this; and "Require all granted" is the newer syntax of "Allow from all" which relates to blocking IP addresses from access to the host, don't want to block anyone, "all granted"; The -Indexes is turning off listing of the files in a directory, there is not one but we don't want to need to change this if usage changes.

All these might be turned on by some builds but if we need to move the site, nice if we can do that without issues.

5
  • Thanks Wayne, this looks to work but I'm having 1 issue. If I navigate directly to http:// somewhere.com, it does not get redirected and I get a "Not Found\nThe requested URL / was not found on this server." If I navigate to http:// somewhere.com/index.html it redirects correctly. Is there something I can add so that just http:// somewhere.com gets redirected? (added spaces after http:// because it was auto removing it and turning into a link)
    – Dtor
    Commented Oct 18, 2022 at 14:53
  • Also, could you explain the bottom 3 lines of the port80 .htaccess? Would like to better understand what they're doing
    – Dtor
    Commented Oct 18, 2022 at 14:55
  • Looking around, I added these lines to the end of the port80 .htaccess (seems to fix the 1 problem, please let me know if it might cause some other issue): RewriteCond %{HTTP_HOST} somewhere\.com [NC] RewriteCond %{REQUEST_URI} ^/$ RewriteRule ^(.*)$ somewhere.com [L,R=301]
    – Dtor
    Commented Oct 18, 2022 at 15:13
  • @Dtor Oops, I missed that; thank you. The rewritecond is the same as I would use although there are others and we can use it as the third condition of this htaccess. The %{HTTP_HOST} has already become true for this htaccess because we simplified the solution in creating a /port80-somesite.com/ directory. Port 80 is HTTP_HOST and Port 443 is the HTTPS host. No need for using HTTP_HOST with this simplified solution. Commented Oct 18, 2022 at 23:40
  • Wayne, many thanks for all the help! I like the solution you put together, was very easy to follow and works!
    – Dtor
    Commented Oct 19, 2022 at 0:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.