4

Here is my situation:

  • Server A: support.example.com -> port 80 is forwarded to this server
  • Server B: hr.example.com

Both are running apache2.

For server B I want to use Let's encrypt. I want to redirect all HTTP requests to HTTPS except for location ./well-known/acme-challenge in order to be able to renew certificate.

Here is my virtualhost of server A:

<VirtualHost *:80>
  ServerName hr.example.com
  Redirect / https://hr.example.com

  RewriteEngine on
  RewriteRule ^"/.well-known/acme-challenge\$" "<IP-SERVER B>/.well-known/acme-challenge" [PT]
</VirtualHost>

But this results in requests to http://hr.example.com/.well-known/acme-challenge being redirect to HTTPS indeed. How can I make an exception?

  • "Here is my virtualhost of server A" - don't you mean "server B"? – MrWhite May 31 '18 at 11:28
  • No, as port 80 is forwarded to server A, I make the redirects to https on this virtualhost. – WouterVE May 31 '18 at 11:32
  • It's just that you state "Server B: hr.example.com" and in your code sample you have ServerName hr.example.com? – MrWhite May 31 '18 at 12:55
  • Yes but that's the point of this virtualhost on Server A: it must redirect requests to hr.example.com to the correct server (=B) where this site is located hence the ServerName hr.example.com. In the Vhost of server B I have also the same ServerName. – WouterVE Jun 1 '18 at 9:43
2

The Acme Challenge protocol that the LetsEncrypt bot uses will happily follow redirects. There is no need to reverse proxy the requests to another machine, you can simply redirect those requests there.

I would first create a specific redirect for the challenge and then redirect everything else to HTTPS:

<VirtualHost *:80>
  ServerName hr.example.com
  Redirect permanent /.well-known/acme-challenge/ http://support.example.com/.well-known/acme-challenge/
  Redirect permanent / https://hr.example.com/
</VirtualHost>

I just tested this set of rules on my server by creating this virtual host and putting hr.example.com into my /etc/hosts file as 127.0.0.1.

# curl -s --head http://hr.example.com/
HTTP/1.1 301 Moved Permanently
Location: https://hr.example.com/

# curl -s --head http://hr.example.com/.well-known/acme-challenge/foo
HTTP/1.1 301 Moved Permanently
Location: http://support.example.com/.well-known/acme-challenge/foo

It is often problematic to mix rewrite rules and redirect directives. It isn't always clear which will be executed first. If you do want to use the proxy method, I would switch your redirect to a rewrite rule that follows the proxy directive. I changed your rewrite rule a bit too. It should be a proxy rule ([P]) not a pass-through rule ([PT]). You also need to proxy every file within that challenge directory, not just the directory itself.

<VirtualHost *:80>
  ServerName hr.example.com    
  RewriteEngine on
  RewriteRule ^/.well-known/acme-challenge/(.*) http://<IP-SERVER B>/.well-known/acme-challenge/$1 [P,L]
  ProxyPassReverse /.well-known/acme-challenge/ http://<IP-SERVER B>/.well-known/acme-challenge/
  RewriteRule /(.*) https://hr.example.com/$1 [R=301,L]      
</VirtualHost>

I blogged about similar problems that I had. A trick that I found helpful but which doesn't appear to exactly match your situation was to create an exception to proxy rules. If you are reverse proxying your entire site but you want to make an exception to handle the acme challenge locally (or allow it to be redirected) you can prevent the proxying of that directory with:

# Don't allow this directory to be reverse proxied
ProxyPass /.well-known/acme-challenge/ !
  • Thanks for your input, but all my requests are still redirected to https, even when I add the extra ProxyPass exception. FYI: I'm using apache2.4.18-2ubuntu3.8 – WouterVE May 31 '18 at 11:16
  • I just tested the first configuration I suggested and it works just fine. I added the results of my testing to my answer. Use that one. – Stephen Ostermiller May 31 '18 at 12:43
  • It works with the redirect directives: yesterday I skipped this option and used rewriterule but apparently redirects fit my use case better. I have the same output for curl as your example. Thank you! – WouterVE Jun 1 '18 at 9:09

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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