ERR_SSL_PROTOCOL_ERROR with nginx and certbot

Domain: cales.casa

OS: Alpine Linux v3.20.0

Certbot v2.10.0
I ran: certbot --nginx -d cales.casa -d www.cales.casa -d mail.cales.casa

/var/log/nginx/error.log shows 0 issues other than when I originally had syntax errors, but I resolved those quickly and reloaded the server.

nginx/1.26.1
Below is my global nginx.conf (default)

user nginx;

# Set number of worker processes automatically based on number of CPU cores.
worker_processes auto;

# Enables the use of JIT for regular expressions to speed-up their processing.
pcre_jit on;

# Configures default error logger.
error_log /var/log/nginx/error.log warn;

# Includes files with directives to load dynamic modules.
include /etc/nginx/modules/*.conf;

events {
	# The maximum number of simultaneous connections that can be opened by
	# a worker process.
	worker_connections 1024;
}

http {
	# Includes mapping of file name extensions to MIME types of responses
	# and defines the default type.
	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	# Name servers used to resolve names of upstream servers into addresses.
	# It's also needed when using tcpsocket and udpsocket in Lua modules.
	#resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001];

	# Don't tell nginx version to the clients. Default is 'on'.
	server_tokens off;

	# Specifies the maximum accepted body size of a client request, as
	# indicated by the request header Content-Length. If the stated content
	# length is greater than this size, then the client receives the HTTP
	# error code 413. Set to 0 to disable. Default is '1m'.
	client_max_body_size 1m;

	# Sendfile copies data between one FD and other from within the kernel,
	# which is more efficient than read() + write(). Default is off.
	sendfile on;

	# Causes nginx to attempt to send its HTTP response head in one packet,
	# instead of using partial frames. Default is 'off'.
	#tcp_nopush on;


	# Enables the specified protocols. Default is TLSv1 TLSv1.1 TLSv1.2.
	# TIP: If you're not obligated to support ancient clients, remove TLSv1.1.
	#ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

	# Path of the file with Diffie-Hellman parameters for EDH ciphers.
	# TIP: Generate with: openssl dhparam -out /etc/ssl/nginx/dh2048.pem 2048
	#ssl_dhparam /etc/ssl/nginx/dh2048.pem;

	# Specifies that our cipher suits should be preferred over client ciphers.
	# Default is 'off'.
	#ssl_prefer_server_ciphers on;

	# Enables a shared SSL cache with size that can hold around 8000 sessions.
	# Default is 'none'.
	#ssl_session_cache shared:SSL:2m;

	# Specifies a time during which a client may reuse the session parameters.
	# Default is '5m'.
	#ssl_session_timeout 1h;

	# Disable TLS session tickets (they are insecure). Default is 'on'.
	#ssl_session_tickets off;


	# Enable gzipping of responses.
	#gzip on;

	# Set the Vary HTTP header as defined in the RFC 2616. Default is 'off'.
	gzip_vary on;


	# Helper variable for proxying websockets.
	map $http_upgrade $connection_upgrade {
		default upgrade;
		'' close;
	}


	# Specifies the main log format.
	log_format main '$remote_addr - $remote_user [$time_local] "$request" '
			'$status $body_bytes_sent "$http_referer" '
			'"$http_user_agent" "$http_x_forwarded_for"';

	# Sets the path, format, and configuration for a buffered log write.
	access_log /var/log/nginx/access.log main;


	# Includes virtual hosts configs.
	include /etc/nginx/http.d/*.conf;

	# Include all configuration files from conf.d
	include /etc/nginx/conf.d/*.conf;
}

It hasn't been touched besides the last include.

Below is the options-ssl-nginx.conf file certbot generated (default)

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 "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";

Below is the nginx config file for my domain (cales.casa.conf)

# Redirect HTTP to HTTPS
server {
        listen 80;

        server_name cales.casa www.cales.casa mail.cales.casa;

        if ($host = www.cales.casa) {
                return 301 https://cales.casa$request_uri;
        }

        return 301 https://$host$request_uri;
}

server {
        listen 443 ssl;

        server_name cales.casa www.cales.casa;

        if ($host = www.cales.casa) {
                return 301 https://cales.casa$request_uri;
        }

        location / {
                root /var/www/cales.casa;
                index index.html;
        }

    ssl_certificate /etc/letsencrypt/live/cales.casa/fullchain.pem; # managed b>
    ssl_certificate_key /etc/letsencrypt/live/cales.casa/privkey.pem; # managed>

        # Additional SSL Settings
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
        listen 443 ssl;

        server_name mail.cales.casa;

        location / {
                root /var/www/cales.casa/mail;
                index index.html;
        }

    ssl_certificate /etc/letsencrypt/live/cales.casa/fullchain.pem; # managed b>
    ssl_certificate_key /etc/letsencrypt/live/cales.casa/privkey.pem; # managed>

        # Additional SSL Settings
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

I've checked the directories to see if my certificate and key actually exist, they do.

I have root access, or else I wouldn't be able to configure anything.

Below is the return of netstat -tuln

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      
tcp        0      0 :::25                   :::*                    LISTEN      
tcp        0      0 :::22                   :::*                    LISTEN      
tcp        0      0 :::80                   :::*                    LISTEN  

From what I can understand, the necessary ports are open and listening.

When I head over to SSL Labs to try their server test, this is the assessment it gives:
Assessment failed: No secure protocols supported

I've been trying many solutions regarding this SSL issue over the past 12 hours and I can't figure anything out. Any help would be very much appreciated. I'm new to hosting my own server, but I'd be happy to provide any other needed information.

Please show the output of:

nginx -T

2 Likes

Your IP looks like a residential system. You should check your router to ensure inbound requests on port 443 get sent to your nginx also on port 443. Your port 80 looks correct so make sure 443 is the same. You might have (probably do have) port 443 in your router sent to nginx on port 80 by mistake.

The nginx -T that rg305 suggested shows your active nginx config. Make sure it shows what you think it should.

2 Likes

Your router is forwarding both of the external ports [80 and 443] to your internal server IP on port 80:

curl -Ii http://cales.casa:80/
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 05 Aug 2024 12:59:22 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://cales.casa/

curl -Ii http://cales.casa:443/
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 05 Aug 2024 12:57:45 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://cales.casa/
1 Like

isn't that redirecting to itself? and port 443 answers http (think forwarded to wrong port)

2 Likes

Thank you!
In the router, there was an optional setting set to 80, which explicitly sent all incoming traffic to http, if I understand correctly.

3 Likes

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