Skip to content

Unclear HttpClient error with default NGINX SSL ciphers #116894

Open
@Michal78900

Description

@Michal78900

Description

When attempting to use HttpClient.GetAsync() I'm getting the following exception:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
 ---> System.Security.Authentication.AuthenticationException: Authentication failed because the remote party sent a TLS alert: 'HandshakeFailure'.
 ---> System.ComponentModel.Win32Exception (0x80090326): The message received was unexpected or badly formatted.

The HttpClient works correctly on HTTP traffic (localhost). It only fails when connecting to domain which uses HTTPS.

The domain uses Let's Encrypt certificate and isn't behind any proxy like Cloudflare.

The site can be accessed using a web browser (Firefox).

I use NGINX with the following configuration in sites-enabled:

server {
	listen 80;
	listen [::]:80;

	server_name [REDACTED];

	return 301 $server_name$request_uri;
}

server {
	listen 443 ssl http2;
        listen [::]:443 ssl http2;
	server_name [REDACTED];

	ssl_verify_client off;
	ssl_certificate /etc/letsencrypt/live/[REDACTED]/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/[REDACTED]/privkey.pem;

	add_header Strict-Transport-Security "max-age=126144000; includeSubDomains; preload" always;
	add_header X-XSS-Protection "1; mode=block" always;
	add_header X-Content-Type-Options "nosniff" always;
	add_header Referrer-Policy "no-referrer" always;
	add_header X-Frame-Options "deny" always;

	location / {
                proxy_pass http://127.0.0.1:[REDACTED];
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

Changing config to this fixes the issue:

server {
	listen 80;
	listen [::]:80;

	server_name [REDACTED];

	return 301 $server_name$request_uri;
}

server {
	listen 443 ssl http2;
        listen [::]:443 ssl http2;
	server_name [REDACTED];

	ssl_verify_client off;
	ssl_certificate /etc/letsencrypt/live/[REDACTED]/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/[REDACTED]/privkey.pem;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDSA+ECDHE+AES256+AESGCM:ECDSA+ECDHE+AES256+AESCCM:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES256+AESGCM;
        ssl_ecdh_curve secp521r1:secp384r1;
        ssl_prefer_server_ciphers on;

	add_header Strict-Transport-Security "max-age=126144000; includeSubDomains; preload" always;
	add_header X-XSS-Protection "1; mode=block" always;
	add_header X-Content-Type-Options "nosniff" always;
	add_header Referrer-Policy "no-referrer" always;
	add_header X-Frame-Options "deny" always;

	location / {
                proxy_pass http://127.0.0.1:[REDACTED];
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

Reproduction Steps

using HttpClient httpClient = new();
await httpClient.GetAsync("https://domain.com");

Expected behavior

The SSL connection is established and I can do requests.

Actual behavior

I'm getting System.Net.Http.HttpRequestException: The SSL connection could not be established and I can't make requests.

Regression?

No response

Known Workarounds

Adding these to the NGINX config file fixes the issue completly (the most important is ssl_ciphers, the rest can probably be skipped):

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDSA+ECDHE+AES256+AESGCM:ECDSA+ECDHE+AES256+AESCCM:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES256+AESGCM;
ssl_ecdh_curve secp521r1:secp384r1;
ssl_prefer_server_ciphers on;

Configuration

  • Client .NET version: 9.0.100
  • Client OS: Windows 10 22H2
  • Server OS: Ubuntu 22.04.5 LTS
  • Server Nginx Version: 1.18.0
  • Server OpenSSL Version: 3.0.2

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Net.Securityneeds-author-actionAn issue or pull request that requires more info or actions from the author.untriagedNew issue has not been triaged by the area owner

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions