Certbot fails to authenticate using webroot authenticator

I believe my issue lies within my nginx server configuration. I believe i set up automatic redirect to HTTPS with a self-signed certificate, then set up the well-known location here. Just in case i also set-it up to work with http.

here is my nginx config:

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
include /etc/nginx/conf.d/sites-enabled/*.conf;

and my homepage config included by the last line above:

server {
listen 443 ssl;
server_name mazornas.net;
include common.conf;
include /etc/nginx/ssl.conf;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}

My domain is: mazornas.net

I ran this command:

using docker:

docker-compose run --entrypoint "
certbot certonly --webroot -w /var/www/certbot
--staging
--email notmyrealemail@gmail.com
-d mazornas.net
--rsa-key-size 4096
--agree-tos
--force-renewal" certbot --verbose

It produced this output:

Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
Domain: mazornas.net
Type: connection
Detail: Fetching http://mazornas.net/.well-known/acme-challenge/xTezBdwjULqJsobLqmiLD8phsPXs_c4N-T_b_6s178I: Timeout during connect (likely firewall problem)

My web server is (include version): nginx version: nginx/1.21.6

The operating system my web server runs on is (include version):
I am using the official nginx docker container which uses
Debian GNU/Linux 11 (bullseye)

My hosting provider, if applicable, is: namecheap

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): the official certbot docker (certbot 1.25.0)

Is 87.68.244.86 the server's actual IP address?

If you host it at home, did you enable port forwarding?

Did you check your firewalls? (OS, router, ISP, ...)

(Your config is a bit messy... but it doesn't matter, it should work)

You did mount the right volumes, right? (The docker-compose command is also messy: you can usually do docker-compose run servicename command)

1 Like

Is 87.68.244.86 the server's actual IP address?
Yes

If you host it at home, did you enable port forwarding?
also, yes

Did you check your firewalls? (OS, router, ISP, ...)
the web server works (its just a reverse proxy wthat you can reach with subdomains

(Your config is a bit messy... but it doesn't matter, it should work)
yeah, sorry a bit confusing since i copied from an online tutorial and played with it a bit to try to get it to work

You did mount the right volumes, right? (The docker-compose command is also messy: you can usually do docker-compose run servicename command )
i believe so. (and yes i'm also copying from a script i found for first time set-up with let's encrypt)

I'm not sure my automatic redirect works well either, it seems like it only sometimes works.

Well... I can't reach it. And neither can the validation bots.

And ok, I just realized what the problem is: you are only listening on port 443. You must listen on port 80 (forward it!) as well, to use http-01.

% nmap mazornas.net
Starting Nmap 7.92 ( https://nmap.org ) at 2022-04-02 21:41 CEST
Nmap scan report for mazornas.net (87.68.244.86)
Host is up (0.093s latency).
rDNS record for 87.68.244.86: 87.68.244.86.adsl.012.net.il
Not shown: 998 filtered tcp ports (no-response)
PORT     STATE SERVICE
443/tcp  open  https
1122/tcp open  availant-mgr

Nmap done: 1 IP address (1 host up) scanned in 9.33 seconds
%
2 Likes

I can't reach port 80 neither.

Either local firewall on the server, firewall in the router, missing/incorrect NAT portmap in the router, missing Docker port statement or ISP firewall.

2 Likes

Seems I got port 80 working now. must have forgot to forward the port.

My next question is if each subdomain needs its own certificate or not. since namecheap does not natively support let's encrypt i understand i cannot use wildcard subdomains.

You can use one certificate per subdomain or one certificate for all subdomains -- and any permutation in between.

It's up to you.

You can also host your DNS elsewhere if you so desire, it doesn't have to be your registrar's. But dns-01 validation is easier to break than http-01: if you can, it's easier not to use it.

1 Like

What is this about?:

2 Likes

This doesn't make too much sense either. Using RSA4096 "because it's safer" without considering how much slower (A LOT) it is is not a good thing and the main advantage of it are bragging rights.

@mazora please use an ecdsa p-256 key if you want stronger encryption, or stick with RSA2048. If you want to go for overkill, p-384 is an option (but it will be slow. not as slow as RSA4096, tho, and with security equivalent to an rsa key three times as long.)

1 Like

I've been using this script: nginx-certbot/init-letsencrypt.sh at master · wmnnd/nginx-certbot · GitHub
to initialize certbot for for the first time.

I was following this online tutorial: Nginx and Let’s Encrypt with Docker in Less Than 5 Minutes | by Philipp | Medium

Is there any issue using force-renewal? as an initializing script it shouldn't affect it correct?
otherwise i will use certbot renew for every future call to cerbot

Will do! According to the documentation, i need to add this option in order to request ecdsa certificate?

--key-type ecdsa

Is there any other options to specify length?

Thanks

1 Like

Anything that uses a forced renewal is a bad example.

1 Like
  --key-type {rsa,ecdsa}
                        Type of generated private key. Only *ONE* per
                        invocation can be provided at this time. (default:
                        rsa)
  --elliptic-curve N    The SECG elliptic curve name to use. Please see RFC
                        8446 for supported values. (default: secp256r1)

You should keep the default. The only other option is secp384r1, which is overkill.

1 Like

I updated my server to use ecdsa but it causes problem when connecting through TLS.
On my chrome browser i receive this error:
ERR_SSL_VERSION_OR_CIPHER_MISMATCH

Using wireshark i see there is a client hello:

Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random: 6b2ee46154f31c420877043b2cce5a8aa3ae04a1f879a2e4de621c513b82e508
Session ID Length: 32
Session ID: a7456b4748076039814872723f0c72fa2f8de468ef5e4c115723026371e164ec
Cipher Suites Length: 32
Cipher Suites (16 suites)
Cipher Suite: Reserved (GREASE) (0xdada)
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302)
Cipher Suite: TLS_CHACHA20_POLY1305_SHA256 (0x1303)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
Cipher Suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9)
Cipher Suite: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c)
Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d)
Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f)
Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 403
Extension: Reserved (GREASE) (len=0)
Extension: server_name (len=20)
Extension: extended_master_secret (len=0)
Extension: renegotiation_info (len=1)
Extension: supported_groups (len=10)
Extension: ec_point_formats (len=2)
Extension: session_ticket (len=0)
Extension: application_layer_protocol_negotiation (len=14)
Extension: status_request (len=5)
Extension: signature_algorithms (len=18)
Extension: signed_certificate_timestamp (len=0)
Extension: key_share (len=43)
Extension: psk_key_exchange_modes (len=2)
Extension: supported_versions (len=7)
Extension: compress_certificate (len=3)
Extension: Unknown type 17513 (len=5)
Extension: Reserved (GREASE) (len=1)
Extension: padding (len=200)

the server response is:

Transport Layer Security
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.2 (0x0303)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)

Any idea why this could be happening?

Check the ssl_protocols directive

http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols

2 Likes

How old is your version of Chrome?
Is this a public site that we can also test?

update: If this site, it only support TLSv1.3 [not TLSv1.2]

1 Like

Got it working, just updated ssl_protocols to include TLSv1.3.

Is there any reason why ssl_prefer_server_ciphers directive should be off?

No. I would keep it on.

1 Like

Actually, there is. But it depends on which ciphers you enabled.

If you only have strong ciphers, turn it off.

For example, if you only have AES GCM and CHACHA20 (defaults for TLS 1.3 that also work for 1.2), turn it off: it will allow phones to use CHACHA20 while PCs will use AES GCM, every client will use the faster and more optimized cipher, instead of the same for everybody.

But, if you want to support clients with older ciphers... That depends on how old.

3 Likes

@9peppe
That assumes the clients have their cipher list preference in a proper order.
From what I've seen MS do with Windows, I'd say that is not the case.
I'd rather control that at the server than leave it to the clients.

1 Like