SSL on a Web API w/Nginx

I’ve done this before. I have serveral sites set up with Let’s Encrypt and nginx. But for some reason Let’s Encrypt cannot get to my .well-known/acme-challenge. I think it’s because this time there is no front end, it’s a web api only (server side only).

I have the following in my nginx file (my server is running on port 8080):

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
 }

upstream app_admin {
  server 127.0.0.1:8080;
}
server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;
  server_name test.com;

  # for Let's Encrypt to work properly
  location ^~ /.well-knownn {
    allow all;
    root /var/www/;
    default_type "text/plain";
  }

My domain is: test.com

I set up I ran this command: ./letsencrypt-auto certonly -a webroot --webroot-path=/var/www -d test.com

It produced this output:

Domain: test.com
   Type:   connection
   Detail: Fetching
   http://test.com/.well-known/acme-challenge/TxLvt42345wrtgnWN3aIlh6oDng8NHCVm6h5Y70:
   Timeout

My web server is (include version): Lastest version of nginx

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

My hosting provider, if applicable, is: AWS

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 control panel, just command line tools.

I also can’t connect to port 80 on your server at all. Is there some kind of firewall or something that prevents inbound connections on port 80?

Thanks. The Web API is hosted on port 8080. There’s nothing on port 80.

The nginx config should route everything from 80 to 8080.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
 }

upstream app_admin {
  server 127.0.0.1:8080;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;
  server_name test.com;

  # for Let's Encrypt to work properly
  location ^~ /.well-knownn {
    allow all;
    root /var/www/;
    default_type "text/plain";
  }

  location / {
    rewrite     ^ https://$server_name$request_uri? permanent;
  }

}

Also, there’s no route on http://test.com/ there’s roots on other routes only.

Keep in mind that you have a typo in location directive, you wrote an extra n for .well-known

1 Like

Do you have an understanding of why your nginx configuration file doesn’t cause nginx to accept incoming connections on port 80? I’m not sure I know nginx well enough to understand this.

1 Like

Thank you @sahsanu, I acually just updated the config with that change and restarted nginx. Reran let’s encrypt:

/opt/letsencrypt# ./letsencrypt-auto certonly -a webroot --webroot-path=/var/www -d test.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for test.com
Using the webroot path /var/www for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. test.com (http-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Fetching http://test.com/.well-known/acme-challenge/qyIolngTdgUfHP5F7AcvMUbTTt4v345345tdSZdIlA: Timeout

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

   Domain: test.com
   Type:   connection
   Detail: Fetching
   http://test.com/.well-known/acme-challenge/qyIolngTdgUfHP5F7AcvMU5345341-IlWutdSZdIlA:
   Timeout

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address. Additionally, please check that
   your computer has a publicly routable IP address and that no
   firewalls are preventing the server from communicating with the
   client. If you're using the webroot plugin, you should also verify
   that you are serving files from the webroot path you provided.

Here’s the updated config file:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
 }

upstream app_admin {
  server 127.0.0.1:8080;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;
  server_name test.com;

  # for Let's Encrypt to work properly
  location ^~ /.well-known {
    allow all;
    root /var/www/;
    default_type "text/plain";
  }

  location / {
    rewrite     ^ https://$server_name$request_uri? permanent;
  }

}

I actually can’t get to anything on port 80, I can only get to it from 8080.

Yeah, the config looks really close to what I have running on other sites, so I'm not sure why it's not routing from 80 to 8080 yet.

Running this I can see nginx is on port 80:

netstat -nlp | grep :80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      19820/nginx
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      19265/node
tcp6       0      0 :::80                   :::*                    LISTEN      19820/nginx

You could try running

netstat -pant

1 Like

Heh, -l is a good idea, forming netstat -plant (although strictly speaking -l contradicts -a).

1 Like

So I think you must have a host or network firewall somewhere forbidding connections from the public on port 80.

1 Like

I'll check to see if I have a restriction on incoming.

That was it, I had 80 blocked for all incoming (but my own) on AWS! Sometimes we just need a little push in the right direction!

You're awesome, Thank you!

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