Services see the site's certificate as self-signed (nginx/ubuntu)

I am using the latest nginx and certbot on a Ubuntu 20.04 machine via ssh connection.

I have executed the command sudo certbot --nginx and followed the instructions to successfully issue a certificate and a key for my domain -- sub.example.com

I then edited the /etc/nginx/sites-available/default file to have https:// instead of http://
I don't have a 'sub.example.com' file. I am only using the default one.

The site is running on https and I can see services recognize the third-party certificate by Let's Encrypt and R3.

The issue is, services such as google and postgres recognize the certificate as a self-signed certificate although it isn't.

Running a test on ssllabs.com, sub.example.com received an A score.
The only thing that seemed off with the certificate there was 'DNS CAA' which the site said doesn't exist.

I cannot provide further details for privacy reasons.

1 Like

Are you serving cert.pem instead of fullchain.pem? Sometimes certain software will not trust/recognize a certificate without the intermediate certificate (R3) being included. This is why fullchain.pem contains cert.pem and the R3 intermediate certificate.

You can use this tool to check:

1 Like

Issuing sudo certbot --nginx should have created a working HTTPS vhost config file.
So I'm not sure what happened during that command that prompted you to need to do this:

Also, neither HTTP:// nor HTTPS:// should be anywhere in such a file.
So, please explain in English or just show the file and thus the changes you made.
Or better yet, show the entire config with:
nginx -T

And if SSLLabs showed an A score, how is it possible that?:

Is this view regarding SMTP/EMAIL?

[ I don't even see how those two things are considered to be similar services otherwise* ]
[ * here google is being taken to refer to the Gmail service (one of the many services Google provides) ]

1 Like

I am serving fullchain.pem (along with linking my privkey.pem), the website you attached shows that my site has the correct chain.

This is the output for nginx -T (changed the original address to sub.example.com)

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

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 TLSv1.3; # 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_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;
#	}
#}

# configuration file /etc/nginx/modules-enabled/50-mod-http-image-filter.conf:
load_module modules/ngx_http_image_filter_module.so;

# configuration file /etc/nginx/modules-enabled/50-mod-http-xslt-filter.conf:
load_module modules/ngx_http_xslt_filter_module.so;

# configuration file /etc/nginx/modules-enabled/50-mod-mail.conf:
load_module modules/ngx_mail_module.so;

# configuration file /etc/nginx/modules-enabled/50-mod-stream.conf:
load_module modules/ngx_stream_module.so;

# configuration file /etc/nginx/mime.types:

types {
	...long list of mime types
}

# configuration file /etc/nginx/sites-enabled/default:
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
server {
	listen 80 default_server;
	listen [::]:80 default_server;

	# SSL configuration
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;

	server_name hellonode;

	location ^~ /assets/ {
		gzip_static on;
		expires 12h;
		add_header Cache-Control public;
  }

	location / {
		proxy_http_version 1.1;
		proxy_cache_bypass $http_upgrade;

		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection 'upgrade';
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;

		proxy_pass http://localhost:3000;
	}
}

server {

	# SSL configuration
	#
	# listen 443 ssl default_server;
	# listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;
    server_name sub.example.com; # managed by Certbot


	location ^~ /assets/ {
		gzip_static on;
		expires 12h;
		add_header Cache-Control public;
  }

	location / {
		proxy_http_version 1.1;
		proxy_cache_bypass $http_upgrade;

		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection 'upgrade';
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;

		proxy_pass https://localhost:3000;
	}


    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/sub.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/sub.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = sub.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


	listen 80 ;
	listen [::]:80 ;
    server_name sub.example.com;
    return 404; # managed by Certbot


}

# configuration file /etc/letsencrypt/options-ssl-nginx.conf:
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

ssl_ciphers "I DONT KNOW IF THIS IS CONFIDENTIAL";

no, authentication via google. they're not similar services, they are just 2 services that being used and they both prompt that the certificate is self-signed.

I can't find anything wrong with the nginx configuration.
Can you show the complaint message?

Yes, but it doesn't really give much,
Error: self signed certificate

Same for google authentication, they just give something like "self signed is not allowed".

Without knowing the domain, nor the exact detail in the error messages, there not much I can do for you :frowning:

The nginx config doesn't even include any other cert!
There must be something on some other port that is being checked (not port 443).
You are leaving something out of the equation - that might seem trivial to you... but holds the key
I can only conclude that this NOT an nginx problem, nor an LE cert problem.
Find where the other cert is being served and you have found the problem.

There isn't much to add, though there are a few things:

  • I am running node, on port :3000. The error code I'm getting on node's side is DEPTH_ZERO_SELF_SIGNED_CERT
  • I saw that it was suggested to add the setting rejectUnauthorized: false, which helps with the node problem but Google authentication still fails at self-signed error on Google's end.
    Also, I'm not sure if it's a good idea to add rejectUnauthorized: false to the code..

I can't provide you with the site domain, but if there's anything else I can add please tell me.

I am serving only the privkey.pem and fullchain.pem that were created via the certbot.
Are you sure it can't be an nginx problem? can it be the fact that the port mentioned in the config above is 80 and not 443? (though the site IS being served in https and working)

100%

I see 443:

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/sub.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/sub.example.com/privkey.pem; # managed by Certbot

I do see this (which I find strange):

server {
	listen 80 default_server;
	listen [::]:80 default_server;
		proxy_pass http://localhost:3000;

server {
		proxy_pass https://localhost:3000;
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot

When anyone connects to your site via port 80, you proxy them to http://localhost:3000
When anyone connects to your site via port 443, you proxy them to https://localhost:3000

localhost:3000 can't possibly be doing HTTP & HTTPS
One of those is right and the other is wrong!
[they need to both be set the same - on the proxied side, when using the same port]

Be sure to mention my name when you DONATE to LE.:wink:

I've tried and when I try to go to http://sub.example.com I just get transferred into https://sub.example.com automatically by the browser.
Also is it ok that I have 3 different server {} ?

Is there something that needs to be changed in that config file that might be causing all of this?
I only want to allow https usage on my site, and not http.

You really need to understand web server coding.
Yes there are three server blocks.

  1. Is for port 80 and name covers default_server which means whenever a name is unmatched that content will be served and also covers the name "hellonode".
    Which is being proxied to: HTTP://localhost:3000
  2. Is for port 443 and covers the name "sub.example.com"
    Which is being proxied to: HTTPS://localhost:3000
  3. Is for port 80 and covers the name "sub.example.com"
    Which redirects all such requests to HTTPS

YES!
You must verify which of these two works (one will surely fail):
HTTP://localhost:3000
HTTPS://localhost:3000 <<<< my money is on this one fails !!!
Reminder:

For the name "sub.example.com", that is already being handled.

What do you mean by that? How do I verify it?

whenever I serve my node app via 'run dev', https://sub.example.com serves my application normally with everything working, and whenever I go to http://sub.example.com I just get redirected to https:// with everything working.

Only when I'm running on production for some reason I get all these self-signed errors from places..

--
My issue has to do with CA I think, which I know nothing about. as I mentioned, the ssllabs test also mentioned I don't have/pass DNS CAA. Do you know if I can do something about it?

Does that mean there are two systems?
[production and development/testing]

If you don't know how to verify which one of those works, then you should hire a web admin.
Sorry about the rudeness now.
But this is a complete waste of my time.

Please see my last reply

Please stop thinking and just do what I've already told you to do three times.
If you don't know how to, then find someone who can.

Can you just explain what do you mean by verifying if it fails because as I already mentioned nothing fails

And I repeat myself (but you obviously don't understand HTTP/HTTPS):

First of all, this is a support forum, I just don't get why are you so toxic

Secondly, you can just explain youself instead of repeating youself. what other cert are you talking about? and why do you keep saying verify which of these work when I tell you I get redirected to a working https:// everytime I access either http:// or https://