Looking for a way to use --webroot but limit access


#1

On a macOS Server, Apache is a major workhorse, also for Server admin stuff. If I want to protect these with letsencrypt certs I need to expose this whole admin stuff to the outside world, and I’d rather not. So — and I know this is more an Apache question, but I suspect the know how is really here — I would like to configure my Apache to only accept outside traffic for http://mydomain.tld/.well-known/acme-challenge while allowing any other URL for my domain.tld only to be accepted when the request comes from the local net. This would effectively restrict outside access to letsencrypt, thus enabling the use of letsencrypt certs without exposing the whole admin interface to the outside world.

Another option would be to have everything that comes from the outside be served from a different directory on my server.

Can someone tell me how to do this?


#2

There are many ways to do access control in Apache - https://httpd.apache.org/docs/current/howto/auth.html .

Which particular directives would work for you depends on how your virtual hosts are setup.

A very basic example:

<VirtualHost *:80>
    ServerName example.org
    DocumentRoot /var/www/html
    AliasMatch ^/\.well-known/acme-challenge/([A-Za-z0-9-_=]+)$ /var/www/letsencrypt/.well-known/acme-challenge/$1
    <Directory /var/www/html>
        Require ip 1.2.3.4
    </Directory>
    <Directory /var/www/letsencrypt>
        Require all granted
    </Directory>
</VirtualHost>

which would allow you to run Certbot with --webroot -w /var/www/letsencrypt.

But of course, if you’re doing things like reverse proxying, it needs to be adjusted.

Edit: fixed a problem with the alias


#3

Thank you. I created my question in a simple way, but the situation in reality is hideously complex. Maybe I should not have tried to ask a simple question. Hence, I’m a bit uncertain (lack of experience) how to use this to create the situation that https://domain1.mydomain.tld/.well-known/etc/ is visible from the outside while the rest of https://domain1.mydomain.tld/ is not, and at the same time have https://domain2.mydomain.tld/ entirely visible from the outside. Especially, because accessing the site I want to block (but allow letsencrypt to access) produces redirects like https://domain1.mydomain.tld/auth?redirect=https://domain1.mydomain.tld/devicemanagement/webapi/authentication/callback and the actual URLs are all apparently rewritten, there is proxying, and it is not just simple directory access.

After studying all of this some more I’m afraid this is too complex for me to find out in reasonable time.


#4

One way to dodge the complexity is to just use the DNS challenge, which takes your web server out of the equation completely.

It does introduce the requirement that you use a “friendly” DNS host (one with API access and preferably one that people have already integrated into Certbot or acme.sh).

Well, it’s still possible with the approach I documented above. You just need to switch around Directory for Location and a couple other adjustments. But like I said, it depends a lot on seeing exactly how your virtual hosts are configured in reality.


#5

I found a very simple solution to be able to use Letsencrypt certificates:

Instead of messing around with Apache, I just used the NAT on my router. I client on the outside trying to connect to port 80 of serverhost.mydomain.tld gets translated to my internal serverhost.mydomain.tld:8079 where a separate small web server is running that is there just for letsencrypt. Now, certbot can use the document root of that server. On the inside, going to port 80 of that server just gets you the Server admin.


#6

If you literally don’t need that web server for anything, you could also try --standalone --preferred-challenges http-01 --http-01-port 8079 (instead of --webroot), which would probably work just as well but wouldn’t require the web server to be running at other times.