Error while renewing certificate under Nginx + NodeJS

Hi,

I have successfully created https certificate and is currently running live on my server. And the certs are due for renewal.

My server environment in AWS is:

Ubuntu 16.04
Nginx server set to https
Node JS server

When I try to renew (even the dry run) I the following error on the terminal window

Attempting to renew cert from /etc/letsencrypt/renewal/xxx.conf produced an unexpected error: Failed authorization procedure. xxx.com (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Could not connect to xxx.com, www.xxx.com (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Could not connect to www.xxx.com. Skipping.

The server is live and running.

Any help will be appreciated.

Thanks,

What’s your website? Does it have IPv6? If so, does it work? Can you make a successful HTTP connection?

1 Like

Hello mnordhoff,

Thanks for the response,

a. the website is: letsNibbl.com

b. I do not think it has been set for IPv6. Is there a way to confirm that?

c. I have been using the site for the last 2 months and renewal is due next week.

Well, the DNS records just have an IPv4 address.

June 25. You have a little more time.

Maybe you should try again? If i try to access it from [very far away] it works. Get a redirect to HTTPS, then a 404 error. If the server's not configured to serve the challenge files, it will fail to validate, but Let's Encrypt would return a different error message. :confused:

My suspicion is that the url fired by the renewal is being addressed by the NodeJS server which must be rejecting the url and hence the error.

My current ngnix server config is:

server {

    listen 80 default_server;

    listen [::]:80 default_server;

    server_name letsnibbl.com www.letsnibbl.com;

    return 301 https://$server_name$request_uri;

}

I was reading some of the community blogs and one suggestion is to change it to:

server {

    listen 80 default_server;

    listen [::]:80 default_server;

    server_name letsnibbl.com www.letsnibbl.com;

    location /.well-known {
       alias /var/www/letsencrypt/.well-known;
   }
     location / {
        return 301 https://$server_name$request_uri;
   }

}

Would you think that would solve the issue?

Thanks, mnordhoff, for the help and prompt responses.

That's exactly what it does. But Let's Encrypt should report a different error, not "Could not connect". :confounded:

That Nginx config looks about right, and is a good idea, but it might not solve this issue.

I made changes to the Nginx conf but still does not work. I have given the following commands and both give the same error

sudo certbot renew --dryrun

as well as

sudo /usr/bin/certbot renew --quiet --renew-hook "/bin/systemctl reload nginx"

Attempting to renew cert from /etc/letsencrypt/renewal/letsnibbl.com.conf produced an unexpected error: Failed authorization procedure. letsnibbl.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://letsnibbl.com/.well-known/acme-challenge/IK3XfSMq-wg7jwNmnB-s-kSFxDAgJgqPZSkpL41lvDg: "<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>", www.letsnibbl.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.letsnibbl.com/.well-known/acme-challenge/kWjvkpwVLbd93s6bprU289Fck05CS2_7fdQEpfuP7KI: "<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>". Skipping.

I find that the redirection does not seem to be working. When I call the url from my browser, it still throws the error page that NodeJS throws on an invalid url.

The full conf in default of ngnix/sites-enabled is

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name letsnibbl.com www.letsnibbl.com;
    location /.well-known {
        alias /var/www/letsnibbl/.well-known;
    }
    location / {
        return 301 https://$server_name$request_uri;
    }
}

server {
   # SSL configuration

    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/ssl-letsnibbl.com.conf;
    include snippets/ssl-params.conf;

    location / {
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-NginX-Proxy true;
          proxy_pass http://localhost:8080/;
          proxy_ssl_session_reuse off;
          proxy_set_header Host $http_host;
          proxy_cache_bypass $http_upgrade;
          proxy_redirect off;
    }
}

yes the challenge goes to http://FQDN/.well-known/acme-challenge/LOLNUMBERSANDLETTERSANDCHARSLOL

I created the directory and placed a text file. When I call the url from the browser it shows its content.

However, when I try a dry run using

sudo certbot renew --dry-run

it shows

Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/letsnibbl.com.conf
-------------------------------------------------------------------------------
Cert is due for renewal, auto-renewing...
Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for letsnibbl.com
http-01 challenge for www.letsnibbl.com
Waiting for verification...
Cleaning up challenges
Attempting to renew cert from /etc/letsencrypt/renewal/letsnibbl.com.conf produced an unexpected error: Failed authorization procedure. www.letsnibbl.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://www.letsnibbl.com/.well-known/acme-challenge/VZ0GyF0hgS_nykbkAR9-NzNgcNihABV5eN9nxatWo_k: "<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>", letsnibbl.com (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://letsnibbl.com/.well-known/acme-challenge/jqxFZlkHsYBked-T61e9WcHBFZq6tbvacAVZk6uZAg8: "<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>". Skipping.
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/letsnibbl.com/fullchain.pem (failure)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
1 renew failure(s), 0 parse failure(s)

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: www.letsnibbl.com
   Type:   unauthorized
   Detail: Invalid response from
   http://www.letsnibbl.com/.well-known/acme-challenge/VZ0GyF0hgS_nykbkAR9-NzNgcNihABV5eN9nxatWo_k:
   "<html>
   <head><title>404 Not Found</title></head>
   <body bgcolor="white">
   <center><h1>404 Not Found</h1></center>
   <hr><center>"

   Domain: letsnibbl.com
   Type:   unauthorized
   Detail: Invalid response from
   http://letsnibbl.com/.well-known/acme-challenge/jqxFZlkHsYBked-T61e9WcHBFZq6tbvacAVZk6uZAg8:
   "<html>
   <head><title>404 Not Found</title></head>
   <body bgcolor="white">
   <center><h1>404 Not Found</h1></center>
   <hr><center>"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A record(s) for that domain
   contain(s) the right IP address.

Thanks

Try:
location /.well-known/acme-challenge/ {
alias /var/www/letsnibbl/.well-known/acme-challenge/;
}

I tried the changes, rg305. The error is the same.

I still find that using http:// … it shows the text file but

when it changes to https://… it shows the NodeJS wrong url response.

Do I need to put the location in the second server block of the nginx config?

no don’t put it in the second part.
you say http:// shows the file.
But from the Internet I still see this:
wget http://www.letsnibbl.com/.well-known/acme-challenge/test.txt
URL transformed to HTTPS due to an HSTS policy <<<<<<<NOT GOOD
–2017-06-06 01:18:30-- https://www.letsnibbl.com/.well-known/acme-challenge/test.txt
Resolving www.letsnibbl.com (www.letsnibbl.com)… 52.24.19.208
Connecting to www.letsnibbl.com (www.letsnibbl.com)|52.24.19.208|:443… connected.
HTTP request sent, awaiting response… 404 Not Found
2017-06-06 01:18:35 ERROR 404: Not Found.

Try disabling HSTS.

I find that in Chrome when I type http://… it auto changes to https://…

but in Firefox it remains and shows the text file.

I am a little challenged on “Try disabling HSTS”!!! How do I do it?

Thanks,

With NGINX there is not just one conf file, so dig through them all and look for something like:
“add_header Strict-Transport-Security”

I found the following in nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}


#mail {
#	# See sample authentication script at:
#	# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#	# auth_http localhost/auth.php;
#	# pop3_capabilities "TOP" "USER";
#	# imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#	server {
#		listen     localhost:110;
#		protocol   pop3;
#		proxy      on;
#	}
# 
#	server {
#		listen     localhost:143;
#		protocol   imap;
#		proxy      on;
#	}
#}

Will check others

check the files in those folders.

I found the following in a snippets directory

# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Should I # out the add_header Strict-Transport-Security settings and restart nginx?

yes # it and restart.
at least that should allow for you to renew.
Than we can figure out how to do both HSTS and renewals.

The above is the ssl-params.conf that is referred to in the sites-enabled settings of https server settings

yes it doesn’t yet make much sense why an HTTPS setting is affect the HTTP conf portion.
but lets take it one step at a time.