Renewing fails when no vhost runs on port 80, but new certs are issued just fine

I have discovered a strange conundrum, I’m using the HTTP authentication for my certificate, which sits behind a varnish cache. This means varnish is listening on port 80, while apache listens on port 443 and 8080 (the latter redirects to 443 if accessed directly).

When trying to renew a certificate, either manually, or with certbots automatic cron task, it fails as there’s no virtual host in apache listening on port 80, this seems like a strange limitation to me, given that I can create a new certificate just fine without certbot trying to look for port 80.

My site, as denoted below in the information sheet, does have a valid certificate at this time, as I just issued a new one, given that the expiration date had passed and it doesn’t look good to have an invalid certificate. I’m not sure if this should be filed as a bug or not on Github, given that the interaction between registration and renewal have different criteria.


My domain is:

I ran this command:
certbot renew

It produced this output:
Attempting to renew cert (clorith.net) from /etc/letsencrypt/renewal/clorith.net.conf produced an unexpected error: Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80… Skipping.

My web server is (include version):
apache2 - 2.4.18-2ubuntu3.9
varnish - 4.1.10-1~xenial

The operating system my web server runs on is (include version):
Ubuntu 16.04.5 LTS

I can login to a root shell on my machine (yes or no, or I don’t know):
yes

I’m using a control panel to manage my site (no, or provide the name and version of the control panel):
no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot):
certbot 0.28.0

Hi @Clorith

yep, you have a new certificate:

CN=clorith.net
	26.01.2019
	26.04.2019
	clorith.net, www.clorith.net - 2 entries 

And your http is redirected to https:

http is varnish, https is Apache.

Is there another cron job with a webroot option?

What says

certbot certificates

Certbot’s Apache authenticator doesn’t really understand setups that are more complicated than the standard. For example Varnish(80)->Apache(non-80) is beyond its abilities. For this, there would need to be a “Varnish authenticator”, but it doesn’t exist.

So you might have better luck using the webroot authenticator and the Apache installer together, e.g.

certbot renew --cert-name clorith.net \
-i apache -a webroot -w /path/to/websites/webroot --dry-run

The Apache authenticator might work if you use “--http-01-port 8080” though.

Oh, I may have been a bit vague, I apologize for that.

I am using webroot authentication already, and passing the --http-01-port 8080 won’t work due to the redirect apache has for “outside users” (not being redirected internally from varnish, to avoid direct access bypassing the cache layer, varnish has handling for access to /.well-known/*).

The webroot auth is being used during the renewal, as it was used for the initial registration, but because of the port 80 checker, it never gets to that point.

Could you share the contents of the file /etc/letsencrypt/renewal/clorith.net.conf? It really sounds like it’s not using the webroot authenticator, as webroot doesn’t know or care about virtual hosts.

Happy to! I’ve redacted the account hash (I don’t know what it does, but I like to stay on the cautious side :slight_smile: )

# renew_before_expiry = 30 days
version = 0.28.0
archive_dir = /etc/letsencrypt/archive/clorith.net
cert = /etc/letsencrypt/live/clorith.net/cert.pem
privkey = /etc/letsencrypt/live/clorith.net/privkey.pem
chain = /etc/letsencrypt/live/clorith.net/chain.pem
fullchain = /etc/letsencrypt/live/clorith.net/fullchain.pem

# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = apache
account = <removed>
server = https://acme-v02.api.letsencrypt.org/directory
webroot_path = /home/clorith/public_html,
[[webroot_map]]
www.clorith.net = /home/clorith/public_html
clorith.net = /home/clorith/public_html

That’s surprising, you are using the webroot authenticator. You’re using the apache installer, but that shouldn’t complain about a missing virtualhost on port 80 as it doesn’t need one. I guess it might complain anyway due to a bug, but if such a bug exists, I can’t reproduce it :frowning:

Maybe check in /etc/letsencrypt/cli.ini to see if there’s anything there that might be forcing the apache authenticator to be used?

If not, I’d recommend trying @mnordhoff’s suggestion, even if it doesn’t seem like it should be relevant, as it might still cause the virtualhost check to look for port 8080 instead of port 80.

Or if there is some bug in the apache installer, you could take it out of the picture and use a deploy hook to reload apache after renewal instead, for example: certbot renew --dry-run --cert-name clorith.net --installer none --deploy-hook "service apache2 reload" (and again without --dry-run if it works).

1 Like

Passing it --installer none didn’t change the outcome.

Using --http-01-port 8080 didn’t complain about the port, but for whatever reason never created the challenge file in /.well-known/ like it should have, so it returned a 404 response instead.

I could create my own task scheduler that looks at expiry times and just issues a new certificate if it’s up for renewal, that’s not the best approach, but would work around this strange behavior since I can still issue new certs just fine.

Since you don’t mention it, did you check /etc/letsencrypt/cli.ini? That’s the only thing I can think of that would cause renewals to break in this way, while still allowing “new” issuance to work (e.g. if you explicitly specified -a webroot on the command line).

Sorry, missed the cli.ini question.

it’s a very bare file, nothing there indicating anything.

# Because we are using logrotate for greater flexibility, disable the
# internal certbot logrotation.
max-log-backups = 0

I can do certbot renew -a webroot --webroot-path /home/clorith/public_html and it will renew the certificate, but that obviously requires me to pass in the webroot path as well, which isn’t what certbot renew does by it self.

Hmmmm. That really sounds like some default setting forcing the apache authenticator to be used, that is overridden when you specify -a webroot explicitly from the command line. But cli.ini is the only thing I know of that could do that.

There may be another one in $HOME/.config/letsencrypt/cli.ini (or /root/.config/letsencrypt/cli.ini) so it might be worth checking there too?

Never did see this output:

Hi, apologies for the delay here, flu season ahs been exceptionally rough.

The certbot certificates output is as follows:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
  Certificate Name: clorith.net
    Domains: clorith.net www.clorith.net
    Expiry Date: 2019-04-26 21:42:59+00:00 (VALID: 72 days)
    Certificate Path: /etc/letsencrypt/live/clorith.net/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/clorith.net/privkey.pem
  Certificate Name: rstt.net
    Domains: rstt.net www.rstt.net
    Expiry Date: 2019-04-27 18:19:55+00:00 (VALID: 73 days)
    Certificate Path: /etc/letsencrypt/live/rstt.net/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/rstt.net/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

They are both my sites hosted on the same box (I’ve had to do the registration, not renewal, on both of them).

There’s also no cli.ini in any of the config directories, so nothing overriding things there.

I think the problem may be with the expected outcome of using –http-01-port

From: https://certbot.eff.org/docs/using.html

  --http-01-port HTTP01_PORT
                        Port used in the http-01 challenge. This only affects
                        the port Certbot listens on. A conforming ACME server
                        will still attempt to connect on port 80. (default:
                        80)

Certbot can’t listen on 8080 as Apache is already listening on 8080.
And all LE requests will still go to FQDN:80

I’m not trying to run certbot in standalone mode though, I am just trying to have it renew via http auth, the same way they were first registered. The webserver is listening on port 80 (via varnish, which is properly redirecting the requests, or else new cert registrations would also fail).

The problem at the root of all of this is I’m somehow being required to run port 80 on apache for it to renew over http.

I’m going to try re-installing certbot, as something is definitely acting weird, will update once that’s done and tested :+1:

I don't think this will change much...

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