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.
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:
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>