Help with Apache redirects/rewrites

I’ve been scratching my head for the last couple of weeks trying to figure out how to set up a Virtual Host configuration in Apache to allow HTTP validation, and still let my web app run, but I must be missing something pretty fundamental. Hopefully someone here can point it out.

I’m running Apache 2.4.6 under CentOS 7, and I’m trying to get Phabricator working on this system. Phabricator requires its own hostname (it has to be, say, phabricator.example.com, not www.example.com/phabricator), and requires its own rewrite rule in the virtual host configuration. I, of course, want to serve it (and everything else) over HTTPS rather than HTTP. I’ve tried a number of configurations that I haven’t kept notes on. Most recently, following something I ran across in another thread, I’ve tried this:

<VirtualHost *:80>
  DocumentRoot "/var/lib/nethserver/vhost/phab/phabricator/webroot"
  ServerName phab2.mydomain
  RewriteEngine on
  RewriteRule ^\.well-known/ - [L]
  RewriteRule (.*) https://phab2.mydomain/$1 [R,L]
  Alias "/.well-known/acme-challenge/" "/var/www/html/.well-known/acme-challenge/"
  <Directory "/var/www/html/.well-known/acme-challenge/">
     Require all granted
     Options -Indexes -FollowSymLinks
     AllowOverride None
  </Directory>
</VirtualHost>

<VirtualHost *:443>
  DocumentRoot "/var/lib/nethserver/vhost/phab/phabricator/webroot"
  ServerName phab2.mydomain
  RewriteEngine on
  RewriteRule ^(.*)$          /index.php?__path__=$1  [B,L,QSA]
  SSLEngine on
  <Directory "/var/lib/nethserver/vhost/phab/phabricator/webroot">
    Require all granted
  </Directory>
</VirtualHost>

But that doesn’t seem to be having the desired effect–when I try to reach /.well-known/acme-challenge/blah, I get redirected to https:

[root@neth-phab virtualhosts.conf]# curl http://localhost/.well-known/acme-challenge/test
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://phab2.mydomain//.well-known/acme-challenge/test">here</a>.</p>
</body></html>

I’m sure I’m missing something pretty obvious, but the rewrite expressions are pretty opaque to me. Thoughts?

I think it’s mostly a confusion over how RewriteCond/RewriteRule work. Those two RewriteRules you have are applied independently, they are not stacking conditions.

What you probably want is:

RewriteCond %{REQUEST_URI} !^/\.well-known/
RewriteRule (.*) https://phab2.mydomain$1 [R,L]

Your suggested fix is correct, but I think your reasoning is wrong. The [L] flag should stop further processing and result in the second RewriteRule being ignored. The reason it doesn't is that the text being matched against includes the leading slash when RewriteRule is used in a VirtualHost context rather than a Directory/.htaccess context:

In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). This is the (%-decoded) URL-path.

In per-directory context (Directory and .htaccess), the Pattern is matched against only a partial path, for example a request of "/app1/index.html" may result in comparison against "app1/index.html" or "index.html" depending on where the RewriteRule is defined.

So an alternative (but inferior IMO) fix would be to add the slash to the first RewriteRule and remove it from the second:

RewriteRule ^/\.well-known/ - [L]
RewriteRule (.*) https://phab2.mydomain$1 [R,L]

Well, what I'd understood they'd do was that the first rule would pass through requests beginning with .well-known unchanged, and then stop evaluating further rules (the redirect to "-" followed by the [L]). Then the second rule, if it got there (i.e., if the request didn't begin with .well-known) would redirect to HTTPS.

I'm still getting (almost--the double slash in the redirect is gone) the same result with that:

[root@neth-phab virtualhosts.conf]# curl http://localhost/.well-known/acme-challenge/test
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://phab2.mydomain/.well-known/acme-challenge/test">here</a>.</p>
</body></html>

This appears to work. Cool, thanks!

Hmm, well I’m glad it worked, but _az’s suggestion should have worked too. Maybe you missed that the first line became RewriteCond?

Nope, copied/pasted directly from his post (though then edited the actual domain back in).

Hm, weird, it works for me. Maybe it’s a difference between Apache 2.4.6 and 2.4.29…

Anyway glad you got it working :smiley:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.